Skip to content

Instantly share code, notes, and snippets.

@lighth7015
Created February 26, 2019 01:47
Show Gist options
  • Save lighth7015/5115b9d5e4871ab09b320dae7d651768 to your computer and use it in GitHub Desktop.
Save lighth7015/5115b9d5e4871ab09b320dae7d651768 to your computer and use it in GitHub Desktop.
Basic XCB UI utilizing C++ and CRTP
#include <iostream>
#include <string.h>
#include <xcb/xcb.h>
template <typename Child>
class Window
{
protected:
xcb_drawable_t handle;
xcb_gcontext_t context;
xcb_rectangle_t* rect;
xcb_connection_t* connection;
const char* caption;
public:
void interface() {
std::cout << "Servicing method." << std::endl;
static_cast<Child*>(this)
->interface();
}
xcb_drawable_t Create(xcb_connection_t *server, xcb_screen_t *display)
{
handle = xcb_generate_id (server);
context = xcb_generate_id (server);
connection = server;
caption = "Window Title";
uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
uint32_t values[2] = {display->white_pixel, 0};
mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
xcb_create_gc (connection, context, display->root, mask, values);
xcb_create_window(server,
XCB_COPY_FROM_PARENT, // depth
handle, // window Id
display->root, // parent window
75, 75, // x, y
100, 120, // width, height
10, // border_width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // class
display->root_visual, // visual
mask, values ); // masks
xcb_change_property(connection,
XCB_PROP_MODE_REPLACE,
handle,
XCB_ATOM_WM_NAME,
XCB_ATOM_STRING,
8,
strlen(caption),
caption);
return handle;
}
bool Show() {
xcb_void_cookie_t cookie =
xcb_map_window_checked(connection, handle);
return true;
}
bool Hide() {
xcb_void_cookie_t cookie =
xcb_unmap_window_checked(connection, handle);
return true;
}
};
class MainWindow : public Window<MainWindow>
{
public:
void interface() {
std::cout << "Child implementation." << std::endl;
}
};
class Application {
xcb_connection_t* connection;
xcb_screen_t* display;
uint32_t status;
void InitDefaultDisplay()
{
connection = xcb_connect (NULL, NULL);
const struct xcb_setup_t* handle =
xcb_get_setup(connection);
xcb_screen_iterator_t displays =
xcb_setup_roots_iterator (handle);
display = displays.data;
}
public:
Application()
{
InitDefaultDisplay();
}
uint32_t result() {
return status;
}
template<typename T>
void run(Window<T>* pWindow)
{
if (connection)
{
Window<T>& window(*pWindow);
xcb_drawable_t hWnd(window.Create(connection, display));
window.Show();
xcb_flush (connection);
for ( xcb_generic_event_t *event = xcb_wait_for_event (connection)
; event
; event = xcb_wait_for_event (connection)
)
{
switch (event->response_type & ~0x80) {
case XCB_EXPOSE:
xcb_flush (connection);
break;
default:
// Unknown event type, ignore it
break;
}
free (event);
}
status = 0;
}
}
};
Application app;
// DispatchEvent(d);
int main()
{
app.run(new MainWindow);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment