mirror of https://github.com/AxioDL/boo.git
some app flow redesign
This commit is contained in:
parent
d69e76d911
commit
12e5948d31
|
@ -27,7 +27,6 @@ else()
|
||||||
lib/x11/ApplicationWayland.hpp
|
lib/x11/ApplicationWayland.hpp
|
||||||
lib/x11/WindowXCB.cpp
|
lib/x11/WindowXCB.cpp
|
||||||
lib/x11/WindowWayland.cpp
|
lib/x11/WindowWayland.cpp
|
||||||
lib/x11/GraphicsContextXCB.cpp
|
|
||||||
lib/x11/GraphicsContextWayland.cpp
|
lib/x11/GraphicsContextWayland.cpp
|
||||||
lib/inputdev/HIDListenerUdev.cpp
|
lib/inputdev/HIDListenerUdev.cpp
|
||||||
lib/inputdev/HIDDeviceUdev.cpp)
|
lib/inputdev/HIDDeviceUdev.cpp)
|
||||||
|
@ -73,7 +72,7 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
|
include_directories(${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
|
||||||
list(APPEND _BOO_SYS_LIBS xcb xcb-glx xcb-xinput xcb-xkb xcb-keysyms xkbcommon xkbcommon-x11 ${DBUS_LIBRARY} udev pthread)
|
list(APPEND _BOO_SYS_LIBS xcb xcb-glx xcb-xinput xcb-xkb xcb-keysyms xkbcommon xkbcommon-x11 GL ${DBUS_LIBRARY} udev pthread)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,8 @@ class IApplication;
|
||||||
|
|
||||||
struct IApplicationCallback
|
struct IApplicationCallback
|
||||||
{
|
{
|
||||||
virtual void appLaunched(IApplication* app) {(void)app;}
|
virtual void appQuitting(IApplication*) {}
|
||||||
virtual void appQuitting(IApplication* app) {(void)app;}
|
virtual void appFilesOpen(IApplication*, const std::vector<std::string>&) {}
|
||||||
virtual void appFilesOpen(IApplication* app, const std::vector<std::string>& paths) {(void)app;(void)paths;}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IApplication
|
class IApplication
|
||||||
|
@ -44,8 +43,7 @@ public:
|
||||||
};
|
};
|
||||||
virtual EPlatformType getPlatformType() const=0;
|
virtual EPlatformType getPlatformType() const=0;
|
||||||
|
|
||||||
virtual void run()=0;
|
virtual void pump()=0;
|
||||||
virtual void quit()=0;
|
|
||||||
virtual const std::string& getUniqueName() const=0;
|
virtual const std::string& getUniqueName() const=0;
|
||||||
virtual const std::string& getFriendlyName() const=0;
|
virtual const std::string& getFriendlyName() const=0;
|
||||||
virtual const std::string& getProcessName() const=0;
|
virtual const std::string& getProcessName() const=0;
|
||||||
|
|
|
@ -128,6 +128,8 @@ public:
|
||||||
virtual bool isFullscreen() const=0;
|
virtual bool isFullscreen() const=0;
|
||||||
virtual void setFullscreen(bool fs)=0;
|
virtual void setFullscreen(bool fs)=0;
|
||||||
|
|
||||||
|
virtual void waitForRetrace()=0;
|
||||||
|
|
||||||
virtual uintptr_t getPlatformHandle() const=0;
|
virtual uintptr_t getPlatformHandle() const=0;
|
||||||
virtual void _incomingEvent(void* event) {(void)event;}
|
virtual void _incomingEvent(void* event) {(void)event;}
|
||||||
|
|
||||||
|
|
|
@ -46,12 +46,7 @@ public:
|
||||||
return PLAT_WAYLAND;
|
return PLAT_WAYLAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
void run()
|
void pump()
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void quit()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,13 @@
|
||||||
#include <xkbcommon/xkbcommon-x11.h>
|
#include <xkbcommon/xkbcommon-x11.h>
|
||||||
#include <xcb/xkb.h>
|
#include <xcb/xkb.h>
|
||||||
#include <xcb/xinput.h>
|
#include <xcb/xinput.h>
|
||||||
|
#include <xcb/glx.h>
|
||||||
#undef explicit
|
#undef explicit
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <GL/glx.h>
|
||||||
|
#include <GL/glxext.h>
|
||||||
|
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
DBusConnection* registerDBus(const char* appName, bool& isFirst);
|
DBusConnection* registerDBus(const char* appName, bool& isFirst);
|
||||||
|
|
||||||
|
@ -20,6 +25,10 @@ DBusConnection* registerDBus(const char* appName, bool& isFirst);
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
|
||||||
|
PFNGLXGETVIDEOSYNCSGIPROC FglXGetVideoSyncSGI = nullptr;
|
||||||
|
PFNGLXWAITVIDEOSYNCSGIPROC FglXWaitVideoSyncSGI = nullptr;
|
||||||
|
|
||||||
|
int XCB_GLX_EVENT_BASE = 0;
|
||||||
int XINPUT_OPCODE = 0;
|
int XINPUT_OPCODE = 0;
|
||||||
|
|
||||||
static xcb_window_t getWindowOfEvent(xcb_generic_event_t* event, bool& windowEvent)
|
static xcb_window_t getWindowOfEvent(xcb_generic_event_t* event, bool& windowEvent)
|
||||||
|
@ -131,7 +140,7 @@ class ApplicationXCB final : public IApplication
|
||||||
std::unordered_map<xcb_window_t, IWindow*> m_windows;
|
std::unordered_map<xcb_window_t, IWindow*> m_windows;
|
||||||
|
|
||||||
xcb_connection_t* m_xcbConn = NULL;
|
xcb_connection_t* m_xcbConn = NULL;
|
||||||
bool m_running;
|
int m_xcbFd, m_dbusFd, m_maxFd;
|
||||||
|
|
||||||
void _deletedWindow(IWindow* window)
|
void _deletedWindow(IWindow* window)
|
||||||
{
|
{
|
||||||
|
@ -198,6 +207,13 @@ public:
|
||||||
/* Open X connection */
|
/* Open X connection */
|
||||||
m_xcbConn = xcb_connect(NULL, NULL);
|
m_xcbConn = xcb_connect(NULL, NULL);
|
||||||
|
|
||||||
|
/* GLX extension data */
|
||||||
|
const xcb_query_extension_reply_t* glxExtData =
|
||||||
|
xcb_get_extension_data(m_xcbConn, &xcb_glx_id);
|
||||||
|
XCB_GLX_EVENT_BASE = glxExtData->first_event;
|
||||||
|
FglXGetVideoSyncSGI = PFNGLXGETVIDEOSYNCSGIPROC(glXGetProcAddress((GLubyte*)"glXGetVideoSyncSGI"));
|
||||||
|
FglXWaitVideoSyncSGI = PFNGLXWAITVIDEOSYNCSGIPROC(glXGetProcAddress((GLubyte*)"glXWaitVideoSyncSGI"));
|
||||||
|
|
||||||
/* The xkb extension requests that the X server does not
|
/* The 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,
|
||||||
|
@ -212,9 +228,14 @@ public:
|
||||||
/* Xinput major opcode */
|
/* Xinput major opcode */
|
||||||
const xcb_query_extension_reply_t* xiReply =
|
const xcb_query_extension_reply_t* xiReply =
|
||||||
xcb_get_extension_data(m_xcbConn, &xcb_input_id);
|
xcb_get_extension_data(m_xcbConn, &xcb_input_id);
|
||||||
if (xiReply)
|
XINPUT_OPCODE = xiReply->major_opcode;
|
||||||
XINPUT_OPCODE = xiReply->major_opcode;
|
|
||||||
|
|
||||||
|
/* Get file descriptors of xcb and dbus interfaces */
|
||||||
|
m_xcbFd = xcb_get_file_descriptor(m_xcbConn);
|
||||||
|
dbus_connection_get_unix_fd(m_dbus, &m_dbusFd);
|
||||||
|
m_maxFd = MAX(m_xcbFd, m_dbusFd);
|
||||||
|
|
||||||
|
xcb_flush(m_xcbConn);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ApplicationXCB()
|
~ApplicationXCB()
|
||||||
|
@ -227,35 +248,23 @@ public:
|
||||||
return PLAT_XCB;
|
return PLAT_XCB;
|
||||||
}
|
}
|
||||||
|
|
||||||
void run()
|
void pump()
|
||||||
{
|
{
|
||||||
if (!m_xcbConn)
|
if (!m_xcbConn)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xcb_generic_event_t* event;
|
xcb_generic_event_t* event;
|
||||||
m_running = true;
|
fd_set fds;
|
||||||
m_callback.appLaunched(this);
|
FD_ZERO(&fds);
|
||||||
xcb_flush(m_xcbConn);
|
FD_SET(m_xcbFd, &fds);
|
||||||
|
FD_SET(m_dbusFd, &fds);
|
||||||
|
select(m_maxFd+1, &fds, NULL, NULL, NULL);
|
||||||
|
|
||||||
int xcbFd = xcb_get_file_descriptor(m_xcbConn);
|
if (FD_ISSET(m_xcbFd, &fds))
|
||||||
int dbusFd;
|
|
||||||
dbus_connection_get_unix_fd(m_dbus, &dbusFd);
|
|
||||||
int maxFd = MAX(xcbFd, dbusFd);
|
|
||||||
|
|
||||||
while (m_running)
|
|
||||||
{
|
{
|
||||||
fd_set fds;
|
event = xcb_poll_for_event(m_xcbConn);
|
||||||
FD_ZERO(&fds);
|
if (event)
|
||||||
FD_SET(xcbFd, &fds);
|
|
||||||
FD_SET(dbusFd, &fds);
|
|
||||||
select(maxFd+1, &fds, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
if (FD_ISSET(xcbFd, &fds))
|
|
||||||
{
|
{
|
||||||
event = xcb_poll_for_event(m_xcbConn);
|
|
||||||
if (!event)
|
|
||||||
break;
|
|
||||||
|
|
||||||
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));
|
//fprintf(stderr, "EVENT %d\n", XCB_EVENT_RESPONSE_TYPE(event));
|
||||||
|
@ -267,40 +276,33 @@ public:
|
||||||
}
|
}
|
||||||
free(event);
|
free(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(dbusFd, &fds))
|
|
||||||
{
|
|
||||||
DBusMessage* msg;
|
|
||||||
dbus_connection_read_write(m_dbus, 0);
|
|
||||||
while ((msg = dbus_connection_pop_message(m_dbus)))
|
|
||||||
{
|
|
||||||
/* check if the message is a signal from the correct interface and with the correct name */
|
|
||||||
if (dbus_message_is_signal(msg, "boo.signal.FileHandling", "Open"))
|
|
||||||
{
|
|
||||||
/* read the parameters */
|
|
||||||
std::vector<std::string> paths;
|
|
||||||
DBusMessageIter iter;
|
|
||||||
dbus_message_iter_init(msg, &iter);
|
|
||||||
while (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID)
|
|
||||||
{
|
|
||||||
const char* argVal;
|
|
||||||
dbus_message_iter_get_basic(&iter, &argVal);
|
|
||||||
paths.push_back(argVal);
|
|
||||||
dbus_message_iter_next(&iter);
|
|
||||||
}
|
|
||||||
m_callback.appFilesOpen(this, paths);
|
|
||||||
}
|
|
||||||
dbus_message_unref(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_callback.appQuitting(this);
|
if (FD_ISSET(m_dbusFd, &fds))
|
||||||
}
|
{
|
||||||
|
DBusMessage* msg;
|
||||||
void quit()
|
dbus_connection_read_write(m_dbus, 0);
|
||||||
{
|
while ((msg = dbus_connection_pop_message(m_dbus)))
|
||||||
m_running = false;
|
{
|
||||||
|
/* check if the message is a signal from the correct interface and with the correct name */
|
||||||
|
if (dbus_message_is_signal(msg, "boo.signal.FileHandling", "Open"))
|
||||||
|
{
|
||||||
|
/* read the parameters */
|
||||||
|
std::vector<std::string> paths;
|
||||||
|
DBusMessageIter iter;
|
||||||
|
dbus_message_iter_init(msg, &iter);
|
||||||
|
while (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID)
|
||||||
|
{
|
||||||
|
const char* argVal;
|
||||||
|
dbus_message_iter_get_basic(&iter, &argVal);
|
||||||
|
paths.push_back(argVal);
|
||||||
|
dbus_message_iter_next(&iter);
|
||||||
|
}
|
||||||
|
m_callback.appFilesOpen(this, paths);
|
||||||
|
}
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& getUniqueName() const
|
const std::string& getUniqueName() const
|
||||||
|
|
|
@ -1,153 +0,0 @@
|
||||||
#include "boo/IGraphicsContext.hpp"
|
|
||||||
#include "boo/IWindow.hpp"
|
|
||||||
|
|
||||||
#include <xcb/xcb.h>
|
|
||||||
#include <xcb/glx.h>
|
|
||||||
#include <GL/glx.h>
|
|
||||||
#include <GL/glcorearb.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
namespace boo
|
|
||||||
{
|
|
||||||
|
|
||||||
struct GraphicsContextXCB : IGraphicsContext
|
|
||||||
{
|
|
||||||
|
|
||||||
EGraphicsAPI m_api;
|
|
||||||
EPixelFormat m_pf;
|
|
||||||
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;
|
|
||||||
|
|
||||||
std::thread* m_commandThread = NULL;
|
|
||||||
|
|
||||||
public:
|
|
||||||
IWindowCallback* m_callback;
|
|
||||||
|
|
||||||
GraphicsContextXCB(EGraphicsAPI api, IWindow* parentWindow, xcb_connection_t* conn, uint32_t& visualIdOut)
|
|
||||||
: m_api(api),
|
|
||||||
m_pf(PF_RGBA8),
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "unable to find suitable pixel format");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
visualIdOut = m_visualid;
|
|
||||||
}
|
|
||||||
|
|
||||||
~GraphicsContextXCB()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void _setCallback(IWindowCallback* cb)
|
|
||||||
{
|
|
||||||
m_callback = cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
EGraphicsAPI getAPI() const
|
|
||||||
{
|
|
||||||
return m_api;
|
|
||||||
}
|
|
||||||
|
|
||||||
EPixelFormat getPixelFormat() const
|
|
||||||
{
|
|
||||||
return m_pf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPixelFormat(EPixelFormat pf)
|
|
||||||
{
|
|
||||||
if (pf > PF_RGBAF32_Z24)
|
|
||||||
return;
|
|
||||||
m_pf = pf;
|
|
||||||
}
|
|
||||||
|
|
||||||
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* _GraphicsContextXCBNew(IGraphicsContext::EGraphicsAPI api,
|
|
||||||
IWindow* parentWindow, xcb_connection_t* conn,
|
|
||||||
uint32_t& visualIdOut)
|
|
||||||
{
|
|
||||||
return new GraphicsContextXCB(api, parentWindow, conn, visualIdOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +1,16 @@
|
||||||
#include "boo/IWindow.hpp"
|
#include "boo/IWindow.hpp"
|
||||||
#include "boo/IGraphicsContext.hpp"
|
#include "boo/IGraphicsContext.hpp"
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <GL/glx.h>
|
||||||
|
#include <GL/glxext.h>
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
|
||||||
|
extern PFNGLXGETVIDEOSYNCSGIPROC FglXGetVideoSyncSGI;
|
||||||
|
extern PFNGLXWAITVIDEOSYNCSGIPROC FglXWaitVideoSyncSGI;
|
||||||
|
|
||||||
IGraphicsContext* _CGraphicsContextWaylandNew(IGraphicsContext::EGraphicsAPI api,
|
IGraphicsContext* _CGraphicsContextWaylandNew(IGraphicsContext::EGraphicsAPI api,
|
||||||
IWindow* parentWindow);
|
IWindow* parentWindow);
|
||||||
|
|
||||||
|
@ -74,6 +81,12 @@ struct WindowWayland : IWindow
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void waitForRetrace()
|
||||||
|
{
|
||||||
|
unsigned int sync;
|
||||||
|
FglXWaitVideoSyncSGI(1, 0, &sync);
|
||||||
|
}
|
||||||
|
|
||||||
uintptr_t getPlatformHandle() const
|
uintptr_t getPlatformHandle() const
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
#include <xcb/xcb_keysyms.h>
|
#include <xcb/xcb_keysyms.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include <xcb/xinput.h>
|
#include <xcb/xinput.h>
|
||||||
|
#include <xcb/glx.h>
|
||||||
|
#include <GL/glx.h>
|
||||||
|
#include <GL/glcorearb.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -25,6 +28,10 @@
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
|
||||||
|
extern PFNGLXGETVIDEOSYNCSGIPROC FglXGetVideoSyncSGI;
|
||||||
|
extern PFNGLXWAITVIDEOSYNCSGIPROC FglXWaitVideoSyncSGI;
|
||||||
|
|
||||||
|
extern int XCB_GLX_EVENT_BASE;
|
||||||
extern int XINPUT_OPCODE;
|
extern int XINPUT_OPCODE;
|
||||||
|
|
||||||
static inline double fp3232val(xcb_input_fp3232_t* val)
|
static inline double fp3232val(xcb_input_fp3232_t* val)
|
||||||
|
@ -146,16 +153,141 @@ static void genFrameDefault(xcb_screen_t* screen, int* xOut, int* yOut, int* wOu
|
||||||
*hOut = height;
|
*hOut = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsContext* _GraphicsContextXCBNew(IGraphicsContext::EGraphicsAPI api,
|
struct GraphicsContextXCB : IGraphicsContext
|
||||||
IWindow* parentWindow, xcb_connection_t* conn,
|
{
|
||||||
uint32_t& visualIdOut);
|
EGraphicsAPI m_api;
|
||||||
|
EPixelFormat m_pf;
|
||||||
|
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:
|
||||||
|
IWindowCallback* m_callback;
|
||||||
|
|
||||||
|
GraphicsContextXCB(EGraphicsAPI api, IWindow* parentWindow, xcb_connection_t* conn, uint32_t& visualIdOut)
|
||||||
|
: m_api(api),
|
||||||
|
m_pf(PF_RGBA8),
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "unable to find suitable pixel format");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
visualIdOut = m_visualid;
|
||||||
|
}
|
||||||
|
|
||||||
|
~GraphicsContextXCB()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setCallback(IWindowCallback* cb)
|
||||||
|
{
|
||||||
|
m_callback = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGraphicsAPI getAPI() const
|
||||||
|
{
|
||||||
|
return m_api;
|
||||||
|
}
|
||||||
|
|
||||||
|
EPixelFormat getPixelFormat() const
|
||||||
|
{
|
||||||
|
return m_pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPixelFormat(EPixelFormat pf)
|
||||||
|
{
|
||||||
|
if (pf > PF_RGBAF32_Z24)
|
||||||
|
return;
|
||||||
|
m_pf = pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
struct WindowXCB : IWindow
|
struct WindowXCB : IWindow
|
||||||
{
|
{
|
||||||
xcb_connection_t* m_xcbConn;
|
xcb_connection_t* m_xcbConn;
|
||||||
xcb_window_t m_windowId;
|
|
||||||
IGraphicsContext* m_gfxCtx;
|
|
||||||
IWindowCallback* m_callback;
|
IWindowCallback* m_callback;
|
||||||
|
xcb_window_t m_windowId;
|
||||||
|
GraphicsContextXCB m_gfxCtx;
|
||||||
|
uint32_t m_visualId;
|
||||||
|
|
||||||
/* Last known input device id (0xffff if not yet set) */
|
/* Last known input device id (0xffff if not yet set) */
|
||||||
xcb_input_device_id_t m_lastInputID = 0xffff;
|
xcb_input_device_id_t m_lastInputID = 0xffff;
|
||||||
|
@ -174,7 +306,7 @@ struct WindowXCB : IWindow
|
||||||
public:
|
public:
|
||||||
|
|
||||||
WindowXCB(const std::string& title, xcb_connection_t* conn)
|
WindowXCB(const std::string& title, xcb_connection_t* conn)
|
||||||
: m_xcbConn(conn), m_callback(NULL)
|
: m_xcbConn(conn), m_callback(NULL), m_gfxCtx(IGraphicsContext::API_OPENGL_3_3, this, m_xcbConn, m_visualId)
|
||||||
{
|
{
|
||||||
if (!S_ATOMS)
|
if (!S_ATOMS)
|
||||||
S_ATOMS = new XCBAtoms(conn);
|
S_ATOMS = new XCBAtoms(conn);
|
||||||
|
@ -183,14 +315,10 @@ public:
|
||||||
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 = _GraphicsContextXCBNew(IGraphicsContext::API_OPENGL_3_3, this, m_xcbConn, visualId);
|
|
||||||
|
|
||||||
/* Create colormap */
|
/* Create colormap */
|
||||||
xcb_colormap_t colormap = xcb_generate_id(m_xcbConn);
|
xcb_colormap_t colormap = xcb_generate_id(m_xcbConn);
|
||||||
xcb_create_colormap(m_xcbConn, XCB_COLORMAP_ALLOC_NONE,
|
xcb_create_colormap(m_xcbConn, XCB_COLORMAP_ALLOC_NONE,
|
||||||
colormap, screen->root, visualId);
|
colormap, screen->root, m_visualId);
|
||||||
|
|
||||||
/* Create window */
|
/* Create window */
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
|
@ -208,10 +336,11 @@ public:
|
||||||
m_windowId = xcb_generate_id(conn);
|
m_windowId = xcb_generate_id(conn);
|
||||||
xcb_create_window(m_xcbConn, XCB_COPY_FROM_PARENT, m_windowId, screen->root,
|
xcb_create_window(m_xcbConn, XCB_COPY_FROM_PARENT, m_windowId, screen->root,
|
||||||
x, y, w, h, 10,
|
x, y, w, h, 10,
|
||||||
XCB_WINDOW_CLASS_INPUT_OUTPUT, visualId,
|
XCB_WINDOW_CLASS_INPUT_OUTPUT, m_visualId,
|
||||||
XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
|
XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
|
||||||
valueMasks);
|
valueMasks);
|
||||||
|
|
||||||
|
|
||||||
/* The XInput 2.1 extension enables per-pixel smooth scrolling trackpads */
|
/* The XInput 2.1 extension enables per-pixel smooth scrolling trackpads */
|
||||||
xcb_generic_error_t* xiErr = NULL;
|
xcb_generic_error_t* xiErr = NULL;
|
||||||
xcb_input_xi_query_version_reply_t* xiReply =
|
xcb_input_xi_query_version_reply_t* xiReply =
|
||||||
|
@ -262,7 +391,7 @@ public:
|
||||||
xcb_map_window(m_xcbConn, m_windowId);
|
xcb_map_window(m_xcbConn, m_windowId);
|
||||||
xcb_flush(m_xcbConn);
|
xcb_flush(m_xcbConn);
|
||||||
|
|
||||||
m_gfxCtx->initializeContext();
|
m_gfxCtx.initializeContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
~WindowXCB()
|
~WindowXCB()
|
||||||
|
@ -383,6 +512,12 @@ public:
|
||||||
(const char*)&fsEvent);
|
(const char*)&fsEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void waitForRetrace()
|
||||||
|
{
|
||||||
|
unsigned int sync;
|
||||||
|
FglXWaitVideoSyncSGI(1, 0, &sync);
|
||||||
|
}
|
||||||
|
|
||||||
uintptr_t getPlatformHandle() const
|
uintptr_t getPlatformHandle() const
|
||||||
{
|
{
|
||||||
return (uintptr_t)m_windowId;
|
return (uintptr_t)m_windowId;
|
||||||
|
|
|
@ -200,7 +200,6 @@ int main(int argc, const char** argv)
|
||||||
std::unique_ptr<boo::IApplication> app =
|
std::unique_ptr<boo::IApplication> app =
|
||||||
ApplicationBootstrap(boo::IApplication::PLAT_AUTO,
|
ApplicationBootstrap(boo::IApplication::PLAT_AUTO,
|
||||||
appCb, "rwk", "RWK", argc, argv);
|
appCb, "rwk", "RWK", argc, argv);
|
||||||
app->run();
|
|
||||||
printf("IM DYING!!\n");
|
printf("IM DYING!!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue