mirror of https://github.com/AxioDL/boo.git
much xcb-glx work
This commit is contained in:
parent
a70cc2c9d1
commit
a66469b991
|
@ -27,8 +27,8 @@ public:
|
||||||
virtual void deviceError(const char* error) {fprintf(stderr, "%s\n", error);}
|
virtual void deviceError(const char* error) {fprintf(stderr, "%s\n", error);}
|
||||||
|
|
||||||
/* Low-Level API */
|
/* Low-Level API */
|
||||||
bool sendUSBInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length);
|
bool sendUSBInterruptTransfer(const uint8_t* data, size_t length);
|
||||||
size_t receiveUSBInterruptTransfer(uint8_t pipe, uint8_t* data, size_t length);
|
size_t receiveUSBInterruptTransfer(uint8_t* data, size_t length);
|
||||||
virtual void initialCycle() {}
|
virtual void initialCycle() {}
|
||||||
virtual void transferCycle() {}
|
virtual void transferCycle() {}
|
||||||
virtual void finalCycle() {}
|
virtual void finalCycle() {}
|
||||||
|
|
|
@ -7,7 +7,6 @@ namespace boo
|
||||||
class IGraphicsContext
|
class IGraphicsContext
|
||||||
{
|
{
|
||||||
friend class CWindowCocoa;
|
friend class CWindowCocoa;
|
||||||
virtual void _setPlatformWindowHandle(void* handle) {(void)handle;};
|
|
||||||
virtual void _setCallback(class IWindowCallback* cb) {(void)cb;};
|
virtual void _setCallback(class IWindowCallback* cb) {(void)cb;};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -3,7 +3,7 @@ CONFIG += console
|
||||||
#QMAKE_CXXFLAGS -= -std=c++0x
|
#QMAKE_CXXFLAGS -= -std=c++0x
|
||||||
#CONFIG += c++11
|
#CONFIG += c++11
|
||||||
unix:QMAKE_CXXFLAGS += -std=c++11 -stdlib=libc++
|
unix:QMAKE_CXXFLAGS += -std=c++11 -stdlib=libc++
|
||||||
unix:LIBS += -std=c++11 -stdlib=libc++ -lc++abi -lxcb -lxcb-xkb -lxcb-keysyms -lxkbcommon -lxkbcommon-x11
|
unix:LIBS += -std=c++11 -stdlib=libc++ -lc++abi -lxcb -lxcb-glx -lxcb-xkb -lxcb-keysyms -lxkbcommon -lxkbcommon-x11
|
||||||
|
|
||||||
win32:LIBS += Setupapi.lib winusb.lib User32.lib /SUBSYSTEM:Windows
|
win32:LIBS += Setupapi.lib winusb.lib User32.lib /SUBSYSTEM:Windows
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ IWindow* _CWindowWaylandNew(const std::string& title);
|
||||||
|
|
||||||
class CApplicationWayland final : public IApplication
|
class CApplicationWayland final : public IApplication
|
||||||
{
|
{
|
||||||
const IApplicationCallback& m_callback;
|
IApplicationCallback& m_callback;
|
||||||
const std::string m_friendlyName;
|
const std::string m_friendlyName;
|
||||||
const std::string m_pname;
|
const std::string m_pname;
|
||||||
const std::vector<std::string> m_args;
|
const std::vector<std::string> m_args;
|
||||||
|
@ -22,7 +22,7 @@ class CApplicationWayland final : public IApplication
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CApplicationWayland(const IApplicationCallback& callback,
|
CApplicationWayland(IApplicationCallback& callback,
|
||||||
const std::string& friendlyName,
|
const std::string& friendlyName,
|
||||||
const std::string& pname,
|
const std::string& pname,
|
||||||
const std::vector<std::string>& args)
|
const std::vector<std::string>& args)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#define explicit explicit_c
|
#define explicit explicit_c
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xcb_event.h>
|
||||||
#include <xkbcommon/xkbcommon-x11.h>
|
#include <xkbcommon/xkbcommon-x11.h>
|
||||||
#include <xcb/xkb.h>
|
#include <xcb/xkb.h>
|
||||||
#undef explicit
|
#undef explicit
|
||||||
|
@ -15,7 +16,7 @@ namespace boo
|
||||||
|
|
||||||
static xcb_window_t getWindowOfEvent(xcb_generic_event_t* event, bool& windowEvent)
|
static xcb_window_t getWindowOfEvent(xcb_generic_event_t* event, bool& windowEvent)
|
||||||
{
|
{
|
||||||
switch (event->response_type & ~0x80)
|
switch (XCB_EVENT_RESPONSE_TYPE(event))
|
||||||
{
|
{
|
||||||
case XCB_EXPOSE:
|
case XCB_EXPOSE:
|
||||||
{
|
{
|
||||||
|
@ -69,7 +70,7 @@ IWindow* _CWindowXCBNew(const std::string& title, xcb_connection_t* conn);
|
||||||
|
|
||||||
class CApplicationXCB final : public IApplication
|
class CApplicationXCB final : public IApplication
|
||||||
{
|
{
|
||||||
const IApplicationCallback& m_callback;
|
IApplicationCallback& m_callback;
|
||||||
const std::string m_friendlyName;
|
const std::string m_friendlyName;
|
||||||
const std::string m_pname;
|
const std::string m_pname;
|
||||||
const std::vector<std::string> m_args;
|
const std::vector<std::string> m_args;
|
||||||
|
@ -86,7 +87,7 @@ class CApplicationXCB final : public IApplication
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CApplicationXCB(const IApplicationCallback& callback,
|
CApplicationXCB(IApplicationCallback& callback,
|
||||||
const std::string& friendlyName,
|
const std::string& friendlyName,
|
||||||
const std::string& pname,
|
const std::string& pname,
|
||||||
const std::vector<std::string>& args)
|
const std::vector<std::string>& args)
|
||||||
|
@ -97,7 +98,7 @@ public:
|
||||||
{
|
{
|
||||||
m_xcbConn = xcb_connect(NULL, NULL);
|
m_xcbConn = xcb_connect(NULL, NULL);
|
||||||
|
|
||||||
/* The convoluted xkb extension requests that the X server does not
|
/* This convoluted xkb extension requests that the X server does not
|
||||||
* send repeated keydown events when a key is held */
|
* send repeated keydown events when a key is held */
|
||||||
xkb_x11_setup_xkb_extension(m_xcbConn,
|
xkb_x11_setup_xkb_extension(m_xcbConn,
|
||||||
XKB_X11_MIN_MAJOR_XKB_VERSION,
|
XKB_X11_MIN_MAJOR_XKB_VERSION,
|
||||||
|
@ -122,17 +123,22 @@ public:
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
xcb_generic_event_t* event;
|
xcb_generic_event_t* event;
|
||||||
|
m_running = true;
|
||||||
|
m_callback.appLaunched(this);
|
||||||
while (m_running && (event = xcb_wait_for_event(m_xcbConn)))
|
while (m_running && (event = xcb_wait_for_event(m_xcbConn)))
|
||||||
{
|
{
|
||||||
bool windowEvent;
|
bool windowEvent;
|
||||||
xcb_window_t evWindow = getWindowOfEvent(event, windowEvent);
|
xcb_window_t evWindow = getWindowOfEvent(event, windowEvent);
|
||||||
|
fprintf(stderr, "EVENT %d\n", XCB_EVENT_RESPONSE_TYPE(event));
|
||||||
if (windowEvent)
|
if (windowEvent)
|
||||||
{
|
{
|
||||||
IWindow* window = m_windows[evWindow];
|
IWindow* window = m_windows[evWindow];
|
||||||
|
if (window)
|
||||||
|
window->_incomingEvent(event);
|
||||||
}
|
}
|
||||||
free(event);
|
free(event);
|
||||||
}
|
}
|
||||||
|
m_callback.appQuitting(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void quit()
|
void quit()
|
||||||
|
|
|
@ -33,17 +33,17 @@ void CDeviceBase::closeDevice()
|
||||||
m_token->_deviceClose();
|
m_token->_deviceClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDeviceBase::sendUSBInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length)
|
bool CDeviceBase::sendUSBInterruptTransfer(const uint8_t* data, size_t length)
|
||||||
{
|
{
|
||||||
if (m_hidDev)
|
if (m_hidDev)
|
||||||
return m_hidDev->_sendUSBInterruptTransfer(pipe, data, length);
|
return m_hidDev->_sendUSBInterruptTransfer(data, length);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CDeviceBase::receiveUSBInterruptTransfer(uint8_t pipe, uint8_t* data, size_t length)
|
size_t CDeviceBase::receiveUSBInterruptTransfer(uint8_t* data, size_t length)
|
||||||
{
|
{
|
||||||
if (m_hidDev)
|
if (m_hidDev)
|
||||||
return m_hidDev->_receiveUSBInterruptTransfer(pipe, data, length);
|
return m_hidDev->_receiveUSBInterruptTransfer(data, length);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,13 +59,13 @@ parseState(SDolphinControllerState* stateOut, uint8_t* payload, bool& rumble)
|
||||||
void CDolphinSmashAdapter::initialCycle()
|
void CDolphinSmashAdapter::initialCycle()
|
||||||
{
|
{
|
||||||
uint8_t handshakePayload[] = {0x13};
|
uint8_t handshakePayload[] = {0x13};
|
||||||
sendUSBInterruptTransfer(0, handshakePayload, sizeof(handshakePayload));
|
sendUSBInterruptTransfer(handshakePayload, sizeof(handshakePayload));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDolphinSmashAdapter::transferCycle()
|
void CDolphinSmashAdapter::transferCycle()
|
||||||
{
|
{
|
||||||
uint8_t payload[37];
|
uint8_t payload[37];
|
||||||
size_t recvSz = receiveUSBInterruptTransfer(0, payload, sizeof(payload));
|
size_t recvSz = receiveUSBInterruptTransfer(payload, sizeof(payload));
|
||||||
if (recvSz != 37 || payload[0] != 0x21)
|
if (recvSz != 37 || payload[0] != 0x21)
|
||||||
return;
|
return;
|
||||||
//printf("RECEIVED DATA %zu %02X\n", recvSz, payload[0]);
|
//printf("RECEIVED DATA %zu %02X\n", recvSz, payload[0]);
|
||||||
|
@ -108,7 +108,7 @@ void CDolphinSmashAdapter::transferCycle()
|
||||||
else
|
else
|
||||||
rumbleMessage[i+1] = 0;
|
rumbleMessage[i+1] = 0;
|
||||||
}
|
}
|
||||||
sendUSBInterruptTransfer(0, rumbleMessage, sizeof(rumbleMessage));
|
sendUSBInterruptTransfer(rumbleMessage, sizeof(rumbleMessage));
|
||||||
m_rumbleState = rumbleReq;
|
m_rumbleState = rumbleReq;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ void CDolphinSmashAdapter::transferCycle()
|
||||||
void CDolphinSmashAdapter::finalCycle()
|
void CDolphinSmashAdapter::finalCycle()
|
||||||
{
|
{
|
||||||
uint8_t rumbleMessage[5] = {0x11, 0, 0, 0, 0};
|
uint8_t rumbleMessage[5] = {0x11, 0, 0, 0, 0};
|
||||||
sendUSBInterruptTransfer(0, rumbleMessage, sizeof(rumbleMessage));
|
sendUSBInterruptTransfer(rumbleMessage, sizeof(rumbleMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDolphinSmashAdapter::deviceDisconnected()
|
void CDolphinSmashAdapter::deviceDisconnected()
|
||||||
|
|
|
@ -24,7 +24,7 @@ class CHIDDeviceIOKit final : public IHIDDevice
|
||||||
std::condition_variable m_initCond;
|
std::condition_variable m_initCond;
|
||||||
std::thread* m_thread;
|
std::thread* m_thread;
|
||||||
|
|
||||||
bool _sendUSBInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length)
|
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length)
|
||||||
{
|
{
|
||||||
if (m_usbIntf)
|
if (m_usbIntf)
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ class CHIDDeviceIOKit final : public IHIDDevice
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _receiveUSBInterruptTransfer(uint8_t pipe, uint8_t* data, size_t length)
|
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length)
|
||||||
{
|
{
|
||||||
if (m_usbIntf)
|
if (m_usbIntf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,7 +38,7 @@ class CHIDDeviceUdev final : public IHIDDevice
|
||||||
std::condition_variable m_initCond;
|
std::condition_variable m_initCond;
|
||||||
std::thread* m_thread;
|
std::thread* m_thread;
|
||||||
|
|
||||||
bool _sendUSBInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length)
|
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length)
|
||||||
{
|
{
|
||||||
if (m_devFd)
|
if (m_devFd)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +57,7 @@ class CHIDDeviceUdev final : public IHIDDevice
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _receiveUSBInterruptTransfer(uint8_t pipe, uint8_t* data, size_t length)
|
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length)
|
||||||
{
|
{
|
||||||
if (m_devFd)
|
if (m_devFd)
|
||||||
{
|
{
|
||||||
|
@ -93,22 +93,22 @@ class CHIDDeviceUdev final : public IHIDDevice
|
||||||
udev_device_unref(udevDev);
|
udev_device_unref(udevDev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
usb_device_descriptor devDesc = {0};
|
usb_device_descriptor devDesc = {};
|
||||||
read(device->m_devFd, &devDesc, 1);
|
read(device->m_devFd, &devDesc, 1);
|
||||||
read(device->m_devFd, &devDesc.bDescriptorType, devDesc.bLength-1);
|
read(device->m_devFd, &devDesc.bDescriptorType, devDesc.bLength-1);
|
||||||
if (devDesc.bNumConfigurations)
|
if (devDesc.bNumConfigurations)
|
||||||
{
|
{
|
||||||
usb_config_descriptor confDesc = {0};
|
usb_config_descriptor confDesc = {};
|
||||||
read(device->m_devFd, &confDesc, 1);
|
read(device->m_devFd, &confDesc, 1);
|
||||||
read(device->m_devFd, &confDesc.bDescriptorType, confDesc.bLength-1);
|
read(device->m_devFd, &confDesc.bDescriptorType, confDesc.bLength-1);
|
||||||
if (confDesc.bNumInterfaces)
|
if (confDesc.bNumInterfaces)
|
||||||
{
|
{
|
||||||
usb_interface_descriptor intfDesc = {0};
|
usb_interface_descriptor intfDesc = {};
|
||||||
read(device->m_devFd, &intfDesc, 1);
|
read(device->m_devFd, &intfDesc, 1);
|
||||||
read(device->m_devFd, &intfDesc.bDescriptorType, intfDesc.bLength-1);
|
read(device->m_devFd, &intfDesc.bDescriptorType, intfDesc.bLength-1);
|
||||||
for (i=0 ; i<intfDesc.bNumEndpoints+1 ; ++i)
|
for (i=0 ; i<intfDesc.bNumEndpoints+1 ; ++i)
|
||||||
{
|
{
|
||||||
usb_endpoint_descriptor endpDesc = {0};
|
usb_endpoint_descriptor endpDesc = {};
|
||||||
read(device->m_devFd, &endpDesc, 1);
|
read(device->m_devFd, &endpDesc, 1);
|
||||||
read(device->m_devFd, &endpDesc.bDescriptorType, endpDesc.bLength-1);
|
read(device->m_devFd, &endpDesc.bDescriptorType, endpDesc.bLength-1);
|
||||||
if ((endpDesc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
|
if ((endpDesc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
|
||||||
|
@ -193,6 +193,8 @@ class CHIDDeviceUdev final : public IHIDDevice
|
||||||
|
|
||||||
bool _sendHIDReport(const uint8_t* data, size_t length)
|
bool _sendHIDReport(const uint8_t* data, size_t length)
|
||||||
{
|
{
|
||||||
|
(void)data;
|
||||||
|
(void)length;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ class CHIDDeviceWinUSB final : public IHIDDevice
|
||||||
std::condition_variable m_initCond;
|
std::condition_variable m_initCond;
|
||||||
std::thread* m_thread;
|
std::thread* m_thread;
|
||||||
|
|
||||||
bool _sendUSBInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length)
|
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length)
|
||||||
{
|
{
|
||||||
if (m_usbHandle)
|
if (m_usbHandle)
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,7 @@ class CHIDDeviceWinUSB final : public IHIDDevice
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _receiveUSBInterruptTransfer(uint8_t pipe, uint8_t* data, size_t length)
|
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length)
|
||||||
{
|
{
|
||||||
if (m_usbHandle)
|
if (m_usbHandle)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,8 +10,8 @@ class IHIDDevice
|
||||||
{
|
{
|
||||||
friend class CDeviceBase;
|
friend class CDeviceBase;
|
||||||
virtual void _deviceDisconnected()=0;
|
virtual void _deviceDisconnected()=0;
|
||||||
virtual bool _sendUSBInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length)=0;
|
virtual bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length)=0;
|
||||||
virtual size_t _receiveUSBInterruptTransfer(uint8_t pipe, uint8_t* data, size_t length)=0;
|
virtual size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length)=0;
|
||||||
virtual bool _sendHIDReport(const uint8_t* data, size_t length)=0;
|
virtual bool _sendHIDReport(const uint8_t* data, size_t length)=0;
|
||||||
public:
|
public:
|
||||||
inline virtual ~IHIDDevice() {}
|
inline virtual ~IHIDDevice() {}
|
||||||
|
|
|
@ -47,10 +47,6 @@ public:
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPlatformWindowHandle(void* handle)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void initializeContext()
|
void initializeContext()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -58,7 +54,7 @@ public:
|
||||||
|
|
||||||
IGraphicsContext* makeShareContext() const
|
IGraphicsContext* makeShareContext() const
|
||||||
{
|
{
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent()
|
void makeCurrent()
|
||||||
|
@ -81,7 +77,7 @@ public:
|
||||||
IGraphicsContext* _CGraphicsContextWaylandNew(IGraphicsContext::EGraphicsAPI api,
|
IGraphicsContext* _CGraphicsContextWaylandNew(IGraphicsContext::EGraphicsAPI api,
|
||||||
IWindow* parentWindow)
|
IWindow* parentWindow)
|
||||||
{
|
{
|
||||||
|
return new CGraphicsContextWayland(api, parentWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,10 +47,6 @@ public:
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPlatformWindowHandle(void* handle)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void initializeContext()
|
void initializeContext()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
#include "windowsys/IGraphicsContext.hpp"
|
#include "windowsys/IGraphicsContext.hpp"
|
||||||
#include "windowsys/IWindow.hpp"
|
#include "windowsys/IWindow.hpp"
|
||||||
|
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/glx.h>
|
||||||
|
#include <GL/glx.h>
|
||||||
|
#include <GL/glcorearb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -10,15 +17,90 @@ class CGraphicsContextXCB final : public IGraphicsContext
|
||||||
EGraphicsAPI m_api;
|
EGraphicsAPI m_api;
|
||||||
EPixelFormat m_pf;
|
EPixelFormat m_pf;
|
||||||
IWindow* m_parentWindow;
|
IWindow* m_parentWindow;
|
||||||
|
xcb_connection_t* m_xcbConn;
|
||||||
|
|
||||||
|
xcb_glx_fbconfig_t m_fbconfig = 0;
|
||||||
|
xcb_visualid_t m_visualid = 0;
|
||||||
|
xcb_glx_window_t m_glxWindow = 0;
|
||||||
|
xcb_glx_context_t m_glxCtx = 0;
|
||||||
|
xcb_glx_context_tag_t m_glxCtxTag = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IWindowCallback* m_callback;
|
IWindowCallback* m_callback;
|
||||||
|
|
||||||
CGraphicsContextXCB(EGraphicsAPI api, IWindow* parentWindow)
|
CGraphicsContextXCB(EGraphicsAPI api, IWindow* parentWindow, xcb_connection_t* conn, uint32_t& visualIdOut)
|
||||||
: m_api(api),
|
: m_api(api),
|
||||||
m_pf(PF_RGBA8),
|
m_pf(PF_RGBA8),
|
||||||
m_parentWindow(parentWindow)
|
m_parentWindow(parentWindow),
|
||||||
{}
|
m_xcbConn(conn)
|
||||||
|
{
|
||||||
|
/* WTF freedesktop?? Fix this awful API and your nonexistant docs */
|
||||||
|
xcb_glx_get_fb_configs_reply_t* fbconfigs =
|
||||||
|
xcb_glx_get_fb_configs_reply(m_xcbConn, xcb_glx_get_fb_configs(m_xcbConn, 0), NULL);
|
||||||
|
struct conf_prop
|
||||||
|
{
|
||||||
|
uint32_t key;
|
||||||
|
uint32_t val;
|
||||||
|
}* props = (struct conf_prop*)xcb_glx_get_fb_configs_property_list(fbconfigs);
|
||||||
|
|
||||||
|
for (uint32_t i=0 ; i<fbconfigs->num_FB_configs ; ++i)
|
||||||
|
{
|
||||||
|
struct conf_prop* configProps = &props[fbconfigs->num_properties * i];
|
||||||
|
uint32_t fbconfId, visualId, depthSize, colorSize, doubleBuffer;
|
||||||
|
for (uint32_t j=0 ; j<fbconfigs->num_properties ; ++j)
|
||||||
|
{
|
||||||
|
struct conf_prop* prop = &configProps[j];
|
||||||
|
if (prop->key == GLX_FBCONFIG_ID)
|
||||||
|
fbconfId = prop->val;
|
||||||
|
if (prop->key == GLX_VISUAL_ID)
|
||||||
|
visualId = prop->val;
|
||||||
|
else if (prop->key == GLX_DEPTH_SIZE)
|
||||||
|
depthSize = prop->val;
|
||||||
|
else if (prop->key == GLX_BUFFER_SIZE)
|
||||||
|
colorSize = prop->val;
|
||||||
|
else if (prop->key == GLX_DOUBLEBUFFER)
|
||||||
|
doubleBuffer = prop->val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Double-buffer only */
|
||||||
|
if (!doubleBuffer)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (m_pf == PF_RGBA8 && colorSize >= 32)
|
||||||
|
{
|
||||||
|
m_fbconfig = fbconfId;
|
||||||
|
m_visualid = visualId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (m_pf == PF_RGBA8_Z24 && colorSize >= 32 && depthSize >= 24)
|
||||||
|
{
|
||||||
|
m_fbconfig = fbconfId;
|
||||||
|
m_visualid = visualId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (m_pf == PF_RGBAF32 && colorSize >= 128)
|
||||||
|
{
|
||||||
|
m_fbconfig = fbconfId;
|
||||||
|
m_visualid = visualId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (m_pf == PF_RGBAF32_Z24 && colorSize >= 128 && depthSize >= 24)
|
||||||
|
{
|
||||||
|
m_fbconfig = fbconfId;
|
||||||
|
m_visualid = visualId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(fbconfigs);
|
||||||
|
|
||||||
|
if (!m_fbconfig)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("unable to find suitable pixel format");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
visualIdOut = m_visualid;
|
||||||
|
}
|
||||||
|
|
||||||
~CGraphicsContextXCB()
|
~CGraphicsContextXCB()
|
||||||
{
|
{
|
||||||
|
@ -47,41 +129,46 @@ public:
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPlatformWindowHandle(void* handle)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void initializeContext()
|
void initializeContext()
|
||||||
{
|
{
|
||||||
|
m_glxWindow = xcb_generate_id(m_xcbConn);
|
||||||
|
xcb_glx_create_window(m_xcbConn, 0, m_fbconfig,
|
||||||
|
m_parentWindow->getPlatformHandle(),
|
||||||
|
m_glxWindow, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsContext* makeShareContext() const
|
IGraphicsContext* makeShareContext() const
|
||||||
{
|
{
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent()
|
void makeCurrent()
|
||||||
{
|
{
|
||||||
|
xcb_glx_make_context_current_reply_t* reply =
|
||||||
|
xcb_glx_make_context_current_reply(m_xcbConn,
|
||||||
|
xcb_glx_make_context_current(m_xcbConn, 0, m_glxWindow, m_glxWindow, m_glxCtx), NULL);
|
||||||
|
m_glxCtxTag = reply->context_tag;
|
||||||
|
free(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearCurrent()
|
void clearCurrent()
|
||||||
{
|
{
|
||||||
|
xcb_glx_make_context_current(m_xcbConn, m_glxCtxTag, m_glxWindow, m_glxWindow, 0);
|
||||||
|
m_glxCtxTag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swapBuffer()
|
void swapBuffer()
|
||||||
{
|
{
|
||||||
|
xcb_glx_swap_buffers(m_xcbConn, m_glxCtxTag, m_glxWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IGraphicsContext* _CGraphicsContextXCBNew(IGraphicsContext::EGraphicsAPI api,
|
IGraphicsContext* _CGraphicsContextXCBNew(IGraphicsContext::EGraphicsAPI api,
|
||||||
IWindow* parentWindow)
|
IWindow* parentWindow, xcb_connection_t* conn,
|
||||||
|
uint32_t& visualIdOut)
|
||||||
{
|
{
|
||||||
|
return new CGraphicsContextXCB(api, parentWindow, conn, visualIdOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ public:
|
||||||
{
|
{
|
||||||
m_nsWindow = [[CWindowCocoaInternal alloc] initWithBooWindow:this title:title];
|
m_nsWindow = [[CWindowCocoaInternal alloc] initWithBooWindow:this title:title];
|
||||||
m_gfxCtx = _CGraphicsContextCocoaNew(IGraphicsContext::API_OPENGL_3_3, this);
|
m_gfxCtx = _CGraphicsContextCocoaNew(IGraphicsContext::API_OPENGL_3_3, this);
|
||||||
m_gfxCtx->_setPlatformWindowHandle(m_nsWindow);
|
|
||||||
m_gfxCtx->initializeContext();
|
m_gfxCtx->initializeContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "IApplication.hpp"
|
#include "IApplication.hpp"
|
||||||
|
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xcb_event.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
#include <xcb/xcb_keysyms.h>
|
#include <xcb/xcb_keysyms.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
@ -99,6 +100,7 @@ do {\
|
||||||
xcb_intern_atom_reply_t* reply = \
|
xcb_intern_atom_reply_t* reply = \
|
||||||
xcb_intern_atom_reply(conn, cookie, NULL); \
|
xcb_intern_atom_reply(conn, cookie, NULL); \
|
||||||
var = reply->atom; \
|
var = reply->atom; \
|
||||||
|
free(reply); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
struct SXCBAtoms
|
struct SXCBAtoms
|
||||||
|
@ -107,6 +109,7 @@ struct SXCBAtoms
|
||||||
xcb_atom_t m_netwmStateFullscreen = 0;
|
xcb_atom_t m_netwmStateFullscreen = 0;
|
||||||
xcb_atom_t m_netwmStateAdd = 0;
|
xcb_atom_t m_netwmStateAdd = 0;
|
||||||
xcb_atom_t m_netwmStateRemove = 0;
|
xcb_atom_t m_netwmStateRemove = 0;
|
||||||
|
xcb_atom_t m_
|
||||||
xcb_key_symbols_t* m_keySyms = NULL;
|
xcb_key_symbols_t* m_keySyms = NULL;
|
||||||
SXCBAtoms(xcb_connection_t* conn)
|
SXCBAtoms(xcb_connection_t* conn)
|
||||||
{
|
{
|
||||||
|
@ -130,7 +133,8 @@ static void genFrameDefault(xcb_screen_t* screen, int* xOut, int* yOut, int* wOu
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsContext* _CGraphicsContextXCBNew(IGraphicsContext::EGraphicsAPI api,
|
IGraphicsContext* _CGraphicsContextXCBNew(IGraphicsContext::EGraphicsAPI api,
|
||||||
IWindow* parentWindow);
|
IWindow* parentWindow, xcb_connection_t* conn,
|
||||||
|
uint32_t& visualIdOut);
|
||||||
|
|
||||||
class CWindowXCB final : public IWindow
|
class CWindowXCB final : public IWindow
|
||||||
{
|
{
|
||||||
|
@ -151,12 +155,21 @@ public:
|
||||||
{
|
{
|
||||||
if (!S_ATOMS)
|
if (!S_ATOMS)
|
||||||
S_ATOMS = new SXCBAtoms(conn);
|
S_ATOMS = new SXCBAtoms(conn);
|
||||||
m_windowId = xcb_generate_id(conn);
|
|
||||||
|
|
||||||
/* Default screen */
|
/* Default screen */
|
||||||
xcb_screen_t* screen = xcb_setup_roots_iterator(xcb_get_setup(m_xcbConn)).data;
|
xcb_screen_t* screen = xcb_setup_roots_iterator(xcb_get_setup(m_xcbConn)).data;
|
||||||
m_pixelFactor = screen->width_in_pixels / (float)screen->width_in_millimeters / REF_DPMM;
|
m_pixelFactor = screen->width_in_pixels / (float)screen->width_in_millimeters / REF_DPMM;
|
||||||
|
|
||||||
|
/* Construct graphics context */
|
||||||
|
uint32_t visualId;
|
||||||
|
m_gfxCtx = _CGraphicsContextXCBNew(IGraphicsContext::API_OPENGL_3_3, this, m_xcbConn, visualId);
|
||||||
|
|
||||||
|
|
||||||
|
/* Create colormap */
|
||||||
|
xcb_colormap_t colormap = xcb_generate_id(m_xcbConn);
|
||||||
|
xcb_create_colormap(m_xcbConn, XCB_COLORMAP_ALLOC_NONE,
|
||||||
|
colormap, screen->root, visualId);
|
||||||
|
|
||||||
/* Create window */
|
/* Create window */
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
genFrameDefault(screen, &x, &y, &w, &h);
|
genFrameDefault(screen, &x, &y, &w, &h);
|
||||||
|
@ -166,10 +179,16 @@ public:
|
||||||
XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
|
XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
|
||||||
XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
|
XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
|
||||||
XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
|
XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
|
||||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY | 0xFFFFFF,
|
||||||
|
colormap,
|
||||||
|
XCB_NONE
|
||||||
};
|
};
|
||||||
xcb_create_window(m_xcbConn, 0, m_windowId, 0, x, y, w, h, 10, 0, screen->root_visual,
|
m_windowId = xcb_generate_id(conn);
|
||||||
XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK, valueMasks);
|
xcb_create_window(m_xcbConn, XCB_COPY_FROM_PARENT, m_windowId, screen->root,
|
||||||
|
x, y, w, h, 10,
|
||||||
|
XCB_WINDOW_CLASS_INPUT_OUTPUT, visualId,
|
||||||
|
XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
|
||||||
|
valueMasks);
|
||||||
|
|
||||||
/* Set the title of the window */
|
/* Set the title of the window */
|
||||||
const char* c_title = title.c_str();
|
const char* c_title = title.c_str();
|
||||||
|
@ -182,8 +201,9 @@ public:
|
||||||
XCB_ATOM_WM_ICON_NAME, XCB_ATOM_STRING, 8,
|
XCB_ATOM_WM_ICON_NAME, XCB_ATOM_STRING, 8,
|
||||||
strlen(c_title), c_title);
|
strlen(c_title), c_title);
|
||||||
|
|
||||||
/* Construct graphics context */
|
/* Initialize context */
|
||||||
m_gfxCtx = _CGraphicsContextXCBNew(IGraphicsContext::API_OPENGL_3_3, this);
|
xcb_map_window(m_xcbConn, m_windowId);
|
||||||
|
m_gfxCtx->initializeContext();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,9 +294,9 @@ public:
|
||||||
xcb_get_property_reply(m_xcbConn, cookie, NULL);
|
xcb_get_property_reply(m_xcbConn, cookie, NULL);
|
||||||
char* props = (char*)xcb_get_property_value(reply);
|
char* props = (char*)xcb_get_property_value(reply);
|
||||||
char fullscreen = false;
|
char fullscreen = false;
|
||||||
for (int i ; i<reply->length/4 ; ++i)
|
for (unsigned i=0 ; i<reply->length/4 ; ++i)
|
||||||
{
|
{
|
||||||
if (props[i] == S_ATOMS->m_netwmStateFullscreen)
|
if ((xcb_atom_t)props[i] == S_ATOMS->m_netwmStateFullscreen)
|
||||||
{
|
{
|
||||||
fullscreen = true;
|
fullscreen = true;
|
||||||
break;
|
break;
|
||||||
|
@ -294,7 +314,8 @@ public:
|
||||||
32,
|
32,
|
||||||
0,
|
0,
|
||||||
m_windowId,
|
m_windowId,
|
||||||
S_ATOMS->m_netwmState
|
S_ATOMS->m_netwmState,
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
fsEvent.data.data32[0] = fs ? S_ATOMS->m_netwmStateAdd : S_ATOMS->m_netwmStateRemove;
|
fsEvent.data.data32[0] = fs ? S_ATOMS->m_netwmStateAdd : S_ATOMS->m_netwmStateRemove;
|
||||||
fsEvent.data.data32[1] = S_ATOMS->m_netwmStateFullscreen;
|
fsEvent.data.data32[1] = S_ATOMS->m_netwmStateFullscreen;
|
||||||
|
@ -313,7 +334,7 @@ public:
|
||||||
void _incomingEvent(void* e)
|
void _incomingEvent(void* e)
|
||||||
{
|
{
|
||||||
xcb_generic_event_t* event = (xcb_generic_event_t*)e;
|
xcb_generic_event_t* event = (xcb_generic_event_t*)e;
|
||||||
switch (event->response_type & ~0x80)
|
switch (XCB_EVENT_RESPONSE_TYPE(event))
|
||||||
{
|
{
|
||||||
case XCB_EXPOSE:
|
case XCB_EXPOSE:
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue