Author | Jakob Wakeling <[email protected]> |
Date | 2024-03-10 10:32:36 |
Commit | 0db58180873b28d900e54d2db51566fcc05ab1d5 |
Parent | 345d96ccfc7061d28302d386dcee06bbac35fd53 |
Use a 32 bit pixel depth instead of 24
Diffstat
M | examples/draw.c | | | 20 | ++++++++++---------- |
M | src/x11/draw.c | | | 71 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- |
2 files changed, 72 insertions, 19 deletions
diff --git a/examples/draw.c b/examples/draw.c index 623e0f0..47b7289 100644 --- a/examples/draw.c +++ b/examples/draw.c @@ -3,19 +3,19 @@ int main() { draw_debug = true; draw_window *window; int32_t w = 800, h = 600; - draw_window_init(&window, w, h, "Draw", 0); + if (draw_window_init(&window, w, h, "Draw", 0) == -1) { return -1; } bool left = false, right = false, draw = false; - uint32_t colour = 0x00ff0000; + uint32_t colour = 0xffff0000; draw_buffer *buf = draw_buffer_init(w, h); - draw_buffer_clear(buf, 0x00000000); + draw_buffer_clear(buf, 0xff000000); for (draw_event e; (e = draw_window_event(window)).kind != DRAW_EVENT_EXIT;) switch (e.kind) { case DRAW_EVENT_KEY: { - if (e.key.code == DRAW_KEY_1) { colour = 0x00ff0000; } - if (e.key.code == DRAW_KEY_2) { colour = 0x0000ff00; } - if (e.key.code == DRAW_KEY_3) { colour = 0x000000ff; } + if (e.key.code == DRAW_KEY_1) { colour = 0xffff0000; } + if (e.key.code == DRAW_KEY_2) { colour = 0xff00ff00; } + if (e.key.code == DRAW_KEY_3) { colour = 0xff0000ff; } } break; case DRAW_EVENT_MOUSE: { if (e.mouse.button == DRAW_MOUSE_LEFT) { @@ -28,10 +28,10 @@ int main() { } if (left) { draw_buffer_rect(buf, (point){e.mouse.x, e.mouse.y}, (rect){-5, -5, 6, 6}, colour); } - if (right) { draw_buffer_rect(buf, (point){e.mouse.x, e.mouse.y}, (rect){-5, -5, 6, 6}, 0x00000000); } - if ((left || right) && !draw) { draw_window_repaint(window); } + if (right) { draw_buffer_rect(buf, (point){e.mouse.x, e.mouse.y}, (rect){-5, -5, 6, 6}, 0xff000000); } + if ((left || right) && !draw) { goto redraw; /*draw_window_repaint(window);*/ } } break; - case DRAW_EVENT_PAINT: { + case DRAW_EVENT_PAINT: redraw: { draw_window_draw(window, (point){0, 0}, buf, buf->bounds); draw = false; } break; case DRAW_EVENT_RESIZE: { @@ -39,7 +39,7 @@ int main() { draw_buffer *old = buf; buf = draw_buffer_init(w, h); - draw_buffer_clear(buf, 0x00000000); + draw_buffer_clear(buf, 0xff000000); draw_buffer_copy(buf, old, (point){0, 0}, old->bounds); draw_buffer_free(&old); } break; diff --git a/src/x11/draw.c b/src/x11/draw.c index bbe3365..d1607db 100644 --- a/src/x11/draw.c +++ b/src/x11/draw.c @@ -8,8 +8,9 @@ #include <xcb/xproto.h> #include <stdint.h> -#include <stdlib.h> #include <stdio.h> +#include <stdlib.h> +#include <string.h> enum : xcb_atom_t { ATOM_REPAINT = 0x0f00, @@ -38,21 +39,68 @@ int draw_window_init(draw_window **window, int32_t w, int32_t h, const char *tit (*window)->connection = xcb_connect(NULL, NULL); if (xcb_connection_has_error((*window)->connection)) { return -1; } + xcb_void_cookie_t cookie; + xcb_generic_error_t *error = NULL; + (*window)->screen = xcb_setup_roots_iterator(xcb_get_setup((*window)->connection)).data; (*window)->window = xcb_generate_id((*window)->connection); if ((*window)->window == -1) { xcb_disconnect((*window)->connection); return -1; } - uint32_t mask = XCB_CW_EVENT_MASK; - uint32_t values[1] = { + uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; + uint32_t values[4] = { + 0xff000000, 0, XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_BUTTON_MOTION }; - xcb_create_window( - (*window)->connection, XCB_COPY_FROM_PARENT, (*window)->window, (*window)->screen->root, 0, 0, w, h, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, (*window)->screen->root_visual, mask, values + /**/ + xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator((*window)->screen); + xcb_visualtype_t *visual = NULL; + + for (; depth_iter.rem; xcb_depth_next(&depth_iter)) { + if (depth_iter.data->depth != 32) continue; + xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(depth_iter.data); + for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) { + visual = visual_iter.data; + break; + } + if (visual != NULL) break; + } + + if (visual == NULL) { xcb_disconnect((*window)->connection); return -1; } + + xcb_colormap_t colormap = xcb_generate_id((*window)->connection); + cookie = xcb_create_colormap( + (*window)->connection, XCB_COLORMAP_ALLOC_NONE, colormap, (*window)->screen->root, visual->visual_id + ); + error = xcb_request_check((*window)->connection, cookie); + if (error != NULL) { + printf("Error %d while creating colormap\n", error->error_code); + free(error); xcb_disconnect((*window)->connection); return -1; + } + + values[3] = colormap; + + cookie = xcb_create_window_checked( + (*window)->connection, 32, (*window)->window, (*window)->screen->root, 0, 0, w, h, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, visual->visual_id, mask, values + ); + error = xcb_request_check((*window)->connection, cookie); + if (error != NULL) { + printf("Error %d while creating window\n", error->error_code); + free(error); xcb_disconnect((*window)->connection); return -1; + } + + xcb_change_property( + (*window)->connection, XCB_PROP_MODE_REPLACE, (*window)->window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, + strlen(title), title + ); + + xcb_change_property( + (*window)->connection, XCB_PROP_MODE_REPLACE, (*window)->window, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, + strlen("libdraw"), "libdraw" ); (*window)->symbols = xcb_key_symbols_alloc((*window)->connection); @@ -140,7 +188,13 @@ draw_event draw_window_event(draw_window *window) { } break; } } break; - default: { if (draw_debug) { printf("Unhandled X11 event: %d\n", _e->response_type & ~0x80); }} break; + default: { if (draw_debug) { + printf("Unhandled X11 event: %d ", _e->response_type & ~0x80); + printf("Sequence: %u ", _e->sequence); + printf("Full sequence: %u ", _e->full_sequence); + printf("Pad0: %u ", _e->pad0); + printf("Pad: %u\n", *_e->pad); + }} break; } free(_e); return event; @@ -161,10 +215,9 @@ int draw_window_draw(draw_window *w, point dp, draw_buffer *buf, rect br) { xcb_gcontext_t gc = xcb_generate_id(w->connection); - xcb_create_gc(w->connection, gc, w->window, 0, NULL); xcb_put_image( - w->connection, XCB_IMAGE_FORMAT_Z_PIXMAP, w->window, gc, br.w, br.h, dp.x, dp.y, 0, 24, + w->connection, XCB_IMAGE_FORMAT_Z_PIXMAP, w->window, gc, br.w, br.h, dp.x, dp.y, 0, 32, (buf->bounds.w * buf->bounds.h) * sizeof (*buf->buf), (uint8_t *)buf->buf ); xcb_free_gc(w->connection, gc);