Gears/src/gears/platform.d

176 lines
4.0 KiB
D

import aliases;
import includes;
import std.stdio;
import core.memory;
version(linux)
{
import core.sys.posix.dlfcn;
struct Window
{
Display *display;
xcb_connection_t *conn;
xcb_window_t window;
xcb_atom_t close_event;
xcb_atom_t minimize_event;
u16 w;
u16 h;
};
struct Library
{
void* ptr;
};
struct Function
{
void* ptr;
};
void CheckErr(Window *window, xcb_void_cookie_t *cookie, xcb_generic_error_t *err, string msg)
{
assert(err == null, msg);
pureFree(err);
};
Window CreateWindow(string name, u16 width, u16 height)
{
Window window = {
w: width,
h: height,
};
assert(width > 0 && height > 0, "CreateWindow error: width and height must be above 0");
window.display = XOpenDisplay(null);
assert(window.display != null, "XOpenDisplay failure");
window.conn = XGetXCBConnection(window.display);
assert(window.conn != null, "XGetXCBConnection failure");
xcb_void_cookie_t cookie;
xcb_generic_error_t *error;
xcb_setup_t *setup = xcb_get_setup(window.conn);
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
xcb_screen_t *screen = iter.data;
i32 event_mask = XCB_EVENT_MASK_EXPOSURE |
XCB_EVENT_MASK_KEY_PRESS |
XCB_EVENT_MASK_KEY_RELEASE |
XCB_EVENT_MASK_BUTTON_PRESS |
XCB_EVENT_MASK_BUTTON_RELEASE |
XCB_EVENT_MASK_POINTER_MOTION |
XCB_EVENT_MASK_STRUCTURE_NOTIFY;
i32[] val_win = [screen.black_pixel, event_mask];
i32 val_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
window.window = xcb_generate_id(window.conn);
cookie = xcb_create_window_checked(
window.conn,
XCB_COPY_FROM_PARENT,
window.window,
screen.root,
0, // x pos
0, // y pos
window.w, // width
window.h, // height
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen.root_visual,
val_mask,
val_win.ptr
);
error = xcb_request_check(window.conn, cookie);
CheckErr(&window, &cookie, error, "xcb_create_window failure");
cookie = xcb_map_window_checked(window.conn, window.window);
error = xcb_request_check(window.conn, cookie);
CheckErr(&window, &cookie, error, "xcb_map_window_checked failure");
cookie = xcb_change_property_checked(
window.conn,
XCB_PROP_MODE_REPLACE,
window.window,
XCB_ATOM_WM_NAME,
XCB_ATOM_STRING,
8,
cast(u32)name.length,
name.ptr
);
error = xcb_request_check(window.conn, cookie);
CheckErr(&window, &cookie, error, "xcb_change_property_checked failure");
xcb_intern_atom_cookie_t c_proto = xcb_intern_atom(window.conn, 1, 12, "WM_PROTOCOLS");
xcb_intern_atom_reply_t *r_proto = xcb_intern_atom_reply(window.conn, c_proto, &error);
CheckErr(&window, &cookie, error, "xcb_intern_atom WM_PROTOCOLS failure");
xcb_intern_atom_cookie_t c_close = xcb_intern_atom(window.conn, 0, 16, "WM_DELETE_WINDOW");
xcb_intern_atom_reply_t *r_close = xcb_intern_atom_reply(window.conn, c_close, &error);
CheckErr(&window, &cookie, error, "xcb_intern_atom WM_DELETE_WINDOW failure");
xcb_intern_atom_cookie_t c_minimize = xcb_intern_atom(window.conn, 0, 20, "_NET_WM_STATE_HIDDEN");
xcb_intern_atom_reply_t *r_minimize = xcb_intern_atom_reply(window.conn, c_minimize, &error);
CheckErr(&window, &cookie, error, "xcb_intern_atom _NET_WM_STATE_HIDDEN failure");
cookie = xcb_change_property_checked(
window.conn,
XCB_PROP_MODE_REPLACE,
window.window,
r_proto.atom,
XCB_ATOM_ATOM,
32,
1,
&r_close.atom
);
error = xcb_request_check(window.conn, cookie);
CheckErr(&window, &cookie, error, "xcb_change_property_checked failure");
window.close_event = r_close.atom;
window.minimize_event = r_minimize.atom;
pureFree(r_proto);
pureFree(r_close);
pureFree(r_minimize);
xcb_map_window(window.conn, window.window);
i32 stream_result = xcb_flush(window.conn);
assert(stream_result > 0, "xcb_flush failure");
return window;
};
Library LoadLibrary(string name)
{
Library lib = {
ptr: null,
};
lib.ptr = dlopen(name.ptr, RTLD_NOW);
return lib;
};
Function LoadFunction(Library lib, string name)
{
Function fn = {
ptr: null,
};
fn.ptr = dlsym(lib.ptr, name.ptr);
return fn;
};
}
version(Windows)
{
}