aboutsummaryrefslogtreecommitdiff
path: root/x11.c
diff options
context:
space:
mode:
Diffstat (limited to 'x11.c')
-rw-r--r--x11.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/x11.c b/x11.c
new file mode 100644
index 0000000..1cf4393
--- /dev/null
+++ b/x11.c
@@ -0,0 +1,114 @@
+#include <stdbool.h>
+#include <glib.h>
+#include <math.h>
+#include <cairo.h>
+#include <cairo-xcb.h>
+#include <xcb/xcb.h>
+#include <xcb/xcb_aux.h>
+#include <xcb/xproto.h>
+#include <xcb/xcb_icccm.h>
+#include <xcb/xcb_xrm.h>
+
+#include "x11.h"
+
+struct Window {
+ xcb_screen_t *screen;
+ xcb_connection_t *connection;
+ xcb_drawable_t window;
+ xcb_visualtype_t *visual_type;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+};
+
+Window *window_create(void)
+{
+ Window *win = g_malloc0(sizeof(Window));
+
+ int preferred_screen = 0;
+ win->connection = xcb_connect(NULL, &preferred_screen);
+
+ xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_get_setup(win->connection));
+
+ while (preferred_screen != 0 && iter.rem) {
+ xcb_screen_next(&iter);
+ preferred_screen--;
+ }
+
+ win->screen = iter.data;
+
+ win->window = xcb_generate_id(win->connection);
+
+ int y = 0, x = 0, h = 300, w = 400;
+ xcb_create_window(win->connection,
+ XCB_COPY_FROM_PARENT,
+ win->window, win->screen->root,
+ y, x, h, w, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ win->screen->root_visual,
+ XCB_CW_BACK_PIXEL,
+ //XCB_CW_BACK_PIXEL | XCB_CW_BACK_PIXMAP | XCB_CW_OVERRIDE_REDIRECT |
+ // XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
+ &win->screen->white_pixel);
+
+ xcb_icccm_set_wm_name(win->connection, win->window, XCB_ATOM_STRING, 8, strlen("comet"), "comet");
+ xcb_map_window(win->connection, win->window);
+ xcb_flush(win->connection);
+
+ xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(win->screen);
+
+ while (depth_iter.rem) {
+ xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
+
+ while (visual_iter.rem) {
+ if (win->screen->root_visual == visual_iter.data->visual_id) {
+ win->visual_type = visual_iter.data;
+ goto done;
+ }
+ xcb_visualtype_next(&visual_iter);
+ }
+ xcb_depth_next(&depth_iter);
+ }
+
+done:
+
+ win->surface = cairo_xcb_surface_create(win->connection, win->window, win->visual_type, w, h);
+ win->cr = cairo_create(win->surface);
+
+ return win;
+}
+
+cairo_t *window_get_context(Window *win)
+{
+ return win->cr;
+}
+
+double window_get_scale(Window *win)
+{
+ // TODO
+ return 1;
+}
+
+void window_paint_surface(Window *win, cairo_surface_t *surface, int width, int height)
+{
+ double scale = window_get_scale(win);
+
+ cairo_xcb_surface_set_size(win->surface, round(width * scale), round(height * scale));
+
+ xcb_clear_area(win->connection, false, win->window, 0, 0, 0, 0);
+
+ cairo_set_source_surface(win->cr, surface, 0, 0);
+ cairo_paint(win->cr);
+ cairo_show_page(win->cr);
+
+ xcb_flush(win->connection);
+}
+
+void window_destroy(Window *win)
+{
+ cairo_destroy(win->cr);
+ cairo_surface_destroy(win->surface);
+ xcb_disconnect(win->connection);
+ g_free(win);
+}
+
+// vim: set ts=4 sw=4 et