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

@ -2,7 +2,7 @@
#include <Spectre/System/Log.h>
#include <Spectre/Graphics/Image.h>
#include "X11WindowEventHandler.h"
#include "X11SharedDisplay.h"
#include "Xlib.h"
#include "GLXContext.h"
#include "X11Display.h"
@ -27,7 +27,6 @@ X11Display* X11Display::getFocused()
X11Display::
X11Display() :
m_screen (0),
m_disp (NULL),
m_size (200,200),
m_cur_last (0),
m_cur_hidden (0)
@ -41,49 +40,44 @@ bool X11Display::create(DisplayDescription description)
Atom protocols;
Visual* visual;
Window root_win;
::Display* disp = Xlib::getDisplay();
m_disp = XGetDisplay();
if (m_disp == NULL) {
Log::warn("X11: Could not open display");
return false;
}
m_screen = DefaultScreen(disp);
root_win = XRootWindow(disp, m_screen);
visual = DefaultVisual(disp, m_screen);
m_screen = DefaultScreen(m_disp);
root_win = XRootWindow(m_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.border_pixel = BlackPixel(disp, m_screen);
attr.background_pixel = WhitePixel(disp, m_screen);
//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.
attr.event_mask = FocusChangeMask
| KeyPressMask | KeyReleaseMask
| ButtonPressMask | ButtonReleaseMask | PointerMotionMask
| StructureNotifyMask | ExposureMask;
m_win = ::XCreateWindow(m_disp, root_win,
m_win = ::XCreateWindow(disp, root_win,
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,
CWBackPixel | CWColormap | CWBorderPixel | CWEventMask, &attr);
// 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.
// 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.
protocols = getAtom("WM_DELETE_WINDOW");
XSetWMProtocols(m_disp, m_win, &protocols, 1);
protocols = Xlib::getAtom("WM_DELETE_WINDOW");
XSetWMProtocols(disp, m_win, &protocols, 1);
setVisible(true);
setSize(description.mode.width, description.mode.height);
// Clear and take focus
XClearWindow(m_disp, m_win);
XMapRaised(m_disp, m_win);
XClearWindow(disp, m_win);
XMapRaised(disp, m_win);
Log::info("X11: Created display");
@ -94,21 +88,16 @@ bool X11Display::create(DisplayDescription description)
void X11Display::destroy()
{
if (m_disp) {
if (m_win) {
X11WindowEventHandler::unregisterHandler(m_disp, m_win);
::XDestroyWindow(m_disp, m_win);
}
XReleaseDisplay(m_disp);
m_disp = NULL;
if (m_win) {
::Display* disp = Xlib::getDisplay();
X11WindowEventHandler::unregisterHandler(disp, m_win);
::XDestroyWindow(disp, m_win);
}
}
bool X11Display::isValid()
{
return m_disp && m_win;
return m_win;
}
void* X11Display::getHandle() const
@ -128,7 +117,7 @@ void X11Display::setSize(unsigned int width, unsigned int 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
@ -138,7 +127,7 @@ Vector2u X11Display::getSize() const
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
@ -146,7 +135,7 @@ Vector2u X11Display::getPosition() const
Vector2u pos(0, 0);
XWindowAttributes attr;
if (XGetWindowAttributes(m_disp, m_win, &attr)) {
if (XGetWindowAttributes(Xlib::getDisplay(), m_win, &attr)) {
pos.x = attr.x;
pos.y = attr.y;
}
@ -156,37 +145,38 @@ Vector2u X11Display::getPosition() const
void X11Display::setVisible(bool visible)
{
if (visible) {
::XMapWindow(m_disp, m_win);
::XMapWindow(Xlib::getDisplay(), m_win);
} else {
::XUnmapWindow(m_disp, m_win);
::XUnmapWindow(Xlib::getDisplay(), m_win);
}
}
void X11Display::minimize()
{
::XIconifyWindow(m_disp, m_win, m_screen);
::XIconifyWindow(Xlib::getDisplay(), m_win, m_screen);
}
void X11Display::maximize()
{
::XClientMessageEvent ev = {};
::Display* disp = Xlib::getDisplay();
ev.type = ClientMessage;
ev.window = m_win;
ev.message_type = getAtom("_NET_WM_STATE");
ev.message_type = Xlib::getAtom("_NET_WM_STATE");
ev.format = 32;
ev.data.l[0] = _NET_WM_STATE_TOGGLE;
ev.data.l[1] = getAtom("_NET_WM_STATE_MAXIMIZED_HORZ");
ev.data.l[2] = getAtom("_NET_WM_STATE_MAXIMIZED_VERT");
ev.data.l[1] = Xlib::getAtom("_NET_WM_STATE_MAXIMIZED_HORZ");
ev.data.l[2] = Xlib::getAtom("_NET_WM_STATE_MAXIMIZED_VERT");
ev.data.l[3] = 1;
::XSendEvent(m_disp, DefaultRootWindow(m_disp), False,
::XSendEvent(disp, DefaultRootWindow(disp), False,
SubstructureNotifyMask, (XEvent*) &ev);
}
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.
@ -201,8 +191,9 @@ void X11Display::setIcon(const std::string& icon)
void X11Display::setIcon(unsigned int width, unsigned int height, const uint8_t *pixels)
{
::Atom net_wm_icon = getAtom("_NET_WM_ICON", False);
::Atom cardinal = getAtom("CARDINAL", False);
::Display* disp = Xlib::getDisplay();
::Atom net_wm_icon = Xlib::getAtom("_NET_WM_ICON", False);
::Atom cardinal = Xlib::getAtom("CARDINAL", False);
std::vector<uint64_t> buffer(2 + width * height);
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);
}
::XChangeProperty(m_disp, m_win,
::XChangeProperty(disp, m_win,
net_wm_icon, cardinal, 32,
PropModeReplace,
reinterpret_cast<const unsigned char*>(&buffer[0]),
2 + width * height);
XFlush(m_disp);
XFlush(disp);
}
void X11Display::createHiddenCursor()
{
::Display* disp = Xlib::getDisplay();
XColor c;
Pixmap pix = ::XCreatePixmap(m_disp, m_win, 1, 1, 1);
GC gc = ::XCreateGC(m_disp, pix, 0, NULL);
Pixmap pix = ::XCreatePixmap(disp, m_win, 1, 1, 1);
GC gc = ::XCreateGC(disp, pix, 0, NULL);
// Draw transparent pixel.
::XDrawPoint(m_disp, pix, gc, 0, 0);
::XDrawPoint(disp, pix, gc, 0, 0);
c.red = c.green = c.blue = 0;
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.
::XFreePixmap(m_disp, pix);
::XFreeGC(m_disp, gc);
::XFreePixmap(disp, pix);
::XFreeGC(disp, gc);
}
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)