diff options
| author | Egor <egor.yusov@gmail.com> | 2019-10-02 04:18:47 +0000 |
|---|---|---|
| committer | Egor <egor.yusov@gmail.com> | 2019-10-02 04:18:47 +0000 |
| commit | 9b5811dffcebc61121ef6d3d9746817aabdabc4e (patch) | |
| tree | 2b6bd7b5de1785f8709734638fcf05f1b4484851 /Imgui/src/ImGuiImplLinuxXCB.cpp | |
| parent | Added ImGui Linux implementation stub (diff) | |
| download | DiligentTools-9b5811dffcebc61121ef6d3d9746817aabdabc4e.tar.gz DiligentTools-9b5811dffcebc61121ef6d3d9746817aabdabc4e.zip | |
Imgui Linux impl: implemented xcb event handling
Diffstat (limited to 'Imgui/src/ImGuiImplLinuxXCB.cpp')
| -rw-r--r-- | Imgui/src/ImGuiImplLinuxXCB.cpp | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/Imgui/src/ImGuiImplLinuxXCB.cpp b/Imgui/src/ImGuiImplLinuxXCB.cpp new file mode 100644 index 0000000..8d3a0dc --- /dev/null +++ b/Imgui/src/ImGuiImplLinuxXCB.cpp @@ -0,0 +1,298 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "imgui.h" + +#include <xcb/xcb.h> +#include <X11/keysym.h> +#include "xcb_keysyms/xcb_keysyms.h" + +#ifdef Bool +# undef Bool +#endif + +#ifdef True +# undef True +#endif + +#ifdef False +# undef False +#endif + +#include "ImGuiImplLinuxXCB.h" + +namespace Diligent +{ + +ImGuiImplLinuxXCB::ImGuiImplLinuxXCB(xcb_connection_t* connection, + IRenderDevice* pDevice, + TEXTURE_FORMAT BackBufferFmt, + TEXTURE_FORMAT DepthBufferFmt, + Uint32 DisplayWidth, + Uint32 DisplayHeight, + Uint32 InitialVertexBufferSize, + Uint32 InitialIndexBufferSize) : + ImGuiImplDiligent(pDevice, BackBufferFmt, DepthBufferFmt, InitialVertexBufferSize, InitialIndexBufferSize) +{ + m_syms = xcb_key_symbols_alloc((xcb_connection_t*)connection); + + auto& io = ImGui::GetIO(); + io.DisplaySize = ImVec2(DisplayWidth, DisplayHeight); + + io.BackendPlatformName = "Diligent-ImGuiImplLinuxXCB"; + + // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime. + io.KeyMap[ImGuiKey_Tab] = 0x17; + io.KeyMap[ImGuiKey_LeftArrow] = 0x71; + io.KeyMap[ImGuiKey_RightArrow] = 0x72; + io.KeyMap[ImGuiKey_UpArrow] = 0x6F; + io.KeyMap[ImGuiKey_DownArrow] = 0x74; + io.KeyMap[ImGuiKey_PageUp] = 0x70; + io.KeyMap[ImGuiKey_PageDown] = 0x75; + io.KeyMap[ImGuiKey_Home] = 0x6E; + io.KeyMap[ImGuiKey_End] = 0x73; + io.KeyMap[ImGuiKey_Insert] = 0x76; + io.KeyMap[ImGuiKey_Delete] = 0x77; + io.KeyMap[ImGuiKey_Backspace] = 0x16; + //io.KeyMap[ImGuiKey_Space] = 0;//VK_SPACE; + io.KeyMap[ImGuiKey_Enter] = 0x24; + io.KeyMap[ImGuiKey_Escape] = 0x09; + io.KeyMap[ImGuiKey_KeyPadEnter] = 0x68; + io.KeyMap[ImGuiKey_A] = 'A'; + io.KeyMap[ImGuiKey_C] = 'C'; + io.KeyMap[ImGuiKey_V] = 'V'; + io.KeyMap[ImGuiKey_X] = 'X'; + io.KeyMap[ImGuiKey_Y] = 'Y'; + io.KeyMap[ImGuiKey_Z] = 'Z'; +} + +ImGuiImplLinuxXCB::~ImGuiImplLinuxXCB() +{ + if (m_syms) + { + xcb_key_symbols_free(m_syms); + } +} + +void ImGuiImplLinuxXCB::NewFrame() +{ + //ImGui_ImplWin32_NewFrame(); + ImGuiImplDiligent::NewFrame(); +} + +// ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- +void ImGuiImplLinuxXCB::HandleKeyEvent(xcb_key_release_event_t* event) +{ + bool IsKeyPressed = (event->response_type & 0x7f) == XCB_KEY_PRESS; + + auto& io = ImGui::GetIO(); + + io.KeyCtrl = event->state & XCB_KEY_BUT_MASK_CONTROL; + io.KeyShift = event->state & XCB_KEY_BUT_MASK_SHIFT; + io.KeyAlt = event->state & XCB_KEY_BUT_MASK_MOD_1; + + int k = 0; + switch (event->detail) + { + case 0x09: k = io.KeyMap[ImGuiKey_Escape]; break; + case 0x6F: k = io.KeyMap[ImGuiKey_UpArrow]; break; + case 0x74: k = io.KeyMap[ImGuiKey_DownArrow]; break; + case 0x72: k = io.KeyMap[ImGuiKey_RightArrow]; break; + case 0x71: k = io.KeyMap[ImGuiKey_LeftArrow]; break; + case 0x24: k = io.KeyMap[ImGuiKey_Enter]; break; + case 0x76: k = io.KeyMap[ImGuiKey_Insert]; break; + case 0x77: k = io.KeyMap[ImGuiKey_Delete]; break; + case 0x16: k = io.KeyMap[ImGuiKey_Backspace]; break; + case 0x6E: k = io.KeyMap[ImGuiKey_Home]; break; + case 0x17: k = io.KeyMap[ImGuiKey_Tab]; break; + case 0x73: k = io.KeyMap[ImGuiKey_End]; break; + case 0x68: k = io.KeyMap[ImGuiKey_KeyPadEnter];break; + case 0x70: k = io.KeyMap[ImGuiKey_PageUp]; break; + case 0x75: k = io.KeyMap[ImGuiKey_PageDown]; break; + } + + if(k == 0 && IsKeyPressed) + { + xcb_keysym_t keysym = xcb_key_press_lookup_keysym(m_syms, event, 0); + switch (keysym) + { +#if 0 + case XK_Control_L: + case XK_Control_R: /*s_KMod |= TW_KMOD_CTRL;*/ break; + + case XK_Shift_L: + case XK_Shift_R: /*s_KMod |= TW_KMOD_SHIFT;*/ break; + + case XK_Alt_L: + case XK_Alt_R: /*s_KMod |= TW_KMOD_ALT;*/ break; + +#ifdef XK_Enter + case XK_Enter: k = TW_KEY_RETURN; break; +#endif + +#ifdef XK_KP_Home + case XK_KP_Home: k = io.KeyMap[ImGuiKey_Home]; break; + case XK_KP_End: k = io.KeyMap[ImGuiKey_End]; break; + case XK_KP_Delete: k = io.KeyMap[ImGuiKey_Delete]; break; +#endif + +#ifdef XK_KP_Up + case XK_KP_Up: k = io.KeyMap[ImGuiKey_UpArrow]; break; + case XK_KP_Down: k = io.KeyMap[ImGuiKey_DownArrow]; break; + case XK_KP_Right: k = io.KeyMap[ImGuiKey_RightArrow]; break; + case XK_KP_Left: k = io.KeyMap[ImGuiKey_LeftArrow]; break; +#endif + +#ifdef XK_KP_Page_Up + case XK_KP_Page_Up: k = io.KeyMap[ImGuiKey_PageUp]; break; + case XK_KP_Page_Down: k = io.KeyMap[ImGuiKey_PageDown]; break; +#endif + +#ifdef XK_KP_Tab + case XK_KP_Tab: k = io.KeyMap[ImGuiKey_Tab]; break; +#endif +#endif + default: + if (keysym > 12 && keysym < 127) + { + if (io.KeyShift) + { + if (keysym >= 'a' && keysym <= 'z') + keysym += (int)'A' - (int)'a'; + else + { + switch(keysym) + { + case '`': keysym = '~'; break; + case '1': keysym = '!'; break; + case '2': keysym = '@'; break; + case '3': keysym = '#'; break; + case '4': keysym = '$'; break; + case '5': keysym = '%'; break; + case '6': keysym = '^'; break; + case '7': keysym = '&'; break; + case '8': keysym = '*'; break; + case '9': keysym = '('; break; + case '0': keysym = ')'; break; + case '-': keysym = '_'; break; + case '=': keysym = '+'; break; + case '[': keysym = '{'; break; + case ']': keysym = '}'; break; + case '\\': keysym = '|'; break; + case ';': keysym = ':'; break; + case '\'': keysym = '\"'; break; + case ',': keysym = '<'; break; + case '.': keysym = '>'; break; + case '/': keysym = '?'; break; + } + } + } + + io.AddInputCharacter(keysym); + } + } + } + + if (k != 0) + { + io.KeysDown[k] = IsKeyPressed; + } +} + +bool ImGuiImplLinuxXCB::HandleXCBEvent(xcb_generic_event_t* event) +{ + auto& io = ImGui::GetIO(); + switch (event->response_type & 0x7f) + { + case XCB_MOTION_NOTIFY: + { + xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)event; + io.MousePos = ImVec2(motion->event_x, motion->event_y); + return io.WantCaptureMouse; + } + break; + + case XCB_BUTTON_PRESS: + { + xcb_button_press_event_t *press = (xcb_button_press_event_t *)event; + int button = -1; + if (press->detail == XCB_BUTTON_INDEX_1) + button = 0; // Left + if (press->detail == XCB_BUTTON_INDEX_2) + button = 2; // middle + if (press->detail == XCB_BUTTON_INDEX_3) + button = 1; // right + if (button >= 0) + { + io.MouseDown[button] = true; + return io.WantCaptureMouse; + } + return false; + } + break; + + case XCB_BUTTON_RELEASE: + { + xcb_button_release_event_t *press = (xcb_button_release_event_t *)event; + int button = -1; + if (press->detail == XCB_BUTTON_INDEX_1) + button = 0; // Left + if (press->detail == XCB_BUTTON_INDEX_2) + button = 2; // middle + if (press->detail == XCB_BUTTON_INDEX_3) + button = 1; // right + if (button >= 0) + { + io.MouseDown[button] = false; + return io.WantCaptureKeyboard; + } + return false; + } + break; + + case XCB_KEY_RELEASE: + case XCB_KEY_PRESS: + { + xcb_key_press_event_t* keyEvent = (xcb_key_press_event_t *)event; + HandleKeyEvent(keyEvent); + return io.WantCaptureKeyboard; + } + break; + + case XCB_CONFIGURE_NOTIFY: + { + const xcb_configure_notify_event_t *cfgEvent = (const xcb_configure_notify_event_t *)event; + io.DisplaySize = ImVec2(cfgEvent->width, cfgEvent->height); + return false; + } + break; + + default: + break; + } + + return false; +} + +} |
