Created
February 26, 2019 01:47
-
-
Save lighth7015/5115b9d5e4871ab09b320dae7d651768 to your computer and use it in GitHub Desktop.
Basic XCB UI utilizing C++ and CRTP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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