module gui.gui; import bcd.xcb.xcb; import lodepng.png; import std.stdio; import std.file; import std.string; GUI gui; class GUI{ xcb_connection_t* conn; xcb_screen_t* screen; Window[xcb_window_t] windows; Button[xcb_window_t] buttons; xcb_generic_event_t* event; this(){ int screen_num; conn = xcb_connect(null, &screen_num); /* Get the preferred screen. */ xcb_screen_iterator_t screen_iter = xcb_setup_roots_iterator(xcb_get_setup(conn)); while(screen_num--) xcb_screen_next(&screen_iter); screen = screen_iter.data; } Window addWindow(geometry geom){ Window w = new Window(screen.root, 0, 0, geom); //Position handled by the window manager xcb_change_window_attributes(gui.conn, w.id, XCB_CW_EVENT_MASK, cast(uint*)[XCB_EVENT_MASK_RESIZE_REDIRECT]); windows[w.id] = w; return w; } void loop(){ loop: xcb_flush(gui.conn); event = xcb_wait_for_event(conn); switch(event.response_type){ case XCB_BUTTON_PRESS: xcb_button_press_event_t* e = cast(xcb_button_press_event_t* )event; if(e.event in buttons) buttons[e.event].onPress(); break; case XCB_BUTTON_RELEASE: xcb_button_release_event_t* e = cast(xcb_button_release_event_t* )event; if(e.event in buttons) buttons[e.event].onRelease(); break; case XCB_RESIZE_REQUEST://FIX writefln("2"); //windows[id].recalculate(); break; default: break; } goto loop; } } struct geometry{ uint width; uint height; } geometry Geometry(uint width, uint height){ geometry geom; geom.width = width; geom.height = height; return geom; } class Window{ xcb_window_t id; Window[] subwindows; this(xcb_window_t parent, int x, int y, geometry geom){ id = xcb_generate_id(gui.conn); xcb_create_window(gui.conn, /* connection */ 0, /* depth */ id, /* window id */ parent, /* parent window */ x, y, /* x, y */ geom.width, geom.height, /* width, height */ 0, /* border_width */ XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */ gui.screen.root_visual, /* visual */ 0, /* masks */ null); } void map(){ xcb_map_window(gui.conn, id); } void unmap(){ xcb_unmap_window(gui.conn, id); } void resize(geometry geom){ xcb_configure_window(gui.conn, id, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, cast(uint*)[geom.width, geom.height]); } void moveResize(int x, int y, geometry geom){ xcb_configure_window(gui.conn, id, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, cast(uint*)[x, y, geom.width, geom.height]); } geometry getGeometry(){ xcb_get_geometry_reply_t* attr = xcb_get_geometry_reply(gui.conn, xcb_get_geometry(gui.conn, id), null); return Geometry(attr.width,attr.height); } void setBackground(char[] filename){ ubyte[] data; Info info = lodepng.png.decode32(data, cast(ubyte[])read(filename)); //if (info.error != 0) //throw new Exception("Error loading png " ~ filename ~ ", errorcode: " ~ toString(info.error)); if(data.length % 4 != 0) throw new Exception("Failcopter"); for(uint i; i