diff options
| author | Egor <egor.yusov@gmail.com> | 2019-10-02 05:58:37 +0000 |
|---|---|---|
| committer | Egor <egor.yusov@gmail.com> | 2019-10-02 05:58:37 +0000 |
| commit | 130b83cd1fa7795613afc5a783a6c43692d5b729 (patch) | |
| tree | 0940512075db69a92397a1ad808837a78683c804 /Imgui/src/ImGuiImplLinuxX11.cpp | |
| parent | ImGui linux XCB: added mouse wheel handling (diff) | |
| download | DiligentTools-130b83cd1fa7795613afc5a783a6c43692d5b729.tar.gz DiligentTools-130b83cd1fa7795613afc5a783a6c43692d5b729.zip | |
Imgui linux: implemented x11 input
Diffstat (limited to 'Imgui/src/ImGuiImplLinuxX11.cpp')
| -rw-r--r-- | Imgui/src/ImGuiImplLinuxX11.cpp | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/Imgui/src/ImGuiImplLinuxX11.cpp b/Imgui/src/ImGuiImplLinuxX11.cpp new file mode 100644 index 0000000..2497978 --- /dev/null +++ b/Imgui/src/ImGuiImplLinuxX11.cpp @@ -0,0 +1,192 @@ +/* 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 <X11/Xlib.h> +#include <X11/keysym.h> +#include <X11/Xutil.h> + +#ifdef Bool +# undef Bool +#endif + +#ifdef True +# undef True +#endif + +#ifdef False +# undef False +#endif + + +#include "imgui.h" + +#include "ImGuiImplLinuxX11.h" + +namespace Diligent +{ + +ImGuiImplLinuxX11::ImGuiImplLinuxX11(IRenderDevice* pDevice, + TEXTURE_FORMAT BackBufferFmt, + TEXTURE_FORMAT DepthBufferFmt, + Uint32 DisplayWidth, + Uint32 DisplayHeight, + Uint32 InitialVertexBufferSize, + Uint32 InitialIndexBufferSize) : + ImGuiImplDiligent(pDevice, BackBufferFmt, DepthBufferFmt, InitialVertexBufferSize, InitialIndexBufferSize) +{ + + auto& io = ImGui::GetIO(); + io.DisplaySize = ImVec2(DisplayWidth, DisplayHeight); + + io.BackendPlatformName = "Diligent-ImGuiImplLinuxX11"; + + // 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] = 256; + io.KeyMap[ImGuiKey_LeftArrow] = 257; + io.KeyMap[ImGuiKey_RightArrow] = 258; + io.KeyMap[ImGuiKey_UpArrow] = 259; + io.KeyMap[ImGuiKey_DownArrow] = 260; + io.KeyMap[ImGuiKey_PageUp] = 261; + io.KeyMap[ImGuiKey_PageDown] = 262; + io.KeyMap[ImGuiKey_Home] = 263; + io.KeyMap[ImGuiKey_End] = 264; + io.KeyMap[ImGuiKey_Insert] = 265; + io.KeyMap[ImGuiKey_Delete] = 266; + io.KeyMap[ImGuiKey_Backspace] = 267; + io.KeyMap[ImGuiKey_Space] = 268; + io.KeyMap[ImGuiKey_Enter] = 269; + //io.KeyMap[ImGuiKey_Escape] = 270; + io.KeyMap[ImGuiKey_KeyPadEnter] = 271; + 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'; + + m_LastTimestamp = std::chrono::high_resolution_clock::now(); +} + +ImGuiImplLinuxX11::~ImGuiImplLinuxX11() +{ +} + +void ImGuiImplLinuxX11::NewFrame() +{ + auto now = std::chrono::high_resolution_clock::now(); + auto elapsed_ns = now - m_LastTimestamp; + m_LastTimestamp = now; + auto& io = ImGui::GetIO(); + io.DeltaTime = static_cast<float>(elapsed_ns.count() / 1e+9); + + ImGuiImplDiligent::NewFrame(); +} + + +bool ImGuiImplLinuxX11::HandleXEvent(XEvent* event) +{ + auto& io = ImGui::GetIO(); + switch (event->type) + { + case ButtonPress: + case ButtonRelease: + { + bool IsPressed = event->type == ButtonPress; + auto* xbe = reinterpret_cast<XButtonEvent *>(event); + switch(xbe->button) + { + case Button1: io.MouseDown[0] = IsPressed; break; // Left + case Button2: io.MouseDown[2] = IsPressed; break; // Middle + case Button3: io.MouseDown[1] = IsPressed; break; // Right + case Button4: io.MouseWheel += 1; break; + case Button5: io.MouseWheel -= 1; break; + } + return io.WantCaptureMouse; + } + + case MotionNotify: + { + XMotionEvent* xme = (XMotionEvent *)event; + io.MousePos = ImVec2(xme->x, xme->y); + return io.WantCaptureMouse; + } + + case ConfigureNotify: + { + XConfigureEvent *xce = (XConfigureEvent *)event; + io.DisplaySize = ImVec2(xce->width, xce->height); + return false; + } + + case KeyPress: + case KeyRelease: + { + bool IsPressed = event->type == KeyPress; + io.KeyCtrl = (event->xkey.state & ControlMask) != 0; + io.KeyShift = (event->xkey.state & ShiftMask) != 0; + io.KeyAlt = (event->xkey.state & Mod1Mask) != 0; + + KeySym keysym = 0; + constexpr int buff_sz = 80; + char buffer[buff_sz]; + int num_char = XLookupString((XKeyEvent *)event, buffer, buff_sz, &keysym, 0); + int k = 0; + switch(keysym) + { + case XK_Tab: k = io.KeyMap[ImGuiKey_Tab]; break; + case XK_Left: k = io.KeyMap[ImGuiKey_LeftArrow]; break; + case XK_Right: k = io.KeyMap[ImGuiKey_RightArrow]; break; + case XK_Up: k = io.KeyMap[ImGuiKey_UpArrow]; break; + case XK_Down: k = io.KeyMap[ImGuiKey_DownArrow]; break; + case XK_Page_Up: k = io.KeyMap[ImGuiKey_PageUp]; break; + case XK_Page_Down: k = io.KeyMap[ImGuiKey_PageDown]; break; + case XK_Home: k = io.KeyMap[ImGuiKey_Home]; break; + case XK_End: k = io.KeyMap[ImGuiKey_End]; break; + case XK_Insert: k = io.KeyMap[ImGuiKey_Insert]; break; + case XK_Delete: k = io.KeyMap[ImGuiKey_Delete]; break; + case XK_BackSpace: k = io.KeyMap[ImGuiKey_Backspace]; break; + //case XK_space: k = io.KeyMap[ImGuiKey_Space]; break; + case XK_Return: k = io.KeyMap[ImGuiKey_Enter]; break; + case XK_Escape: k = io.KeyMap[ImGuiKey_Escape]; break; + case XK_KP_Enter: k = io.KeyMap[ImGuiKey_KeyPadEnter];break; + } + + if (k!=0) + io.KeysDown[k] = IsPressed; + + if (k == 0 && IsPressed) + { + for (int i=0; i < num_char; ++i) + io.AddInputCharacter(buffer[i]); + } + + return io.WantCaptureKeyboard; + } + + default: + break; + } + return false; +} + +} |
