1
0
Fork 0
spectre/source/Platform/Unix/X11Display.cpp

143 lines
3 KiB
C++

#include <Spectre/Display/DisplayDescription.h> // Prevents conflict with X.h defining "None"
#include <Spectre/System/Log.h>
#include "X11WindowEventHandler.h"
#include "X11SharedDisplay.h"
#include "GLXContext.h"
#include "X11Display.h"
namespace sp {
X11Display::
X11Display() :
m_screen (0),
m_disp (NULL),
m_size (200,200)
{
}
bool X11Display::create(DisplayDescription description)
{
XSetWindowAttributes attr;
XVisualInfo* vi;
Atom protocols;
m_disp = XGetDisplay();
if (m_disp == NULL) {
Log::warn("X11: Could not open display");
return false;
}
m_screen = DefaultScreen(m_disp);
attr.border_pixel = BlackPixel(m_disp, m_screen);
attr.background_pixel = WhitePixel(m_disp, m_screen);
//attr.override_redirect = True;
attr.colormap = ::XCreateColormap(m_disp, RootWindow(m_disp, m_screen), DefaultVisual(m_disp, m_screen), AllocNone);
// We want Keyboard,Mouse,Resize,Exposure (repaint) events.
attr.event_mask = KeyPressMask | KeyReleaseMask
| ButtonPressMask | ButtonReleaseMask | PointerMotionMask
| StructureNotifyMask | ExposureMask;
m_win = XCreateWindow(m_disp,
RootWindow(m_disp, m_screen),
0, 0,
m_size.x, m_size.y, 0, DefaultDepth(m_disp, m_screen),
InputOutput, DefaultVisual(m_disp, m_screen),
CWBackPixel | CWColormap | CWBorderPixel | CWEventMask, &attr);
// Register event handler
X11WindowEventHandler::registerHandler(m_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);
XMapWindow(m_disp, m_win);
setSize(description.mode.width, description.mode.height);
// Clear and take focus
XClearWindow(m_disp, m_win);
XMapRaised(m_disp, m_win);
Log::info("X11: Created display");
return true;
}
void X11Display::destroy()
{
if (m_win) {
X11WindowEventHandler::unregisterHandler(m_disp, m_win);
}
if (m_disp) {
XReleaseDisplay();
m_disp = NULL;
}
}
bool X11Display::isValid()
{
return m_disp && m_win;
}
void* X11Display::getHandle() const
{
return (void*) m_win;
}
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);
}
Vector2u X11Display::getSize() const
{
return m_size;
}
void X11Display::setPosition(unsigned int x, unsigned int y)
{
::XMoveWindow(m_disp, m_win, x, y);
}
void X11Display::setCaption(const std::string& caption)
{
::XStoreName(m_disp, m_win, caption.c_str());
}
void X11Display::setIcon(const std::string& icon)
{
// TODO: Implement
}
void X11Display::showCursor(bool value)
{
// TODO: Implement
}
void X11Display::processEvent(const ::XEvent& event)
{
Vector2u size;
switch(event.xany.type) {
case ConfigureNotify:
size.x = event.xconfigure.width;
size.y = event.xconfigure.height;
if (m_size != size) {
m_size = size;
Log::info("X11: Resize event");
onReshape(size.x, size.y);
}
break;
}
}
} // namespace sp