Initial commit.
This commit is contained in:
commit
59c6161fdb
134 changed files with 4751 additions and 0 deletions
13
src/windows/AbstractDesktopApp.h
Normal file
13
src/windows/AbstractDesktopApp.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
class AbstractDesktopApp
|
||||
{
|
||||
public:
|
||||
|
||||
AbstractDesktopApp() = default;
|
||||
virtual ~AbstractDesktopApp() = default;
|
||||
};
|
||||
|
||||
using AbstractDesktopAppPtr = std::shared_ptr<AbstractDesktopApp>;
|
22
src/windows/CMakeLists.txt
Normal file
22
src/windows/CMakeLists.txt
Normal file
|
@ -0,0 +1,22 @@
|
|||
list(APPEND windows_LIB_INCLUDES
|
||||
managers/WindowManager.cpp
|
||||
managers/DesktopManager.cpp
|
||||
ui_interfaces/x11/XcbInterface.cpp
|
||||
ui_interfaces/x11/XcbLayerInterface.cpp
|
||||
ui_interfaces/x11/XcbTextInterface.cpp
|
||||
ui_interfaces/x11/XcbKeyboard.cpp
|
||||
ui_interfaces/x11/GlxInterface.cpp)
|
||||
|
||||
# add the library
|
||||
add_library(windows SHARED ${windows_LIB_INCLUDES})
|
||||
|
||||
target_include_directories(windows PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/managers"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/ui_interfaces/x11"
|
||||
"${PROJECT_SOURCE_DIR}/src/geometry"
|
||||
"${PROJECT_SOURCE_DIR}/src/graphics"
|
||||
"${PROJECT_SOURCE_DIR}/src/ui_elements"
|
||||
"${PROJECT_SOURCE_DIR}/src/ui_elements/widgets"
|
||||
)
|
||||
target_link_libraries(windows PUBLIC X11 X11-xcb xcb core graphics geometry ui_elements)
|
112
src/windows/managers/DesktopManager.cpp
Normal file
112
src/windows/managers/DesktopManager.cpp
Normal file
|
@ -0,0 +1,112 @@
|
|||
#include "DesktopManager.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
DesktopManager::DesktopManager()
|
||||
: mScreens(),
|
||||
mWindowManager(),
|
||||
mKeyboard(),
|
||||
mMainApplication(),
|
||||
mModified(false)
|
||||
{
|
||||
mWindowManager = WindowManager::Create();
|
||||
mKeyboard = Keyboard::Create();
|
||||
}
|
||||
|
||||
DesktopManager::~DesktopManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<DesktopManager> DesktopManager::Create()
|
||||
{
|
||||
return std::make_shared<DesktopManager>();
|
||||
}
|
||||
|
||||
void DesktopManager::OnKeyboardEvent(KeyboardEventPtr keyboardEvent)
|
||||
{
|
||||
std::cout << "Key: " << keyboardEvent->GetKeyString() << std::endl;
|
||||
}
|
||||
|
||||
void DesktopManager::OnPaintEvent(PaintEventPtr paintEvent)
|
||||
{
|
||||
GetWindowManager()->OnPaintEvent(paintEvent);
|
||||
}
|
||||
|
||||
void DesktopManager::OnMouseEvent(MouseEventPtr mouseEvent)
|
||||
{
|
||||
GetWindowManager()->OnMouseEvent(mouseEvent);
|
||||
}
|
||||
|
||||
bool DesktopManager::IsModified()
|
||||
{
|
||||
return mModified;
|
||||
}
|
||||
|
||||
void DesktopManager::OnUiEvent(UiEventPtr event)
|
||||
{
|
||||
mModified = false;
|
||||
switch (event->GetType())
|
||||
{
|
||||
case (UiEvent::Type::Paint):
|
||||
{
|
||||
OnPaintEvent(std::dynamic_pointer_cast<PaintEvent>(event));
|
||||
break;
|
||||
}
|
||||
case (UiEvent::Type::Keyboard):
|
||||
{
|
||||
OnKeyboardEvent(std::dynamic_pointer_cast<KeyboardEvent>(event));
|
||||
//mModified = true;
|
||||
break;
|
||||
}
|
||||
case (UiEvent::Type::Mouse):
|
||||
{
|
||||
auto mouseEvent = std::dynamic_pointer_cast<MouseEvent>(event);
|
||||
|
||||
OnMouseEvent(mouseEvent);
|
||||
if(mouseEvent->GetAction() == MouseEvent::Action::Pressed)
|
||||
{
|
||||
std::cout << "mouse pressed" << std::endl;
|
||||
mModified = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DesktopManager::SetIsModified(bool modified)
|
||||
{
|
||||
mModified = modified;
|
||||
}
|
||||
|
||||
KeyboardPtr DesktopManager::GetKeyboard()
|
||||
{
|
||||
return mKeyboard;
|
||||
}
|
||||
|
||||
void DesktopManager::SetKeyboard(KeyboardPtr keyboard)
|
||||
{
|
||||
mKeyboard = keyboard;
|
||||
}
|
||||
|
||||
void DesktopManager::SetMainApp(AbstractDesktopAppPtr mainApp)
|
||||
{
|
||||
mMainApplication = mainApp;
|
||||
}
|
||||
|
||||
AbstractDesktopAppPtr DesktopManager::GetMainApp()
|
||||
{
|
||||
return mMainApplication;
|
||||
}
|
||||
|
||||
void DesktopManager::SetWindowManager(WindowManagerPtr windowManager)
|
||||
{
|
||||
mWindowManager = windowManager;
|
||||
}
|
||||
|
||||
WindowManagerPtr DesktopManager::GetWindowManager()
|
||||
{
|
||||
return mWindowManager;
|
||||
}
|
58
src/windows/managers/DesktopManager.h
Normal file
58
src/windows/managers/DesktopManager.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "Keyboard.h"
|
||||
#include "Screen.h"
|
||||
#include "KeyboardEvent.h"
|
||||
#include "PaintEvent.h"
|
||||
#include "MouseEvent.h"
|
||||
#include "WindowManager.h"
|
||||
#include "UiEvent.h"
|
||||
#include "AbstractDesktopApp.h"
|
||||
|
||||
class DesktopManager
|
||||
{
|
||||
std::vector<ScreenPtr> mScreens;
|
||||
WindowManagerPtr mWindowManager;
|
||||
KeyboardPtr mKeyboard;
|
||||
AbstractDesktopAppPtr mMainApplication;
|
||||
bool mModified;
|
||||
|
||||
public:
|
||||
|
||||
DesktopManager();
|
||||
|
||||
~DesktopManager();
|
||||
|
||||
static std::shared_ptr<DesktopManager> Create();
|
||||
|
||||
void SetWindowManager(WindowManagerPtr windowManager);
|
||||
|
||||
void SetMainApp(AbstractDesktopAppPtr mainApp);
|
||||
|
||||
AbstractDesktopAppPtr GetMainApp();
|
||||
|
||||
WindowManagerPtr GetWindowManager();
|
||||
|
||||
KeyboardPtr GetKeyboard();
|
||||
|
||||
bool IsModified();
|
||||
|
||||
void SetIsModified(bool modified);
|
||||
|
||||
void SetKeyboard(KeyboardPtr keyboard);
|
||||
|
||||
void OnUiEvent(UiEventPtr event);
|
||||
|
||||
void OnKeyboardEvent(KeyboardEventPtr keyboardEvent);
|
||||
|
||||
void OnMouseEvent(MouseEventPtr mouseEvent);
|
||||
|
||||
void OnPaintEvent(PaintEventPtr paintEvent);
|
||||
|
||||
|
||||
};
|
||||
|
||||
using DesktopManagerPtr = std::shared_ptr<DesktopManager>;
|
37
src/windows/managers/WindowManager.cpp
Normal file
37
src/windows/managers/WindowManager.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include "WindowManager.h"
|
||||
|
||||
WindowManager::WindowManager()
|
||||
: mWindows()
|
||||
{
|
||||
AddWindow(mt::Window::Create());
|
||||
}
|
||||
|
||||
WindowManager::~WindowManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void WindowManager::OnPaintEvent(PaintEventPtr event)
|
||||
{
|
||||
GetMainWindow()->OnPaint(event);
|
||||
}
|
||||
|
||||
void WindowManager::OnMouseEvent(MouseEventPtr event)
|
||||
{
|
||||
GetMainWindow()->OnMouseEvent(event);
|
||||
}
|
||||
|
||||
void WindowManager::AddWindow(WindowPtr window)
|
||||
{
|
||||
mWindows.push_back(window);
|
||||
}
|
||||
|
||||
std::shared_ptr<WindowManager> WindowManager::Create()
|
||||
{
|
||||
return std::make_shared<WindowManager>();
|
||||
}
|
||||
|
||||
WindowPtr WindowManager::GetMainWindow()
|
||||
{
|
||||
return mWindows[0];
|
||||
}
|
36
src/windows/managers/WindowManager.h
Normal file
36
src/windows/managers/WindowManager.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "Window.h"
|
||||
#include "PaintEvent.h"
|
||||
#include "MouseEvent.h"
|
||||
|
||||
|
||||
class WindowManager
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
std::vector<WindowPtr> mWindows;
|
||||
|
||||
public:
|
||||
|
||||
WindowManager();
|
||||
|
||||
~WindowManager();
|
||||
|
||||
void AddWindow(WindowPtr window);
|
||||
|
||||
static std::shared_ptr<WindowManager> Create();
|
||||
|
||||
WindowPtr GetMainWindow();
|
||||
|
||||
void OnPaintEvent(PaintEventPtr event);
|
||||
|
||||
void OnMouseEvent(MouseEventPtr event);
|
||||
|
||||
};
|
||||
|
||||
using WindowManagerPtr = std::shared_ptr<WindowManager>;
|
113
src/windows/ui_interfaces/x11/GlxInterface.cpp
Normal file
113
src/windows/ui_interfaces/x11/GlxInterface.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
#include "GlxInterface.h"
|
||||
#include <GL/gl.h>
|
||||
#include <iostream>
|
||||
#include "OpenGlInterface.h"
|
||||
|
||||
GlxInterface::GlxInterface()
|
||||
: mContext(),
|
||||
mDrawable(),
|
||||
mWindow(),
|
||||
mConfig()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int visual_attribs[] =
|
||||
{
|
||||
GLX_X_RENDERABLE, True,
|
||||
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_ALPHA_SIZE, 8,
|
||||
GLX_DEPTH_SIZE, 24,
|
||||
GLX_STENCIL_SIZE, 8,
|
||||
GLX_DOUBLEBUFFER, True,
|
||||
//GLX_SAMPLE_BUFFERS , 1,
|
||||
//GLX_SAMPLES , 4,
|
||||
None
|
||||
};
|
||||
|
||||
std::shared_ptr<GlxInterface> GlxInterface::Create()
|
||||
{
|
||||
return std::make_shared<GlxInterface>();
|
||||
}
|
||||
|
||||
void GlxInterface::SetupContext(Display* display, int default_screen)
|
||||
{
|
||||
int visualID = 0;
|
||||
|
||||
/* Query framebuffer configurations that match visual_attribs */
|
||||
GLXFBConfig *fb_configs = 0;
|
||||
int num_fb_configs = 0;
|
||||
fb_configs = glXChooseFBConfig(display, default_screen, visual_attribs, &num_fb_configs);
|
||||
if(!fb_configs || num_fb_configs == 0)
|
||||
{
|
||||
std::cerr << "glXGetFBConfigs failed" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Select first framebuffer config and query visualID */
|
||||
mConfig = fb_configs[0];
|
||||
glXGetFBConfigAttrib(display, mConfig, GLX_VISUAL_ID , &visualID);
|
||||
|
||||
GLXContext context;
|
||||
|
||||
/* Create OpenGL context */
|
||||
mContext = glXCreateNewContext(display, mConfig, GLX_RGBA_TYPE, 0, True);
|
||||
if(!mContext)
|
||||
{
|
||||
std::cerr << "glXCreateNewContext failed" << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void GlxInterface::SwapBuffers(Display* display)
|
||||
{
|
||||
glXSwapBuffers(display, mDrawable);
|
||||
}
|
||||
|
||||
void GlxInterface::Draw()
|
||||
{
|
||||
OpenGlInterface::draw();
|
||||
}
|
||||
|
||||
bool GlxInterface::SetupWindow(Display* display, xcb_window_t window)
|
||||
{
|
||||
/* Create GLX Window */
|
||||
//GLXDrawable drawable = 0;
|
||||
|
||||
mWindow = glXCreateWindow(display, mConfig, window, 0);
|
||||
|
||||
if(!mWindow)
|
||||
{
|
||||
//xcb_destroy_window(connection, window);
|
||||
glXDestroyContext(display, mContext);
|
||||
std::cerr << "glXCreateWindow failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
mDrawable = mWindow;
|
||||
|
||||
/* make OpenGL context current */
|
||||
if(!glXMakeContextCurrent(display, mDrawable, mDrawable, mContext))
|
||||
{
|
||||
//
|
||||
glXDestroyContext(display, mContext);
|
||||
std::cerr << "glXMakeContextCurrent failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GlxInterface::DestroyWindow(Display* display)
|
||||
{
|
||||
glXDestroyWindow(display, mWindow);
|
||||
}
|
||||
|
||||
void GlxInterface::DestroyContext(Display* display)
|
||||
{
|
||||
glXDestroyContext(display, mContext);
|
||||
}
|
32
src/windows/ui_interfaces/x11/GlxInterface.h
Normal file
32
src/windows/ui_interfaces/x11/GlxInterface.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
#include <GL/glx.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <memory>
|
||||
|
||||
class GlxInterface
|
||||
{
|
||||
GLXContext mContext;
|
||||
GLXDrawable mDrawable;
|
||||
GLXWindow mWindow;
|
||||
GLXFBConfig mConfig;
|
||||
|
||||
public:
|
||||
|
||||
GlxInterface();
|
||||
|
||||
void SetupContext(Display* display, int default_screen);
|
||||
|
||||
bool SetupWindow(Display* display, xcb_window_t window);
|
||||
|
||||
void DestroyWindow(Display* display);
|
||||
|
||||
void DestroyContext(Display* display);
|
||||
|
||||
void SwapBuffers(Display* display);
|
||||
|
||||
void Draw();
|
||||
|
||||
static std::shared_ptr<GlxInterface> Create();
|
||||
};
|
||||
|
||||
using GlxInterfacePtr = std::shared_ptr<GlxInterface>;
|
348
src/windows/ui_interfaces/x11/XcbInterface.cpp
Normal file
348
src/windows/ui_interfaces/x11/XcbInterface.cpp
Normal file
|
@ -0,0 +1,348 @@
|
|||
#include "XcbInterface.h"
|
||||
#include "DesktopManager.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xlib-xcb.h> /* for XGetXCBConnection, link with libX11-xcb */
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include "KeyboardEvent.h"
|
||||
#include "MouseEvent.h"
|
||||
#include "PaintEvent.h"
|
||||
#include "UiEvent.h"
|
||||
#include "XcbKeyboard.h"
|
||||
#include "XcbLayerInterface.h"
|
||||
#include "GlxInterface.h"
|
||||
|
||||
|
||||
XcbInterface::XcbInterface()
|
||||
: mUseOpenGl(true),
|
||||
mConnection(nullptr),
|
||||
mScreen(nullptr),
|
||||
mWindows(),
|
||||
mHandles(),
|
||||
mDefaultWindow(-1),
|
||||
mGraphicsContext(-1),
|
||||
mX11Display(),
|
||||
mGlxInterface()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
XcbInterface::~XcbInterface()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void XcbInterface::SetUseOpenGl(bool use)
|
||||
{
|
||||
mUseOpenGl = use;
|
||||
}
|
||||
|
||||
void XcbInterface::Initialize()
|
||||
{
|
||||
Connect();
|
||||
UpdateScreen();
|
||||
CreateGraphicsContext();
|
||||
|
||||
if(mUseOpenGl)
|
||||
{
|
||||
InitializeOpenGl();
|
||||
}
|
||||
}
|
||||
|
||||
void XcbInterface::Connect()
|
||||
{
|
||||
if(mUseOpenGl)
|
||||
{
|
||||
/* Open Xlib Display */
|
||||
mX11Display = XOpenDisplay(0);
|
||||
if(!mX11Display)
|
||||
{
|
||||
std::cerr << "Can't open X11 display" << std::endl;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Got display" << std::endl;
|
||||
}
|
||||
|
||||
/* Get the XCB connection from the display */
|
||||
mConnection = XGetXCBConnection(mX11Display);
|
||||
if(!mConnection)
|
||||
{
|
||||
XCloseDisplay(mX11Display);
|
||||
std::cerr << "Can't get xcb connection from display" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "Got connection" << std::endl;
|
||||
|
||||
/* Acquire event queue ownership */
|
||||
XSetEventQueueOwner(mX11Display, XCBOwnsEventQueue);
|
||||
}
|
||||
else
|
||||
{
|
||||
mConnection = xcb_connect(nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void XcbInterface::UpdateScreen()
|
||||
{
|
||||
if(!mConnection) return;
|
||||
|
||||
auto screen_iter = xcb_setup_roots_iterator(xcb_get_setup(mConnection));
|
||||
if(mUseOpenGl)
|
||||
{
|
||||
if(!mX11Display) return;
|
||||
int default_screen = DefaultScreen(mX11Display);
|
||||
for(int screen_num = default_screen;
|
||||
screen_iter.rem && screen_num > 0;
|
||||
--screen_num, xcb_screen_next(&screen_iter));
|
||||
}
|
||||
mScreen = screen_iter.data;
|
||||
}
|
||||
|
||||
void XcbInterface::InitializeOpenGl()
|
||||
{
|
||||
mGlxInterface = GlxInterface::Create();
|
||||
int default_screen = DefaultScreen(mX11Display);
|
||||
mGlxInterface->SetupContext(mX11Display, default_screen);
|
||||
}
|
||||
|
||||
void XcbInterface::CreateOpenGlDrawable(WindowPtr window)
|
||||
{
|
||||
if(!mUseOpenGl)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto hwnd = mHandles[window];
|
||||
bool result = mGlxInterface->SetupWindow(mX11Display, hwnd);
|
||||
if(!result)
|
||||
{
|
||||
xcb_destroy_window(mConnection, hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
void XcbInterface::CreateGraphicsContext()
|
||||
{
|
||||
if(!mConnection || !mScreen) return;
|
||||
mGraphicsContext = xcb_generate_id(mConnection);
|
||||
|
||||
xcb_drawable_t window = mScreen->root;
|
||||
uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
|
||||
uint32_t values[2] = {XcbLayerInterface::GetColor(240, 240, 240), 0};
|
||||
xcb_create_gc(mConnection, mGraphicsContext, window, mask, values);
|
||||
}
|
||||
|
||||
void XcbInterface::MapWindow(WindowPtr window)
|
||||
{
|
||||
if(!mConnection) return;
|
||||
xcb_map_window(mConnection, mHandles[window]);
|
||||
xcb_flush(mConnection);
|
||||
}
|
||||
|
||||
void XcbInterface::ShowWindow(WindowPtr window)
|
||||
{
|
||||
MapWindow(window);
|
||||
}
|
||||
|
||||
uint32_t XcbInterface::GetEventMask()
|
||||
{
|
||||
return XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS |
|
||||
XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION;
|
||||
}
|
||||
|
||||
void XcbInterface::AddWindow(WindowPtr window)
|
||||
{
|
||||
if(!mConnection || !mScreen) return;
|
||||
auto hwnd = xcb_generate_id(mConnection);
|
||||
|
||||
uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
|
||||
uint32_t values[2] = {mScreen->white_pixel, GetEventMask()};
|
||||
|
||||
xcb_create_window (mConnection, /* connection */
|
||||
XCB_COPY_FROM_PARENT, /* depth */
|
||||
hwnd, /* window Id */
|
||||
mScreen->root, /* parent window */
|
||||
0, 0, /* x, y */
|
||||
window->GetWidth(), window->GetHeight(), /* width, height */
|
||||
10, /* border_width */
|
||||
XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
|
||||
mScreen->root_visual, /* visual */
|
||||
mask, values ); /* masks */
|
||||
mWindows[hwnd] = window;
|
||||
mHandles[window] = hwnd;
|
||||
mDefaultWindow = hwnd;
|
||||
}
|
||||
|
||||
void XcbInterface::onPaint(DesktopManagerPtr desktopManager)
|
||||
{
|
||||
auto ui_event = PaintEvent::Create();
|
||||
desktopManager->OnUiEvent(ui_event);
|
||||
|
||||
PaintWindow(desktopManager->GetWindowManager()->GetMainWindow());
|
||||
}
|
||||
|
||||
void XcbInterface::PaintWindow(WindowPtr window)
|
||||
{
|
||||
const auto hwnd = mHandles[window];
|
||||
for(const auto& layer : window->GetLayers())
|
||||
{
|
||||
XcbLayerInterface::AddLayer(mConnection, mScreen,
|
||||
hwnd, mGraphicsContext, layer);
|
||||
}
|
||||
}
|
||||
|
||||
void XcbInterface::OnKeyPress(xcb_key_press_event_t* event, DesktopManagerPtr desktopManager)
|
||||
{
|
||||
auto ui_event = KeyboardEvent::Create();
|
||||
ui_event->SetAction(KeyboardEvent::Action::Pressed);
|
||||
std::string keyVal = desktopManager->GetKeyboard()->GetKeyString(event->detail);
|
||||
ui_event->SetKeyString(keyVal);
|
||||
desktopManager->OnUiEvent(ui_event);
|
||||
}
|
||||
|
||||
void XcbInterface::OnKeyRelease(xcb_key_release_event_t* event, DesktopManagerPtr desktopManager)
|
||||
{
|
||||
auto ui_event = KeyboardEvent::Create();
|
||||
ui_event->SetAction(KeyboardEvent::Action::Released);
|
||||
std::string keyVal = desktopManager->GetKeyboard()->GetKeyString(event->detail);
|
||||
ui_event->SetKeyString(keyVal);
|
||||
desktopManager->OnUiEvent(ui_event);
|
||||
}
|
||||
|
||||
void XcbInterface::OnButtonPress(xcb_button_press_event_t* event, DesktopManagerPtr desktopManager)
|
||||
{
|
||||
auto ui_event = MouseEvent::Create();
|
||||
auto x = static_cast<unsigned>(event->event_x);
|
||||
auto y = static_cast<unsigned>(event->event_y);
|
||||
ui_event->SetClientLocation(DiscretePoint(x, y));
|
||||
|
||||
auto screen_x = static_cast<unsigned>(event->root_x);
|
||||
auto screen_y = static_cast<unsigned>(event->root_y);
|
||||
ui_event->SetScreenLocation(DiscretePoint(x, y));
|
||||
|
||||
ui_event->SetAction(MouseEvent::Action::Pressed);
|
||||
desktopManager->OnUiEvent(ui_event);
|
||||
}
|
||||
|
||||
void XcbInterface::LoopOpenGl(std::shared_ptr<DesktopManager> desktopManager)
|
||||
{
|
||||
int running = 1;
|
||||
while(running)
|
||||
{
|
||||
/* Wait for event */
|
||||
xcb_generic_event_t *event = xcb_wait_for_event(mConnection);
|
||||
if(!event)
|
||||
{
|
||||
std::cout << "i/o error in xcb_wait_for_event" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(event->response_type & ~0x80)
|
||||
{
|
||||
case XCB_KEY_PRESS:
|
||||
/* Quit on key press */
|
||||
std::cout << "got key" << std::endl;
|
||||
running = 0;
|
||||
break;
|
||||
case XCB_KEY_RELEASE:
|
||||
/* Quit on key press */
|
||||
std::cout << "got key" << std::endl;
|
||||
running = 0;
|
||||
break;
|
||||
case XCB_EXPOSE:
|
||||
std::cout << "got expose" << std::endl;
|
||||
/* Handle expose event, draw and swap buffers */
|
||||
mGlxInterface->Draw();
|
||||
mGlxInterface->SwapBuffers(mX11Display);
|
||||
std::cout << "end expose" << std::endl;
|
||||
break;
|
||||
default:
|
||||
std::cout << "got something else" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
free(event);
|
||||
}
|
||||
mGlxInterface->DestroyWindow(mX11Display);
|
||||
//xcb_destroy_window(mConnection, window);
|
||||
mGlxInterface->DestroyContext(mX11Display);
|
||||
return;
|
||||
}
|
||||
|
||||
void XcbInterface::ClearWindow(WindowPtr window)
|
||||
{
|
||||
xcb_clear_area(mConnection, 1, mHandles[window], 0, 0,
|
||||
window->GetWidth(), window->GetHeight());
|
||||
xcb_flush(mConnection);
|
||||
}
|
||||
|
||||
void XcbInterface::Loop(DesktopManagerPtr desktopManager)
|
||||
{
|
||||
if(!mConnection) return;
|
||||
|
||||
if(mUseOpenGl)
|
||||
{
|
||||
LoopOpenGl(desktopManager);
|
||||
return;
|
||||
}
|
||||
|
||||
xcb_generic_event_t *event;
|
||||
while ((event = xcb_wait_for_event(mConnection)))
|
||||
{
|
||||
switch (event->response_type & ~0x80)
|
||||
{
|
||||
case XCB_EXPOSE:{
|
||||
auto expose_event = reinterpret_cast<xcb_expose_event_t*>(event);
|
||||
|
||||
// Update the window
|
||||
auto window = mWindows[expose_event->window];
|
||||
window->SetSize(expose_event->width, expose_event->height);
|
||||
|
||||
onPaint(desktopManager);
|
||||
/* flush the request */
|
||||
xcb_flush(mConnection);
|
||||
break;
|
||||
}
|
||||
case XCB_KEY_PRESS: {
|
||||
auto kr = reinterpret_cast<xcb_key_press_event_t*>(event);
|
||||
OnKeyPress(kr, desktopManager);
|
||||
break;
|
||||
}
|
||||
|
||||
case XCB_KEY_RELEASE: {
|
||||
auto kr = reinterpret_cast<xcb_key_release_event_t*>(event);
|
||||
OnKeyRelease(kr, desktopManager);
|
||||
break;
|
||||
}
|
||||
case XCB_BUTTON_PRESS: {
|
||||
auto press = reinterpret_cast<xcb_button_press_event_t*>(event);
|
||||
OnButtonPress(press, desktopManager);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* Unknown event type, ignore it */
|
||||
break;
|
||||
}
|
||||
if(desktopManager->IsModified())
|
||||
{
|
||||
desktopManager->SetIsModified(false);
|
||||
ClearWindow(desktopManager->GetWindowManager()->GetMainWindow());
|
||||
}
|
||||
|
||||
free (event);
|
||||
}
|
||||
}
|
||||
|
||||
void XcbInterface::ShutDown()
|
||||
{
|
||||
if(!mConnection) return;
|
||||
std::cout << "starting shutdown" << std::endl;
|
||||
xcb_disconnect(mConnection);
|
||||
if(mUseOpenGl && mX11Display)
|
||||
{
|
||||
//XCloseDisplay(mX11Display);
|
||||
}
|
||||
std::cout << "ending shutdown" << std::endl;
|
||||
}
|
84
src/windows/ui_interfaces/x11/XcbInterface.h
Normal file
84
src/windows/ui_interfaces/x11/XcbInterface.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
#include "Window.h"
|
||||
#include "VisualLayer.h"
|
||||
|
||||
class DesktopManager;
|
||||
using DesktopManagerPtr = std::shared_ptr<DesktopManager>;
|
||||
|
||||
class GlxInterface;
|
||||
using GlxInterfacePtr = std::shared_ptr<GlxInterface>;
|
||||
|
||||
struct xcb_screen_t;
|
||||
struct xcb_connection_t;
|
||||
struct xcb_key_press_event_t;
|
||||
struct xcb_button_press_event_t;
|
||||
struct _XDisplay;
|
||||
|
||||
class XcbInterface
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
bool mUseOpenGl;
|
||||
std::map<unsigned, WindowPtr> mWindows;
|
||||
std::map<WindowPtr, unsigned> mHandles;
|
||||
unsigned mDefaultWindow;
|
||||
xcb_connection_t* mConnection;
|
||||
xcb_screen_t* mScreen;
|
||||
unsigned mGraphicsContext;
|
||||
_XDisplay* mX11Display;
|
||||
GlxInterfacePtr mGlxInterface;
|
||||
|
||||
public:
|
||||
|
||||
XcbInterface();
|
||||
|
||||
~XcbInterface();
|
||||
|
||||
void SetUseOpenGl(bool use);
|
||||
void onPaint(std::shared_ptr<DesktopManager> desktopManager);
|
||||
|
||||
void Initialize();
|
||||
|
||||
void InitializeOpenGl();
|
||||
|
||||
void CreateOpenGlDrawable(WindowPtr window);
|
||||
|
||||
void Loop(std::shared_ptr<DesktopManager> desktopManager);
|
||||
|
||||
void LoopOpenGl(std::shared_ptr<DesktopManager> desktopManager);
|
||||
|
||||
void ShutDown();
|
||||
|
||||
void AddWindow(WindowPtr window);
|
||||
|
||||
void ShowWindow(WindowPtr window);
|
||||
|
||||
void PaintWindow(WindowPtr window);
|
||||
|
||||
void ClearWindow(WindowPtr window);
|
||||
|
||||
private:
|
||||
|
||||
void Connect();
|
||||
|
||||
void UpdateScreen();
|
||||
|
||||
uint32_t GetEventMask();
|
||||
|
||||
void OnKeyPress(xcb_key_press_event_t* event, DesktopManagerPtr);
|
||||
|
||||
void OnKeyRelease(xcb_key_press_event_t* event, DesktopManagerPtr);
|
||||
|
||||
void OnButtonPress(xcb_button_press_event_t* event, DesktopManagerPtr);
|
||||
|
||||
void MapWindow(WindowPtr window);
|
||||
|
||||
void CreateGraphicsContext();
|
||||
|
||||
|
||||
};
|
24
src/windows/ui_interfaces/x11/XcbKeyboard.cpp
Normal file
24
src/windows/ui_interfaces/x11/XcbKeyboard.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "XcbKeyboard.h"
|
||||
|
||||
|
||||
XcbKeyboard::XcbKeyboard()
|
||||
: Keyboard()
|
||||
{
|
||||
mKeyMap = {{24, "q"}, {25, "w"},
|
||||
{26, "e"}, {27, "r"},
|
||||
{28, "t"}, {29, "y"}, {30, "u"}, {31, "i"}, {32, "o"},
|
||||
{33, "p"}, {38, "a"}, {39, "s"}, {40, "d"}, {41, "f"},
|
||||
{42, "g"}, {43, "h"}, {44, "j"}, {45, "k"}, {46, "l"},
|
||||
{52, "z"}, {53, "x"}, {54, "c"}, {55, "v"}, {56, "b"},
|
||||
{57, "n"}, {58, "m"}};
|
||||
}
|
||||
|
||||
std::shared_ptr<XcbKeyboard> XcbKeyboard::Create()
|
||||
{
|
||||
return std::make_shared<XcbKeyboard>();
|
||||
}
|
||||
|
||||
std::string XcbKeyboard::GetKeyString(KeyCode keyCode)
|
||||
{
|
||||
return mKeyMap[keyCode];
|
||||
}
|
14
src/windows/ui_interfaces/x11/XcbKeyboard.h
Normal file
14
src/windows/ui_interfaces/x11/XcbKeyboard.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
#include "Keyboard.h"
|
||||
|
||||
class XcbKeyboard : public Keyboard
|
||||
{
|
||||
public:
|
||||
XcbKeyboard();
|
||||
|
||||
static std::shared_ptr<XcbKeyboard> Create();
|
||||
|
||||
std::string GetKeyString(KeyCode keyCode) override;
|
||||
};
|
||||
|
||||
using XcbKeyboardPtr = std::shared_ptr<XcbKeyboard>;
|
50
src/windows/ui_interfaces/x11/XcbLayerInterface.cpp
Normal file
50
src/windows/ui_interfaces/x11/XcbLayerInterface.cpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
#include "XcbLayerInterface.h"
|
||||
#include "XcbTextInterface.h"
|
||||
#include "RectangleElement.h"
|
||||
#include <memory>
|
||||
|
||||
uint32_t XcbLayerInterface::GetColor(ColorPtr color)
|
||||
{
|
||||
return XcbLayerInterface::GetColor(color->GetR(),
|
||||
color->GetG(), color->GetB());
|
||||
}
|
||||
|
||||
uint32_t XcbLayerInterface::GetColor(int r, int g, int b)
|
||||
{
|
||||
return b + (g<<8) + (r<<16);
|
||||
}
|
||||
|
||||
void XcbLayerInterface::ModifyGcColor(xcb_connection_t* connection, xcb_gcontext_t gc,
|
||||
ColorPtr color)
|
||||
{
|
||||
uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
|
||||
uint32_t values[2] = {XcbLayerInterface::GetColor(color), 0};
|
||||
|
||||
xcb_change_gc(connection, gc, mask, values);
|
||||
}
|
||||
|
||||
void XcbLayerInterface::AddLayer(xcb_connection_t* connection,
|
||||
xcb_screen_t* screen, xcb_window_t window, xcb_gcontext_t gc,
|
||||
VisualLayerPtr layer)
|
||||
{
|
||||
if(layer->HasText())
|
||||
{
|
||||
XcbTextInterface::AddTextElement(connection, screen, window, layer->GetText());
|
||||
}
|
||||
else if(layer->HasShape())
|
||||
{
|
||||
auto shape = layer->GetShape();
|
||||
if(shape->GetType() == GeometryElement::Type::Rectangle)
|
||||
{
|
||||
auto rectangle = std::dynamic_pointer_cast<RectangleElement>(shape);
|
||||
Pixel loc = rectangle->GetLocation();
|
||||
auto width = static_cast<uint16_t>(rectangle->GetWidth());
|
||||
auto height = static_cast<uint16_t>(rectangle->GetHeight());
|
||||
xcb_rectangle_t rectangles[] = { { static_cast<int16_t>(loc.GetX()),
|
||||
static_cast<int16_t>(loc.GetY()), width, height} };
|
||||
XcbLayerInterface::ModifyGcColor(connection, gc, rectangle->GetFillColor());
|
||||
xcb_poly_fill_rectangle(connection, window, gc, 1, rectangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
22
src/windows/ui_interfaces/x11/XcbLayerInterface.h
Normal file
22
src/windows/ui_interfaces/x11/XcbLayerInterface.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include "VisualLayer.h"
|
||||
#include "Color.h"
|
||||
|
||||
class XcbLayerInterface
|
||||
{
|
||||
public:
|
||||
|
||||
static uint32_t GetColor(ColorPtr);
|
||||
|
||||
static uint32_t GetColor(int r, int g, int b);
|
||||
|
||||
static void ModifyGcColor(xcb_connection_t* connection, xcb_gcontext_t gc,
|
||||
ColorPtr color);
|
||||
|
||||
static void AddLayer(xcb_connection_t* connection,
|
||||
xcb_screen_t* screen, xcb_window_t window, xcb_gcontext_t gc,
|
||||
VisualLayerPtr layer);
|
||||
};
|
||||
|
39
src/windows/ui_interfaces/x11/XcbTextInterface.cpp
Normal file
39
src/windows/ui_interfaces/x11/XcbTextInterface.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include "XcbTextInterface.h"
|
||||
#include <string.h>
|
||||
|
||||
xcb_gcontext_t XcbTextInterface::GetFontGC(xcb_connection_t *connection,
|
||||
xcb_screen_t *screen, xcb_window_t window, const char*font_name)
|
||||
{
|
||||
/* get font */
|
||||
xcb_font_t font = xcb_generate_id(connection);
|
||||
xcb_open_font(connection, font, strlen(font_name), font_name);
|
||||
|
||||
/* create graphics context */
|
||||
xcb_gcontext_t gc = xcb_generate_id(connection);
|
||||
uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
|
||||
uint32_t value_list[3] = {screen->black_pixel, screen->white_pixel, font };
|
||||
|
||||
xcb_create_gc(connection, gc, window, mask, value_list);
|
||||
|
||||
/* close font */
|
||||
xcb_close_font(connection, font);
|
||||
return gc;
|
||||
}
|
||||
|
||||
void XcbTextInterface::AddTextElement(xcb_connection_t* connection,
|
||||
xcb_screen_t* screen, xcb_window_t window,
|
||||
TextElementPtr textElement)
|
||||
{
|
||||
/* get graphics context */
|
||||
xcb_gcontext_t gc = XcbTextInterface::GetFontGC(connection, screen, window,
|
||||
textElement->GetFontLabel().c_str());
|
||||
|
||||
/* draw the text */
|
||||
std::string content = textElement->GetContent();
|
||||
Pixel loc = textElement->GetLocation();
|
||||
xcb_image_text_8(connection, content.length(), window, gc,
|
||||
loc.GetX(), loc.GetY(), content.c_str());
|
||||
|
||||
/* free the gc */
|
||||
xcb_free_gc(connection, gc);
|
||||
}
|
16
src/windows/ui_interfaces/x11/XcbTextInterface.h
Normal file
16
src/windows/ui_interfaces/x11/XcbTextInterface.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
#include "TextElement.h"
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
class XcbTextInterface
|
||||
{
|
||||
public:
|
||||
static xcb_gcontext_t GetFontGC(xcb_connection_t* connection,
|
||||
xcb_screen_t*screen, xcb_window_t window, const char*font_name);
|
||||
|
||||
static void AddTextElement(xcb_connection_t* connection,
|
||||
xcb_screen_t* screen, xcb_window_t window,
|
||||
TextElementPtr textElement);
|
||||
|
||||
};
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue