diff options
| -rw-r--r-- | draw.c | 61 | ||||
| -rw-r--r-- | log.h | 2 | ||||
| -rw-r--r-- | x11.c | 78 | ||||
| -rw-r--r-- | x11.h | 6 |
4 files changed, 117 insertions, 30 deletions
@@ -3,31 +3,66 @@ #include <cairo.h> #include "x11.h" +#include "log.h" + +#define EVEN(n) ((int)(n) - ((int)(n) % 2 != 0)) void draw(Window *win) { double scale = window_get_scale(win); - int w = 1000, h = 1000; - cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, - round(w * scale), - round(h * scale)); + int screen_width, screen_height; + window_get_screen_size(win, &screen_width, &screen_height); - cairo_t *cr = cairo_create(surface); + int width = EVEN(round(screen_width * 0.98 * scale)); + int height = EVEN(round(screen_height * 0.02 * scale)); + cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + + cairo_t *cr = cairo_create(surface); + cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); - cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); - cairo_rectangle(cr, 0, 0, 10000, 10000); + cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); + cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); - cairo_select_font_face(cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size(cr, 50.0); - cairo_set_source_rgb(cr, 0, 0, 0); - cairo_move_to(cr, 50, 50); - cairo_show_text(cr, "Hello, world"); + for (int i = 0; i < 9; i++) + { + cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); + cairo_rectangle(cr, height * i, 0, height, height); + cairo_fill(cr); + + cairo_set_source_rgb(cr, 0.4, 0.4, 0.4); + cairo_set_line_width(cr, 1 * scale); + cairo_rectangle(cr, height * i, 0, height, height); + cairo_stroke(cr); + + cairo_select_font_face(cr, "monospace", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); + cairo_set_font_size(cr, 20.0); + + char btn[] = { '0' + i, '\0' }; + + cairo_text_extents_t te; + cairo_text_extents(cr, btn, &te); + + cairo_move_to(cr, (height * i) + (height / 2) - te.x_bearing - te.width / 2, + (height / 2) - te.y_bearing - te.height / 2); + cairo_show_text(cr, btn); + } + cairo_destroy(cr); - window_paint_surface(win, surface, w, h); + + int x = EVEN((screen_width - width) / 2.0); + int y = EVEN(screen_height * 0.005); + + // TODO: Move these somewhere else + window_move(win, x, y); + window_resize(win, width, height); + + window_paint_surface(win, surface, width, height); cairo_surface_destroy(surface); } @@ -1,7 +1,7 @@ #ifndef COMET_LOG_H #define COMET_LOG_H -#include <stdio.h> +#include <glib.h> #define DEBUG_FORMAT(format, ...) \ "[%s] \x1b[1mdebug\x1b[0m: " format, __func__, ## __VA_ARGS__ @@ -24,6 +24,10 @@ struct Window { cairo_surface_t *surface; cairo_t *cr; double dpi; + uint16_t screen_width; + uint16_t screen_height; + int x, y; + int width, height; }; static xcb_atom_t intern_atom(Window *win, const char *atom) @@ -71,6 +75,12 @@ Window *window_create(void) xcb_randr_screen_size_t *screen_size = xcb_randr_get_screen_info_sizes(info_reply); log_debug("Screen size [width=%d, height=%d]", screen_size->width, screen_size->height); + win->screen_width = screen_size->width; + win->screen_height = screen_size->height; + + win->width = win->height = 0; + win->x = win->y = 0; + xcb_randr_select_input(win->connection, win->window, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE | @@ -131,24 +141,19 @@ found_visual: colormap // colormap }; - int width = screen_size->width * 0.98; - int height = screen_size->height * 0.03; - - width -= width % 2 != 0; - height -= height % 2 != 0; + win->width = win->height = 1; + log_debug("Window (temporary) size [width=%d, height=%d]", win->width, win->height); - log_debug("Window size [width=%d, height=%d]", width, height); - - int x = (screen_size->width - width) / 2.0; - int y = screen_size->height * 0.0125; - - log_debug("Window position [x=%d, y=%d]", x, y); + win->x = win->y = 0; + log_debug("Window (temporary) position [x=%d, y=%d]", win->x, win->y); win->window = xcb_generate_id(win->connection); xcb_create_window(win->connection, XCB_COPY_FROM_PARENT, win->window, win->screen->root, - x, y, width, height, 0, + win->x, win->y, + win->width, win->height, + 0, // border XCB_WINDOW_CLASS_INPUT_OUTPUT, win->screen->root_visual, value_mask, @@ -182,7 +187,12 @@ found_visual: xcb_flush(win->connection); log_debug("Xcb initialized"); - win->surface = cairo_xcb_surface_create(win->connection, win->window, win->visual_type, width, height); + win->surface = cairo_xcb_surface_create(win->connection, + win->window, + win->visual_type, + screen_size->width, + screen_size->height); + assert(cairo_surface_status(win->surface) == CAIRO_STATUS_SUCCESS); win->cr = cairo_create(win->surface); @@ -203,12 +213,47 @@ double window_get_scale(Window *win) return MAX(1, win->dpi/96.); } -void window_paint_surface(Window *win, cairo_surface_t *surface, int width, int height) +void window_get_screen_size(Window *win, int *width, int *height) +{ + *width = win->screen_width; + *height = win->screen_height; +} + +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->connection, + win->window, + XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, + values); + + log_debug("Window (new) position [x=%d, y=%d]", win->x, win->y); +} + +void window_resize(Window *win, int width, int height) { - double scale = window_get_scale(win); + if (win->width == width && win->height == height) return; + + win->width = width; + win->height = height; - cairo_xcb_surface_set_size(win->surface, round(width * scale), round(height * scale)); + const uint32_t values[] = { width, height }; + xcb_configure_window(win->connection, + win->window, + XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, + values); + log_debug("Window (new) size [width=%d, height=%d]", win->width, win->height); +} + +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->connection, false, win->window, 0, 0, 0, 0); cairo_set_source_surface(win->cr, surface, 0, 0); @@ -222,6 +267,7 @@ void window_destroy(Window *win) { cairo_destroy(win->cr); cairo_surface_destroy(win->surface); + xcb_xrm_database_free(win->database); xcb_disconnect(win->connection); g_free(win); @@ -11,6 +11,12 @@ cairo_t *window_get_context(Window *win); double window_get_scale(Window *win); +void window_get_screen_size(Window *win, int *width, int *height); + +void window_move(Window *win, int x, int y); + +void window_resize(Window *win, int width, int height); + void window_paint_surface(Window *win, cairo_surface_t *surface, int width, int height); void window_destroy(Window *win); |
