diff options
Diffstat (limited to 'x11.c')
| -rw-r--r-- | x11.c | 114 |
1 files changed, 114 insertions, 0 deletions
@@ -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 |
