diff options
| author | Federico Angelilli <code@fedang.net> | 2023-11-17 15:42:49 +0100 |
|---|---|---|
| committer | Federico Angelilli <code@fedang.net> | 2023-11-17 15:42:49 +0100 |
| commit | ab92cac18652f72be12f68b5a96095ba8eb5afdf (patch) | |
| tree | e52a5f295c7cda59e67a341fa87d25983bd56745 /window.c | |
| parent | f8363e89257e8b0a4ff71accbd7b6be22935274f (diff) | |
Reorganize project structure
Diffstat (limited to 'window.c')
| -rw-r--r-- | window.c | 321 |
1 files changed, 0 insertions, 321 deletions
diff --git a/window.c b/window.c deleted file mode 100644 index 734761a..0000000 --- a/window.c +++ /dev/null @@ -1,321 +0,0 @@ -#include <glib.h> -#include <unistd.h> -#include <math.h> -#include <cairo.h> -#include <cairo-xcb.h> -#include <xcb/xcb.h> -#include <xcb/xproto.h> -#include <xcb/xcb_aux.h> -#include <xcb/xcb_icccm.h> -#include <xcb/xcb_ewmh.h> -#include <xcb/xcb_xrm.h> -#include <xcb/xcb_errors.h> -#include <xcb/randr.h> -#include <xcb/shape.h> - -#include "window.h" -#include "log.h" - -static xcb_atom_t intern_atom(Window *win, const char *atom) -{ - xcb_generic_error_t *error; - xcb_intern_atom_cookie_t cookie = xcb_intern_atom(win->con->connection, false, strlen(atom), atom); - xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(win->con->connection, cookie, &error); - - g_assert_null(error); - xcb_atom_t id = reply->atom; - g_free(reply); - return id; -} - -static void wm_set_size(Window *win) -{ - xcb_size_hints_t hints; - xcb_icccm_size_hints_set_size(&hints, false, win->width, win->height); - xcb_icccm_size_hints_set_min_size(&hints, win->width, win->height); - xcb_icccm_size_hints_set_max_size(&hints, win->width, win->height); - xcb_icccm_size_hints_set_base_size(&hints, win->width, win->height); - xcb_icccm_size_hints_set_position(&hints, false, win->x, win->y); - - xcb_icccm_set_wm_size_hints(win->con->connection, win->window, XCB_ATOM_WM_NORMAL_HINTS, &hints); - log_debug("Xcb icccm updated size hints"); -} - -static void wm_set_struts(Window *win) -{ - const uint32_t end = MAX(0, win->x + win->width - 1); - - const uint32_t values[12] = { - 0, 0, win->height, 0, // left, right, top, bottom - 0, 0, 0, 0, // left y0, left y1, right y0, right y1 - win->x, end, 0, 0, // top y0, top y1, bottom y0, bottom y1 - }; - - xcb_change_property(win->con->connection, - XCB_PROP_MODE_REPLACE, - win->window, - win->con->ewmh._NET_WM_STRUT, - XCB_ATOM_CARDINAL, - 32, - 4, - values); - - xcb_change_property(win->con->connection, - XCB_PROP_MODE_REPLACE, - win->window, - win->con->ewmh._NET_WM_STRUT_PARTIAL, - XCB_ATOM_CARDINAL, - 32, - 12, - values); - - log_debug("Xcb ewmh struts updated"); -} - -static void wm_setup(Window *win) -{ - const char *title = "comet"; - xcb_icccm_set_wm_name(win->con->connection, win->window, XCB_ATOM_STRING, 8, strlen(title), title); - log_debug("Window updated title [%s]", title); - - const char class[] = "comet\0Comet"; - xcb_icccm_set_wm_class(win->con->connection, win->window, strlen(class), class); - log_debug("Window updated class [%s]", "comet\\0Comet"); - - xcb_generic_error_t *error; - xcb_intern_atom_cookie_t *ewmh_cookie = xcb_ewmh_init_atoms(win->con->connection, &win->con->ewmh); - - g_assert_true(xcb_ewmh_init_atoms_replies(&win->con->ewmh, ewmh_cookie, &error)); - g_assert_null(error); - log_debug("Xcb ewmh connected"); - - xcb_ewmh_set_wm_window_type(&win->con->ewmh, win->window, 1, &win->con->ewmh._NET_WM_WINDOW_TYPE_DOCK); - - xcb_atom_t state[] = { - win->con->ewmh._NET_WM_STATE_STICKY, - win->con->ewmh._NET_WM_STATE_ABOVE - }; - xcb_ewmh_set_wm_state(&win->con->ewmh, win->window, G_N_ELEMENTS(state), state); - - xcb_ewmh_set_wm_desktop(&win->con->ewmh, win->window, 0xFFFFFFFF); - - xcb_ewmh_set_wm_pid(&win->con->ewmh, win->window, getpid()); - - wm_set_size(win); - - wm_set_struts(win); -} - -Window *window_create(Connection *con) -{ - Window *win = g_malloc0(sizeof(Window)); - g_assert_nonnull(win); - win->con = con; - - const uint32_t value_mask = XCB_CW_BACK_PIXMAP | XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL - | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; - - const uint32_t event_mask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY - | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_FOCUS_CHANGE - | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS; - - xcb_colormap_t colormap = xcb_generate_id(con->connection); - xcb_create_colormap(con->connection, XCB_COLORMAP_ALLOC_NONE, colormap, con->screen->root, con->visual_type->visual_id); - log_debug("Xcb colormap created [id=%u]", colormap); - - const uint32_t value_list[] = { - XCB_NONE, // back pixmap - 0x00000000, // back pixel - 0x00000000, // border pixel - true, // override redirect - event_mask, // event mask - colormap // colormap - }; - - win->width = win->height = 1; - log_debug("Window temporary size [width=%d, height=%d]", win->width, win->height); - - win->x = win->y = 0; - log_debug("Window temporary position [x=%d, y=%d]", win->x, win->y); - - win->window = xcb_generate_id(con->connection); - xcb_create_window(con->connection, - con->screen_depth, - win->window, - con->screen->root, - win->x, win->y, - win->width, win->height, - 0, // border - XCB_WINDOW_CLASS_COPY_FROM_PARENT, - con->visual_type->visual_id, - value_mask, - value_list); - - log_debug("Xcb window created [id=%u]", win->window); - - wm_setup(win); - log_debug("Window wm options completed"); - - xcb_map_window(con->connection, win->window); - xcb_flush(con->connection); - log_debug("Xcb initialized"); - - win->surface = cairo_xcb_surface_create(con->connection, - win->window, - con->visual_type, - con->screen_size->width, - con->screen_size->height); - - g_assert_cmpint(cairo_surface_status(win->surface), ==, CAIRO_STATUS_SUCCESS); - log_debug("Cairo surface created"); - - win->cr = cairo_create(win->surface); - g_assert_cmpint(cairo_status(win->cr), ==, CAIRO_STATUS_SUCCESS); - log_debug("Cairo context created"); - - return win; -} - -cairo_t *window_get_context(Window *win) -{ - return win->cr; -} - -double window_get_scale(Window *win) -{ - return MAX(1, win->con->screen_dpi/96.); -} - -void window_get_screen_size(Window *win, int *width, int *height) -{ - *width = win->con->screen_size->width; - *height = win->con->screen_size->height; -} - -void window_set_opacity(Window *win, double alpha) -{ - // Value between 0 and 1 - g_assert_true(alpha >= 0 && alpha <= 1); - unsigned long opacity = 0xffffffff * alpha; - - xcb_atom_t _NET_WM_WINDOW_OPACITY = intern_atom(win, "_NET_WM_WINDOW_OPACITY"); - xcb_change_property(win->con->connection, - XCB_PROP_MODE_REPLACE, - win->window, - _NET_WM_WINDOW_OPACITY, - XCB_ATOM_CARDINAL, - 32, - 1, - (char *)&opacity); - - log_debug("Window updated opacity [%.2lf%%]", alpha * 100.0); - -} - -void window_move(Window *win, int x, int y) -{ - if (win->x == x && win->y == y) return; - - win->x = x; - win->y = y; - - const uint32_t values[] = { x, y }; - xcb_configure_window(win->con->connection, - win->window, - XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, - values); - - log_debug("Window updated position [x=%d, y=%d]", win->x, win->y); -} - -void window_resize(Window *win, int width, int height) -{ - if (win->width == width && win->height == height) return; - - win->width = width; - win->height = height; - - const uint32_t values[] = { width, height }; - xcb_configure_window(win->con->connection, - win->window, - XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, - values); - - log_debug("Window updated size [width=%d, height=%d]", win->width, win->height); - - wm_set_size(win); -} - -static void window_paint_corners(Window *win) -{ - // TODO: Actually make this a parameter - int radius = win->height / 2; - double degree = M_PI / 180.0; - - // TODO: Check this value - int depth = 1; - - xcb_pixmap_t bitmap = xcb_generate_id(win->con->connection); - xcb_create_pixmap(win->con->connection, depth, bitmap, win->window, win->width, win->height); - log_debug("Xcb pixmap created [id=%u]", bitmap); - - cairo_surface_t *surface = cairo_xcb_surface_create_for_bitmap(win->con->connection, - win->con->screen, - bitmap, - win->width, - win->height); - - cairo_t *cr = cairo_create(surface); - - // TODO: Fix antialiasing situation - //cairo_set_antialias(cr, CAIRO_ANTIALIAS_GOOD); - - cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); - cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); - - cairo_set_source_rgba(cr, 0, 0, 0, 0); - cairo_paint(cr); - - cairo_set_source_rgba(cr, 1, 1, 1, 1); - cairo_arc(cr, radius, radius, radius, 90.0 * degree, 270 * degree); - cairo_arc(cr, win->width - radius, radius, radius, 270 * degree, 450 * degree); - cairo_fill(cr); - - log_debug("Xcb shape painted"); - - cairo_show_page(cr); - cairo_destroy(cr); - cairo_surface_flush(surface); - cairo_surface_destroy(surface); - - xcb_shape_mask(win->con->connection, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, win->window, 0, 0, bitmap); - xcb_shape_select_input(win->con->connection, win->window, XCB_SHAPE_NOTIFY); - log_debug("Xcb shape mask configured"); - - xcb_free_pixmap(win->con->connection, bitmap); -} - -void window_paint_surface(Window *win, cairo_surface_t *surface, int width, int height) -{ - cairo_xcb_surface_set_size(win->surface, width, height); - xcb_clear_area(win->con->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); - - window_paint_corners(win); - - xcb_circulate_window(win->con->connection, XCB_CIRCULATE_RAISE_LOWEST, win->window); - xcb_flush(win->con->connection); -} - -void window_destroy(Window *win) -{ - cairo_destroy(win->cr); - cairo_surface_destroy(win->surface); - - g_free(win); -} - -// vim: ts=4 sw=4 et |
