Move windows to uptr. Add simple text editing.
This commit is contained in:
parent
2bcc7b3d83
commit
b99708e7d3
55 changed files with 1257 additions and 994 deletions
|
@ -16,15 +16,15 @@
|
|||
|
||||
|
||||
XcbInterface::XcbInterface()
|
||||
: mUseOpenGl(true),
|
||||
mConnection(nullptr),
|
||||
mScreen(nullptr),
|
||||
mWindows(),
|
||||
mHandles(),
|
||||
mDefaultWindow(-1),
|
||||
mGraphicsContext(-1),
|
||||
mX11Display(),
|
||||
mGlxInterface()
|
||||
: mUseOpenGl(true),
|
||||
mConnection(nullptr),
|
||||
mScreen(nullptr),
|
||||
mWindows(),
|
||||
mHandles(),
|
||||
mDefaultWindow(-1),
|
||||
mGraphicsContext(-1),
|
||||
mX11Display(),
|
||||
mGlxInterface()
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -36,313 +36,314 @@ XcbInterface::~XcbInterface()
|
|||
|
||||
void XcbInterface::SetUseOpenGl(bool use)
|
||||
{
|
||||
mUseOpenGl = use;
|
||||
mUseOpenGl = use;
|
||||
}
|
||||
|
||||
void XcbInterface::Initialize()
|
||||
{
|
||||
Connect();
|
||||
UpdateScreen();
|
||||
CreateGraphicsContext();
|
||||
Connect();
|
||||
UpdateScreen();
|
||||
CreateGraphicsContext();
|
||||
|
||||
if(mUseOpenGl)
|
||||
{
|
||||
InitializeOpenGl();
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
/* 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);
|
||||
}
|
||||
/* Acquire event queue ownership */
|
||||
XSetEventQueueOwner(mX11Display, XCBOwnsEventQueue);
|
||||
}
|
||||
else
|
||||
{
|
||||
mConnection = xcb_connect(nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void XcbInterface::UpdateScreen()
|
||||
{
|
||||
if(!mConnection) return;
|
||||
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;
|
||||
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);
|
||||
mGlxInterface = GlxInterface::Create();
|
||||
int default_screen = DefaultScreen(mX11Display);
|
||||
mGlxInterface->SetupContext(mX11Display, default_screen);
|
||||
}
|
||||
|
||||
void XcbInterface::CreateOpenGlDrawable(WindowPtr window)
|
||||
void XcbInterface::CreateOpenGlDrawable(mt::Window* window)
|
||||
{
|
||||
if(!mUseOpenGl)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto hwnd = mHandles[window];
|
||||
bool result = mGlxInterface->SetupWindow(mX11Display, hwnd);
|
||||
if(!result)
|
||||
{
|
||||
xcb_destroy_window(mConnection, hwnd);
|
||||
}
|
||||
if(!mUseOpenGl or !window)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
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)
|
||||
void XcbInterface::MapWindow(mt::Window* window)
|
||||
{
|
||||
if(!mConnection) return;
|
||||
xcb_map_window(mConnection, mHandles[window]);
|
||||
xcb_flush(mConnection);
|
||||
if(!mConnection or !window) return;
|
||||
xcb_map_window(mConnection, mHandles[window]);
|
||||
xcb_flush(mConnection);
|
||||
}
|
||||
|
||||
void XcbInterface::ShowWindow(WindowPtr window)
|
||||
void XcbInterface::ShowWindow(mt::Window* window)
|
||||
{
|
||||
MapWindow(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;
|
||||
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)
|
||||
void XcbInterface::AddWindow(mt::Window* window)
|
||||
{
|
||||
if(!mConnection || !mScreen) return;
|
||||
auto hwnd = xcb_generate_id(mConnection);
|
||||
if(!mConnection || !mScreen || !window) 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()};
|
||||
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;
|
||||
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)
|
||||
void XcbInterface::onPaint(DesktopManager* desktopManager)
|
||||
{
|
||||
auto ui_event = PaintEvent::Create();
|
||||
desktopManager->OnUiEvent(ui_event);
|
||||
|
||||
PaintWindow(desktopManager->GetWindowManager()->GetMainWindow());
|
||||
desktopManager->OnUiEvent(PaintEvent::Create());
|
||||
PaintWindow(desktopManager->GetWindowManager()->GetMainWindow());
|
||||
}
|
||||
|
||||
void XcbInterface::PaintWindow(WindowPtr window)
|
||||
void XcbInterface::PaintWindow(mt::Window* window)
|
||||
{
|
||||
const auto hwnd = mHandles[window];
|
||||
for(const auto& layer : window->GetLayers())
|
||||
{
|
||||
XcbLayerInterface::AddLayer(mConnection, mScreen,
|
||||
hwnd, mGraphicsContext, layer);
|
||||
}
|
||||
if(!window) return;
|
||||
|
||||
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)
|
||||
void XcbInterface::OnKeyPress(xcb_key_press_event_t* event, DesktopManager* 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);
|
||||
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(std::move(ui_event));
|
||||
}
|
||||
|
||||
void XcbInterface::OnKeyRelease(xcb_key_release_event_t* event, DesktopManagerPtr desktopManager)
|
||||
void XcbInterface::OnKeyRelease(xcb_key_release_event_t* event, DesktopManager* 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);
|
||||
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(std::move(ui_event));
|
||||
}
|
||||
|
||||
void XcbInterface::OnButtonPress(xcb_button_press_event_t* event, DesktopManagerPtr desktopManager)
|
||||
void XcbInterface::OnButtonPress(xcb_button_press_event_t* event, DesktopManager* desktopManager)
|
||||
{
|
||||
auto ui_event = MouseEvent::Create();
|
||||
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));
|
||||
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);
|
||||
ui_event->SetAction(MouseEvent::Action::Pressed);
|
||||
desktopManager->OnUiEvent(std::move(ui_event));
|
||||
}
|
||||
|
||||
void XcbInterface::LoopOpenGl(std::shared_ptr<DesktopManager> desktopManager)
|
||||
void XcbInterface::LoopOpenGl(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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
free(event);
|
||||
}
|
||||
mGlxInterface->DestroyWindow(mX11Display);
|
||||
//xcb_destroy_window(mConnection, window);
|
||||
mGlxInterface->DestroyContext(mX11Display);
|
||||
return;
|
||||
}
|
||||
|
||||
void XcbInterface::ClearWindow(WindowPtr window)
|
||||
void XcbInterface::ClearWindow(mt::Window* window)
|
||||
{
|
||||
xcb_clear_area(mConnection, 1, mHandles[window], 0, 0,
|
||||
window->GetWidth(), window->GetHeight());
|
||||
xcb_flush(mConnection);
|
||||
if(!window) return;
|
||||
xcb_clear_area(mConnection, 1, mHandles[window], 0, 0,
|
||||
window->GetWidth(), window->GetHeight());
|
||||
xcb_flush(mConnection);
|
||||
}
|
||||
|
||||
void XcbInterface::Loop(DesktopManagerPtr desktopManager)
|
||||
void XcbInterface::Loop(DesktopManager* desktopManager)
|
||||
{
|
||||
if(!mConnection) return;
|
||||
if(!mConnection) return;
|
||||
|
||||
if(mUseOpenGl)
|
||||
{
|
||||
LoopOpenGl(desktopManager);
|
||||
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);
|
||||
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);
|
||||
// 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;
|
||||
}
|
||||
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());
|
||||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
if(!mConnection) return;
|
||||
std::cout << "starting shutdown" << std::endl;
|
||||
xcb_disconnect(mConnection);
|
||||
if(mUseOpenGl && mX11Display)
|
||||
{
|
||||
//XCloseDisplay(mX11Display);
|
||||
}
|
||||
std::cout << "ending shutdown" << std::endl;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue