mirror of https://github.com/AxioDL/boo.git
Fallback flow for graphics APIs
This commit is contained in:
parent
1c8236d100
commit
66c64cde08
|
@ -45,7 +45,7 @@ public:
|
||||||
virtual EGraphicsAPI getAPI() const=0;
|
virtual EGraphicsAPI getAPI() const=0;
|
||||||
virtual EPixelFormat getPixelFormat() const=0;
|
virtual EPixelFormat getPixelFormat() const=0;
|
||||||
virtual void setPixelFormat(EPixelFormat pf)=0;
|
virtual void setPixelFormat(EPixelFormat pf)=0;
|
||||||
virtual void initializeContext(void* handle)=0;
|
virtual bool initializeContext(void* handle)=0;
|
||||||
virtual void makeCurrent()=0;
|
virtual void makeCurrent()=0;
|
||||||
virtual void postInit()=0;
|
virtual void postInit()=0;
|
||||||
virtual void present()=0;
|
virtual void present()=0;
|
||||||
|
|
|
@ -74,7 +74,7 @@ struct VulkanContext
|
||||||
std::unordered_map<const boo::IWindow*, std::unique_ptr<Window>> m_windows;
|
std::unordered_map<const boo::IWindow*, std::unique_ptr<Window>> m_windows;
|
||||||
|
|
||||||
void initVulkan(const char* appName);
|
void initVulkan(const char* appName);
|
||||||
void enumerateDevices();
|
bool enumerateDevices();
|
||||||
void initDevice();
|
void initDevice();
|
||||||
void initSwapChain(Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace);
|
void initSwapChain(Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace);
|
||||||
void resizeSwapChain(Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace);
|
void resizeSwapChain(Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace);
|
||||||
|
|
|
@ -342,26 +342,32 @@ void VulkanContext::initVulkan(const char* appName)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::enumerateDevices()
|
bool VulkanContext::enumerateDevices()
|
||||||
{
|
{
|
||||||
uint32_t gpuCount = 1;
|
uint32_t gpuCount = 1;
|
||||||
ThrowIfFailed(vk::EnumeratePhysicalDevices(m_instance, &gpuCount, nullptr));
|
ThrowIfFailed(vk::EnumeratePhysicalDevices(m_instance, &gpuCount, nullptr));
|
||||||
assert(gpuCount);
|
if (!gpuCount)
|
||||||
|
return false;
|
||||||
m_gpus.resize(gpuCount);
|
m_gpus.resize(gpuCount);
|
||||||
|
|
||||||
ThrowIfFailed(vk::EnumeratePhysicalDevices(m_instance, &gpuCount, m_gpus.data()));
|
ThrowIfFailed(vk::EnumeratePhysicalDevices(m_instance, &gpuCount, m_gpus.data()));
|
||||||
assert(gpuCount >= 1);
|
if (!gpuCount)
|
||||||
|
return false;
|
||||||
|
|
||||||
vk::GetPhysicalDeviceQueueFamilyProperties(m_gpus[0], &m_queueCount, nullptr);
|
vk::GetPhysicalDeviceQueueFamilyProperties(m_gpus[0], &m_queueCount, nullptr);
|
||||||
assert(m_queueCount >= 1);
|
if (!m_queueCount)
|
||||||
|
return false;
|
||||||
|
|
||||||
m_queueProps.resize(m_queueCount);
|
m_queueProps.resize(m_queueCount);
|
||||||
vk::GetPhysicalDeviceQueueFamilyProperties(m_gpus[0], &m_queueCount, m_queueProps.data());
|
vk::GetPhysicalDeviceQueueFamilyProperties(m_gpus[0], &m_queueCount, m_queueProps.data());
|
||||||
assert(m_queueCount >= 1);
|
if (!m_queueCount)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* This is as good a place as any to do this */
|
/* This is as good a place as any to do this */
|
||||||
vk::GetPhysicalDeviceMemoryProperties(m_gpus[0], &m_memoryProperties);
|
vk::GetPhysicalDeviceMemoryProperties(m_gpus[0], &m_memoryProperties);
|
||||||
vk::GetPhysicalDeviceProperties(m_gpus[0], &m_gpuProps);
|
vk::GetPhysicalDeviceProperties(m_gpus[0], &m_gpuProps);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::initDevice()
|
void VulkanContext::initDevice()
|
||||||
|
|
|
@ -219,7 +219,7 @@ public:
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeContext(void*)
|
bool initializeContext(void*)
|
||||||
{
|
{
|
||||||
m_nsContext = [[GraphicsContextCocoaGLInternal alloc] initWithBooContext:this];
|
m_nsContext = [[GraphicsContextCocoaGLInternal alloc] initWithBooContext:this];
|
||||||
if (!m_nsContext)
|
if (!m_nsContext)
|
||||||
|
@ -229,6 +229,7 @@ public:
|
||||||
CVDisplayLinkSetOutputCallback(m_dispLink, (CVDisplayLinkOutputCallback)DLCallback, this);
|
CVDisplayLinkSetOutputCallback(m_dispLink, (CVDisplayLinkOutputCallback)DLCallback, this);
|
||||||
CVDisplayLinkStart(m_dispLink);
|
CVDisplayLinkStart(m_dispLink);
|
||||||
m_commandQueue = _NewGLCommandQueue(this);
|
m_commandQueue = _NewGLCommandQueue(this);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent()
|
void makeCurrent()
|
||||||
|
@ -375,7 +376,7 @@ public:
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeContext(void*)
|
bool initializeContext(void*)
|
||||||
{
|
{
|
||||||
MetalContext::Window& w = m_metalCtx->m_windows[m_parentWindow];
|
MetalContext::Window& w = m_metalCtx->m_windows[m_parentWindow];
|
||||||
m_nsContext = [[GraphicsContextCocoaMetalInternal alloc] initWithBooContext:this];
|
m_nsContext = [[GraphicsContextCocoaMetalInternal alloc] initWithBooContext:this];
|
||||||
|
@ -387,6 +388,7 @@ public:
|
||||||
CVDisplayLinkSetOutputCallback(m_dispLink, (CVDisplayLinkOutputCallback)DLCallback, this);
|
CVDisplayLinkSetOutputCallback(m_dispLink, (CVDisplayLinkOutputCallback)DLCallback, this);
|
||||||
CVDisplayLinkStart(m_dispLink);
|
CVDisplayLinkStart(m_dispLink);
|
||||||
m_commandQueue = _NewMetalCommandQueue(m_metalCtx, m_parentWindow, this);
|
m_commandQueue = _NewMetalCommandQueue(m_metalCtx, m_parentWindow, this);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent()
|
void makeCurrent()
|
||||||
|
|
|
@ -164,7 +164,7 @@ public:
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeContext(void*) {}
|
bool initializeContext(void*) {return true;}
|
||||||
|
|
||||||
void makeCurrent() {}
|
void makeCurrent() {}
|
||||||
|
|
||||||
|
@ -305,7 +305,7 @@ public:
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeContext(void*) {}
|
bool initializeContext(void*) {return true;}
|
||||||
|
|
||||||
void makeCurrent()
|
void makeCurrent()
|
||||||
{
|
{
|
||||||
|
@ -487,7 +487,7 @@ public:
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeContext(void* getVkProc)
|
bool initializeContext(void* getVkProc)
|
||||||
{
|
{
|
||||||
vk::init_dispatch_table_top(PFN_vkGetInstanceProcAddr(getVkProc));
|
vk::init_dispatch_table_top(PFN_vkGetInstanceProcAddr(getVkProc));
|
||||||
if (m_ctx->m_instance == VK_NULL_HANDLE)
|
if (m_ctx->m_instance == VK_NULL_HANDLE)
|
||||||
|
@ -500,7 +500,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::init_dispatch_table_middle(m_ctx->m_instance, false);
|
vk::init_dispatch_table_middle(m_ctx->m_instance, false);
|
||||||
m_ctx->enumerateDevices();
|
if (!m_ctx->enumerateDevices())
|
||||||
|
return false;
|
||||||
|
|
||||||
m_windowCtx =
|
m_windowCtx =
|
||||||
m_ctx->m_windows.emplace(std::make_pair(m_parentWindow,
|
m_ctx->m_windows.emplace(std::make_pair(m_parentWindow,
|
||||||
|
@ -554,7 +555,7 @@ public:
|
||||||
if (!vk::GetPhysicalDeviceWin32PresentationSupportKHR(m_ctx->m_gpus[0], m_ctx->m_graphicsQueueFamilyIndex))
|
if (!vk::GetPhysicalDeviceWin32PresentationSupportKHR(m_ctx->m_gpus[0], m_ctx->m_graphicsQueueFamilyIndex))
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Fatal, "Win32 doesn't support vulkan present");
|
Log.report(logvisor::Fatal, "Win32 doesn't support vulkan present");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the list of VkFormats that are supported */
|
/* Get the list of VkFormats that are supported */
|
||||||
|
@ -582,6 +583,7 @@ public:
|
||||||
|
|
||||||
m_dataFactory = new class VulkanDataFactory(this, m_ctx, m_sampleCount);
|
m_dataFactory = new class VulkanDataFactory(this, m_ctx, m_sampleCount);
|
||||||
m_commandQueue = _NewVulkanCommandQueue(m_ctx, m_ctx->m_windows[m_parentWindow].get(), this);
|
m_commandQueue = _NewVulkanCommandQueue(m_ctx, m_ctx->m_windows[m_parentWindow].get(), this);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent() {}
|
void makeCurrent() {}
|
||||||
|
@ -974,8 +976,8 @@ public:
|
||||||
{
|
{
|
||||||
m_gfxCtx.reset(new GraphicsContextWin32Vulkan(this, wndInstance, m_hwnd, &g_VulkanContext,
|
m_gfxCtx.reset(new GraphicsContextWin32Vulkan(this, wndInstance, m_hwnd, &g_VulkanContext,
|
||||||
b3dCtx, sampleCount));
|
b3dCtx, sampleCount));
|
||||||
m_gfxCtx->initializeContext(vulkanHandle);
|
if (m_gfxCtx->initializeContext(vulkanHandle))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx, sampleCount));
|
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx, sampleCount));
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,9 +50,9 @@ public:
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeContext(void*)
|
bool initializeContext(void*)
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent()
|
void makeCurrent()
|
||||||
|
|
|
@ -439,7 +439,7 @@ public:
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeContext(void*)
|
bool initializeContext(void*)
|
||||||
{
|
{
|
||||||
if (!glXCreateContextAttribsARB)
|
if (!glXCreateContextAttribsARB)
|
||||||
{
|
{
|
||||||
|
@ -522,6 +522,8 @@ public:
|
||||||
XUnlockDisplay(m_xDisp);
|
XUnlockDisplay(m_xDisp);
|
||||||
m_commandQueue = _NewGLCommandQueue(this);
|
m_commandQueue = _NewGLCommandQueue(this);
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent()
|
void makeCurrent()
|
||||||
|
@ -675,7 +677,7 @@ public:
|
||||||
m_pf = pf;
|
m_pf = pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeContext(void* getVkProc)
|
bool initializeContext(void* getVkProc)
|
||||||
{
|
{
|
||||||
if (!glXWaitVideoSyncSGI)
|
if (!glXWaitVideoSyncSGI)
|
||||||
{
|
{
|
||||||
|
@ -690,7 +692,8 @@ public:
|
||||||
m_ctx->initVulkan(APP->getUniqueName().c_str());
|
m_ctx->initVulkan(APP->getUniqueName().c_str());
|
||||||
|
|
||||||
vk::init_dispatch_table_middle(m_ctx->m_instance, false);
|
vk::init_dispatch_table_middle(m_ctx->m_instance, false);
|
||||||
m_ctx->enumerateDevices();
|
if (!m_ctx->enumerateDevices())
|
||||||
|
return false;
|
||||||
|
|
||||||
m_windowCtx =
|
m_windowCtx =
|
||||||
m_ctx->m_windows.emplace(std::make_pair(m_parentWindow,
|
m_ctx->m_windows.emplace(std::make_pair(m_parentWindow,
|
||||||
|
@ -744,7 +747,7 @@ public:
|
||||||
if (!vk::GetPhysicalDeviceXcbPresentationSupportKHR(m_ctx->m_gpus[0], m_ctx->m_graphicsQueueFamilyIndex, m_xcbConn, m_visualid))
|
if (!vk::GetPhysicalDeviceXcbPresentationSupportKHR(m_ctx->m_gpus[0], m_ctx->m_graphicsQueueFamilyIndex, m_xcbConn, m_visualid))
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Fatal, "XCB visual doesn't support vulkan present");
|
Log.report(logvisor::Fatal, "XCB visual doesn't support vulkan present");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the list of VkFormats that are supported */
|
/* Get the list of VkFormats that are supported */
|
||||||
|
@ -817,6 +820,8 @@ public:
|
||||||
|
|
||||||
m_dataFactory = new class VulkanDataFactory(this, m_ctx, m_drawSamples);
|
m_dataFactory = new class VulkanDataFactory(this, m_ctx, m_drawSamples);
|
||||||
m_commandQueue = _NewVulkanCommandQueue(m_ctx, m_ctx->m_windows[m_parentWindow].get(), this);
|
m_commandQueue = _NewVulkanCommandQueue(m_ctx, m_ctx->m_windows[m_parentWindow].get(), this);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeCurrent() {}
|
void makeCurrent() {}
|
||||||
|
@ -916,108 +921,123 @@ public:
|
||||||
if (!S_ATOMS)
|
if (!S_ATOMS)
|
||||||
S_ATOMS = new XlibAtoms(display);
|
S_ATOMS = new XlibAtoms(display);
|
||||||
|
|
||||||
|
for (int i = 1; i >= 0 ; --i)
|
||||||
|
{
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
if (vulkanHandle)
|
if (vulkanHandle && i == 1)
|
||||||
m_gfxCtx.reset(new GraphicsContextXlibVulkan(this, display, (xcb_connection_t*)xcbConn, defaultScreen,
|
|
||||||
&g_VulkanContext, m_visualId, drawSamples));
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
m_gfxCtx.reset(new GraphicsContextXlibGLX(IGraphicsContext::EGraphicsAPI::OpenGL3_3,
|
|
||||||
this, display, defaultScreen, lastCtx, m_visualId, drawSamples));
|
|
||||||
|
|
||||||
/* Default screen */
|
|
||||||
Screen* screen = ScreenOfDisplay(display, defaultScreen);
|
|
||||||
m_pixelFactor = screen->width / (float)screen->mwidth / REF_DPMM;
|
|
||||||
|
|
||||||
XVisualInfo visTemplate;
|
|
||||||
visTemplate.screen = defaultScreen;
|
|
||||||
int numVisuals;
|
|
||||||
XVisualInfo* visualList = XGetVisualInfo(display, VisualScreenMask, &visTemplate, &numVisuals);
|
|
||||||
Visual* selectedVisual = nullptr;
|
|
||||||
for (int i=0 ; i<numVisuals ; ++i)
|
|
||||||
{
|
|
||||||
if (visualList[i].visualid == m_visualId)
|
|
||||||
{
|
{
|
||||||
selectedVisual = visualList[i].visual;
|
m_gfxCtx.reset(new GraphicsContextXlibVulkan(this, display, (xcb_connection_t*)xcbConn, defaultScreen,
|
||||||
break;
|
&g_VulkanContext, m_visualId, drawSamples));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
m_gfxCtx.reset(new GraphicsContextXlibGLX(IGraphicsContext::EGraphicsAPI::OpenGL3_3,
|
||||||
|
this, display, defaultScreen, lastCtx, m_visualId, drawSamples));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Default screen */
|
||||||
|
Screen* screen = ScreenOfDisplay(display, defaultScreen);
|
||||||
|
m_pixelFactor = screen->width / (float)screen->mwidth / REF_DPMM;
|
||||||
|
|
||||||
|
XVisualInfo visTemplate;
|
||||||
|
visTemplate.screen = defaultScreen;
|
||||||
|
int numVisuals;
|
||||||
|
XVisualInfo* visualList = XGetVisualInfo(display, VisualScreenMask, &visTemplate, &numVisuals);
|
||||||
|
Visual* selectedVisual = nullptr;
|
||||||
|
for (int i=0 ; i<numVisuals ; ++i)
|
||||||
|
{
|
||||||
|
if (visualList[i].visualid == m_visualId)
|
||||||
|
{
|
||||||
|
selectedVisual = visualList[i].visual;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFree(visualList);
|
||||||
|
|
||||||
|
/* Create colormap */
|
||||||
|
m_colormapId = XCreateColormap(m_xDisp, screen->root, selectedVisual, AllocNone);
|
||||||
|
|
||||||
|
/* Create window */
|
||||||
|
int x, y, w, h;
|
||||||
|
genFrameDefault(screen, x, y, w, h);
|
||||||
|
XSetWindowAttributes swa;
|
||||||
|
swa.colormap = m_colormapId;
|
||||||
|
swa.border_pixmap = 0;
|
||||||
|
swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | StructureNotifyMask | LeaveWindowMask | EnterWindowMask;
|
||||||
|
|
||||||
|
m_windowId = XCreateWindow(display, screen->root, x, y, w, h, 10,
|
||||||
|
CopyFromParent, CopyFromParent, selectedVisual,
|
||||||
|
CWBorderPixel | CWEventMask | CWColormap, &swa);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now go create an IC using the style we chose.
|
||||||
|
* Also set the window and fontset attributes now.
|
||||||
|
*/
|
||||||
|
if (xIM)
|
||||||
|
{
|
||||||
|
XPoint pt = {0,0};
|
||||||
|
XVaNestedList nlist;
|
||||||
|
m_xIC = XCreateIC(xIM, XNInputStyle, bestInputStyle,
|
||||||
|
XNClientWindow, m_windowId,
|
||||||
|
XNFocusWindow, m_windowId,
|
||||||
|
XNPreeditAttributes, nlist = XVaCreateNestedList(0,
|
||||||
|
XNSpotLocation, &pt,
|
||||||
|
XNFontSet, fontset,
|
||||||
|
nullptr),
|
||||||
|
nullptr);
|
||||||
|
XFree(nlist);
|
||||||
|
long im_event_mask;
|
||||||
|
XGetICValues(m_xIC, XNFilterEvents, &im_event_mask, nullptr);
|
||||||
|
XSelectInput(display, m_windowId, swa.event_mask | im_event_mask);
|
||||||
|
XSetICFocus(m_xIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The XInput 2.1 extension enables per-pixel smooth scrolling trackpads */
|
||||||
|
XIEventMask mask = {XIAllMasterDevices, XIMaskLen(XI_LASTEVENT)};
|
||||||
|
mask.mask = (unsigned char*)malloc(mask.mask_len);
|
||||||
|
memset(mask.mask, 0, mask.mask_len);
|
||||||
|
/* XISetMask(mask.mask, XI_Motion); Can't do this without losing mouse move events :( */
|
||||||
|
XISetMask(mask.mask, XI_TouchBegin);
|
||||||
|
XISetMask(mask.mask, XI_TouchUpdate);
|
||||||
|
XISetMask(mask.mask, XI_TouchEnd);
|
||||||
|
XISelectEvents(m_xDisp, m_windowId, &mask, 1);
|
||||||
|
free(mask.mask);
|
||||||
|
|
||||||
|
|
||||||
|
/* Register netwm extension atom for window closing */
|
||||||
|
XSetWMProtocols(m_xDisp, m_windowId, &S_ATOMS->m_wmDeleteWindow, 1);
|
||||||
|
|
||||||
|
/* Set the title of the window */
|
||||||
|
const unsigned char* c_title = (unsigned char*)title.c_str();
|
||||||
|
XChangeProperty(m_xDisp, m_windowId, XA_WM_NAME, XA_STRING, 8, PropModeReplace, c_title, title.length());
|
||||||
|
|
||||||
|
/* Set the title of the window icon */
|
||||||
|
XChangeProperty(m_xDisp, m_windowId, XA_WM_ICON_NAME, XA_STRING, 8, PropModeReplace, c_title, title.length());
|
||||||
|
|
||||||
|
/* Add window icon */
|
||||||
|
if (MAINICON_NETWM_SZ && S_ATOMS->m_netwmIcon)
|
||||||
|
{
|
||||||
|
XChangeProperty(display, m_windowId, S_ATOMS->m_netwmIcon, XA_CARDINAL,
|
||||||
|
32, PropModeReplace, MAINICON_NETWM, MAINICON_NETWM_SZ / sizeof(unsigned long));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize context */
|
||||||
|
XMapWindow(m_xDisp, m_windowId);
|
||||||
|
setStyle(EWindowStyle::Default);
|
||||||
|
setCursor(EMouseCursor::Pointer);
|
||||||
|
XFlush(m_xDisp);
|
||||||
|
|
||||||
|
if (!m_gfxCtx->initializeContext(vulkanHandle))
|
||||||
|
{
|
||||||
|
XUnmapWindow(m_xDisp, m_windowId);
|
||||||
|
XDestroyWindow(m_xDisp, m_windowId);
|
||||||
|
XFreeColormap(m_xDisp, m_colormapId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
XFree(visualList);
|
|
||||||
|
|
||||||
/* Create colormap */
|
|
||||||
m_colormapId = XCreateColormap(m_xDisp, screen->root, selectedVisual, AllocNone);
|
|
||||||
|
|
||||||
/* Create window */
|
|
||||||
int x, y, w, h;
|
|
||||||
genFrameDefault(screen, x, y, w, h);
|
|
||||||
XSetWindowAttributes swa;
|
|
||||||
swa.colormap = m_colormapId;
|
|
||||||
swa.border_pixmap = 0;
|
|
||||||
swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | StructureNotifyMask | LeaveWindowMask | EnterWindowMask;
|
|
||||||
|
|
||||||
m_windowId = XCreateWindow(display, screen->root, x, y, w, h, 10,
|
|
||||||
CopyFromParent, CopyFromParent, selectedVisual,
|
|
||||||
CWBorderPixel | CWEventMask | CWColormap, &swa);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now go create an IC using the style we chose.
|
|
||||||
* Also set the window and fontset attributes now.
|
|
||||||
*/
|
|
||||||
if (xIM)
|
|
||||||
{
|
|
||||||
XPoint pt = {0,0};
|
|
||||||
XVaNestedList nlist;
|
|
||||||
m_xIC = XCreateIC(xIM, XNInputStyle, bestInputStyle,
|
|
||||||
XNClientWindow, m_windowId,
|
|
||||||
XNFocusWindow, m_windowId,
|
|
||||||
XNPreeditAttributes, nlist = XVaCreateNestedList(0,
|
|
||||||
XNSpotLocation, &pt,
|
|
||||||
XNFontSet, fontset,
|
|
||||||
nullptr),
|
|
||||||
nullptr);
|
|
||||||
XFree(nlist);
|
|
||||||
long im_event_mask;
|
|
||||||
XGetICValues(m_xIC, XNFilterEvents, &im_event_mask, nullptr);
|
|
||||||
XSelectInput(display, m_windowId, swa.event_mask | im_event_mask);
|
|
||||||
XSetICFocus(m_xIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The XInput 2.1 extension enables per-pixel smooth scrolling trackpads */
|
|
||||||
XIEventMask mask = {XIAllMasterDevices, XIMaskLen(XI_LASTEVENT)};
|
|
||||||
mask.mask = (unsigned char*)malloc(mask.mask_len);
|
|
||||||
memset(mask.mask, 0, mask.mask_len);
|
|
||||||
/* XISetMask(mask.mask, XI_Motion); Can't do this without losing mouse move events :( */
|
|
||||||
XISetMask(mask.mask, XI_TouchBegin);
|
|
||||||
XISetMask(mask.mask, XI_TouchUpdate);
|
|
||||||
XISetMask(mask.mask, XI_TouchEnd);
|
|
||||||
XISelectEvents(m_xDisp, m_windowId, &mask, 1);
|
|
||||||
free(mask.mask);
|
|
||||||
|
|
||||||
|
|
||||||
/* Register netwm extension atom for window closing */
|
|
||||||
XSetWMProtocols(m_xDisp, m_windowId, &S_ATOMS->m_wmDeleteWindow, 1);
|
|
||||||
|
|
||||||
/* Set the title of the window */
|
|
||||||
const unsigned char* c_title = (unsigned char*)title.c_str();
|
|
||||||
XChangeProperty(m_xDisp, m_windowId, XA_WM_NAME, XA_STRING, 8, PropModeReplace, c_title, title.length());
|
|
||||||
|
|
||||||
/* Set the title of the window icon */
|
|
||||||
XChangeProperty(m_xDisp, m_windowId, XA_WM_ICON_NAME, XA_STRING, 8, PropModeReplace, c_title, title.length());
|
|
||||||
|
|
||||||
/* Add window icon */
|
|
||||||
if (MAINICON_NETWM_SZ && S_ATOMS->m_netwmIcon)
|
|
||||||
{
|
|
||||||
XChangeProperty(display, m_windowId, S_ATOMS->m_netwmIcon, XA_CARDINAL,
|
|
||||||
32, PropModeReplace, MAINICON_NETWM, MAINICON_NETWM_SZ / sizeof(unsigned long));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize context */
|
|
||||||
XMapWindow(m_xDisp, m_windowId);
|
|
||||||
setStyle(EWindowStyle::Default);
|
|
||||||
setCursor(EMouseCursor::Pointer);
|
|
||||||
XFlush(m_xDisp);
|
|
||||||
|
|
||||||
m_gfxCtx->initializeContext(vulkanHandle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~WindowXlib()
|
~WindowXlib()
|
||||||
|
|
Loading…
Reference in New Issue