diff options
| -rw-r--r-- | .gitignore | 4 | ||||
| -rw-r--r-- | Makefile | 22 | ||||
| -rw-r--r--[-rwxr-xr-x] | README | 0 | ||||
| -rw-r--r-- | comet.c | 18 | ||||
| -rw-r--r-- | draw.c | 34 | ||||
| -rw-r--r-- | draw.h | 10 | ||||
| -rw-r--r-- | x11.c | 114 | ||||
| -rw-r--r-- | x11.h | 20 |
8 files changed, 222 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5abeb24 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +*.old +*.swp +*.bin diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..288a9ea --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +SRC = $(wildcard *.c) +OBJ = $(SRC:.c=.o) +BIN = comet.bin + +DEPS = cairo \ + xcb \ + xcb-icccm \ + xcb-xrm \ + glib-2.0 +CFLAGS := $(shell pkgconf --cflags $(DEPS)) +LDFLAGS := $(shell pkgconf --libs $(DEPS)) -lm + +all: $(BIN) + +$(BIN): $(OBJ) + $(CC) -o $@ $(LDFLAGS) $^ + +%.o: %.c + $(CC) -o $@ -c $(CFLAGS) $^ + +clean: + rm -rf $(BIN) $(OBJ) @@ -0,0 +1,18 @@ +#include <glib.h> +#include <glib-unix.h> + +#include "x11.h" +#include "draw.h" + +int main(int argc, char **argv) +{ + Window *win = window_create(); + + draw(win); + sleep(10); + + window_destroy(win); + return 0; +} + +// vim: set ts=4 sw=4 et @@ -0,0 +1,34 @@ +#include <stdbool.h> +#include <math.h> +#include <cairo.h> + +#include "x11.h" + +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)); + + cairo_t *cr = cairo_create(surface); + + + cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); + cairo_rectangle(cr, 0, 0, 10000, 10000); + 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"); + + cairo_destroy(cr); + window_paint_surface(win, surface, w, h); + cairo_surface_destroy(surface); +} + +// vim: set ts=4 sw=4 et @@ -0,0 +1,10 @@ +#ifndef COMET_DRAW_H +#define COMET_DRAW_H + +#include "x11.h" + +void draw(Window *win); + +#endif + +// vim: set ts=4 sw=4 et @@ -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 @@ -0,0 +1,20 @@ +#ifndef COMET_X11_H +#define COMET_X11_H + +#include <cairo.h> + +typedef struct Window Window; + +Window *window_create(void); + +cairo_t *window_get_context(Window *win); + +double window_get_scale(Window *win); + +void window_paint_surface(Window *win, cairo_surface_t *surface, int width, int height); + +void window_destroy(Window *win); + +#endif + +// vim: set ts=4 sw=4 et |
