From 0aba86751073dafcda29b4f3be90b6e415935284 Mon Sep 17 00:00:00 2001 From: Branimir Karadzic Date: Thu, 2 Oct 2014 19:52:43 -0700 Subject: [PATCH] x11: Create/destroy window code. --- examples/common/entry/entry_x11.cpp | 191 ++++++++++++++++++++++++---- 1 file changed, 163 insertions(+), 28 deletions(-) diff --git a/examples/common/entry/entry_x11.cpp b/examples/common/entry/entry_x11.cpp index fe0e9e8b..f8371cd0 100644 --- a/examples/common/entry/entry_x11.cpp +++ b/examples/common/entry/entry_x11.cpp @@ -15,7 +15,9 @@ #undef None #include #include +#include #include // memset +#include namespace entry { @@ -42,6 +44,25 @@ namespace entry static int32_t threadFunc(void* _userData); }; + struct Msg + { + Msg() + : m_x(0) + , m_y(0) + , m_width(0) + , m_height(0) + , m_flags(0) + { + } + + int32_t m_x; + int32_t m_y; + uint32_t m_width; + uint32_t m_height; + uint32_t m_flags; + std::string m_title; + }; + struct Context { Context() @@ -131,9 +152,9 @@ namespace entry m_display = XOpenDisplay(0); int32_t screen = DefaultScreen(m_display); - int32_t depth = DefaultDepth(m_display, screen); - Visual* visual = DefaultVisual(m_display, screen); - Window root = RootWindow(m_display, screen); + m_depth = DefaultDepth(m_display, screen); + m_visual = DefaultVisual(m_display, screen); + m_root = RootWindow(m_display, screen); XSetWindowAttributes windowAttrs; memset(&windowAttrs, 0, sizeof(windowAttrs) ); @@ -150,12 +171,14 @@ namespace entry | StructureNotifyMask ; - m_window = XCreateWindow(m_display - , root + m_windowAlloc.alloc(); + m_window[0] = XCreateWindow(m_display + , m_root , 0, 0 - , ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT, 0, depth + , ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT, 0 + , m_depth , InputOutput - , visual + , m_visual , CWBorderPixel|CWEventMask , &windowAttrs ); @@ -163,18 +186,18 @@ namespace entry // Clear window to black. XSetWindowAttributes attr; memset(&attr, 0, sizeof(attr) ); - XChangeWindowAttributes(m_display, m_window, CWBackPixel, &attr); + XChangeWindowAttributes(m_display, m_window[0], CWBackPixel, &attr); const char* wmDeleteWindowName = "WM_DELETE_WINDOW"; Atom wmDeleteWindow; XInternAtoms(m_display, (char **)&wmDeleteWindowName, 1, False, &wmDeleteWindow); - XSetWMProtocols(m_display, m_window, &wmDeleteWindow, 1); + XSetWMProtocols(m_display, m_window[0], &wmDeleteWindow, 1); - XMapWindow(m_display, m_window); - XStoreName(m_display, m_window, "BGFX"); + XMapWindow(m_display, m_window[0]); + XStoreName(m_display, m_window[0], "BGFX"); // - bgfx::x11SetDisplayWindow(m_display, m_window); + bgfx::x11SetDisplayWindow(m_display, m_window[0]); MainThreadEntry mte; mte.m_argc = _argc; @@ -223,7 +246,8 @@ namespace entry if (MouseButton::None != mb) { - m_eventQueue.postMouseEvent(defaultWindow + WindowHandle handle = findHandle(xbutton.window); + m_eventQueue.postMouseEvent(handle , xbutton.x , xbutton.y , 0 @@ -237,7 +261,8 @@ namespace entry case MotionNotify: { const XMotionEvent& xmotion = event.xmotion; - m_eventQueue.postMouseEvent(defaultWindow + WindowHandle handle = findHandle(xmotion.window); + m_eventQueue.postMouseEvent(handle , xmotion.x , xmotion.y , 0 @@ -266,7 +291,8 @@ namespace entry Key::Enum key = fromXk(keysym); if (Key::None != key) { - m_eventQueue.postKeyEvent(defaultWindow, key, m_modifiers, KeyPress == event.type); + WindowHandle handle = findHandle(xkey.window); + m_eventQueue.postKeyEvent(handle, key, m_modifiers, KeyPress == event.type); } } break; @@ -277,8 +303,12 @@ namespace entry case ResizeRequest: { const XResizeRequestEvent& xresize = event.xresizerequest; - XResizeWindow(m_display, m_window, xresize.width, xresize.height); - m_eventQueue.postSizeEvent(defaultWindow, xresize.width, xresize.height); + XResizeWindow(xresize.display, xresize.window, xresize.width, xresize.height); + WindowHandle handle = findHandle(xresize.window); + if (isValid(handle) ) + { + m_eventQueue.postSizeEvent(handle, xresize.width, xresize.height); + } } break; } @@ -287,8 +317,8 @@ namespace entry thread.shutdown(); - XUnmapWindow(m_display, m_window); - XDestroyWindow(m_display, m_window); + XUnmapWindow(m_display, m_window[0]); + XDestroyWindow(m_display, m_window[0]); return EXIT_SUCCESS; } @@ -299,12 +329,97 @@ namespace entry m_modifiers |= _set ? _modifier : 0; } + void createWindow(WindowHandle _handle, Msg* msg) + { + XSetWindowAttributes windowAttrs; + memset(&windowAttrs, 0, sizeof(windowAttrs) ); + windowAttrs.background_pixmap = 0; + windowAttrs.border_pixel = 0; + windowAttrs.event_mask = 0 + | ButtonPressMask + | ButtonReleaseMask + | ExposureMask + | KeyPressMask + | KeyReleaseMask + | PointerMotionMask + | ResizeRedirectMask + | StructureNotifyMask + ; + + Window window = XCreateWindow(m_display + , m_root + , msg->m_x + , msg->m_y + , msg->m_width + , msg->m_height + , 0 + , m_depth + , InputOutput + , m_visual + , CWBorderPixel|CWEventMask + , &windowAttrs + ); + m_window[_handle.idx] = window; + + // Clear window to black. + XSetWindowAttributes attr; + memset(&attr, 0, sizeof(attr) ); + XChangeWindowAttributes(m_display, window, CWBackPixel, &attr); + + const char* wmDeleteWindowName = "WM_DELETE_WINDOW"; + Atom wmDeleteWindow; + XInternAtoms(m_display, (char **)&wmDeleteWindowName, 1, False, &wmDeleteWindow); + XSetWMProtocols(m_display, window, &wmDeleteWindow, 1); + + XMapWindow(m_display, window); + XStoreName(m_display, window, msg->m_title.c_str() ); + + m_eventQueue.postSizeEvent(_handle, msg->m_width, msg->m_height); + + union cast + { + void* p; + ::Window w; + }; + + cast c; + c.w = window; + m_eventQueue.postWindowEvent(_handle, c.p); + + delete msg; + } + + WindowHandle findHandle(Window _window) + { + bx::LwMutexScope scope(m_lock); + for (uint32_t ii = 0, num = m_windowAlloc.getNumHandles(); ii < num; ++ii) + { + uint16_t idx = m_windowAlloc.getHandleAt(ii); + if (_window == m_window[idx]) + { + WindowHandle handle = { idx }; + return handle; + } + } + + WindowHandle invalid = { UINT16_MAX }; + return invalid; + } + uint8_t m_modifiers; - Display* m_display; - Window m_window; bool m_exit; EventQueue m_eventQueue; + bx::LwMutex m_lock; + bx::HandleAllocT m_windowAlloc; + + int32_t m_depth; + Visual* m_visual; + Window m_root; + + Display* m_display; + Window m_window[ENTRY_CONFIG_MAX_WINDOWS]; + uint32_t m_flags[ENTRY_CONFIG_MAX_WINDOWS]; }; static Context s_ctx; @@ -334,14 +449,35 @@ namespace entry WindowHandle createWindow(int32_t _x, int32_t _y, uint32_t _width, uint32_t _height, uint32_t _flags, const char* _title) { - BX_UNUSED(_x, _y, _width, _height, _flags, _title); - WindowHandle handle = { UINT16_MAX }; + bx::LwMutexScope scope(s_ctx.m_lock); + WindowHandle handle = { s_ctx.m_windowAlloc.alloc() }; + + if (isValid(handle) ) + { + Msg* msg = new Msg; + msg->m_x = _x; + msg->m_y = _y; + msg->m_width = _width; + msg->m_height = _height; + msg->m_title = _title; + msg->m_flags = _flags; + s_ctx.createWindow(handle, msg); + } + return handle; } void destroyWindow(WindowHandle _handle) { - BX_UNUSED(_handle); + if (isValid(handle) ) + { + s_ctx.m_eventQueue.postWindowEvent(_handle, NULL); + XUnmapWindow(s_ctx.m_display, s_ctx.m_window[_handle.idx]); + XDestroyWindow(s_ctx.m_display, s_ctx.m_window[_handle.idx]); + + bx::LwMutexScope scope(s_ctx.m_lock); + s_ctx.m_windowAlloc.free(_handle.idx); + } } void setWindowPos(WindowHandle _handle, int32_t _x, int32_t _y) @@ -357,16 +493,15 @@ namespace entry ev.serial = 0; ev.send_event = true; ev.display = s_ctx.m_display; - ev.window = s_ctx.m_window; + ev.window = s_ctx.m_window[0]; ev.width = (int)_width; ev.height = (int)_height; - XSendEvent(s_ctx.m_display, s_ctx.m_window, false, ResizeRedirectMask, (XEvent*)&ev); + XSendEvent(s_ctx.m_display, s_ctx.m_window[0], false, ResizeRedirectMask, (XEvent*)&ev); } void setWindowTitle(WindowHandle _handle, const char* _title) { - BX_UNUSED(_handle); - XStoreName(s_ctx.m_display, s_ctx.m_window, _title); + XStoreName(s_ctx.m_display, s_ctx.m_window[_handle.idx], _title); } void toggleWindowFrame(WindowHandle _handle)