diff --git a/libc3/window/cairo/c3_window_cairo_demo.c b/libc3/window/cairo/c3_window_cairo_demo.c
index 2badd55..2966c27 100644
--- a/libc3/window/cairo/c3_window_cairo_demo.c
+++ b/libc3/window/cairo/c3_window_cairo_demo.c
@@ -10,14 +10,29 @@
* AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
* THIS SOFTWARE.
*/
+#include <stdio.h>
#include <libc3/c3.h>
#include <cairo/cairo.h>
#include "c3_window_cairo_demo.h"
+#include "types.h"
-bool c3_window_cairo_demo_render (cairo_t *cr)
+bool c3_window_cairo_demo_render (s_window_cairo *window,
+ cairo_t *cr)
{
- cairo_set_source_rgb(cr, 0, 0, 1);
- cairo_rectangle(cr, 20, 20, 100, 100);
+ assert(window);
+ assert(cr);
+ (void) window;
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_rectangle(cr, 0, 0, window->w, window->h);
cairo_fill(cr);
return true;
}
+
+bool c3_window_cairo_demo_resize (s_window_cairo *window,
+ uw w, uw h)
+{
+ assert(window);
+ window->w = w;
+ window->h = h;
+ return true;
+}
diff --git a/libc3/window/cairo/c3_window_cairo_demo.h b/libc3/window/cairo/c3_window_cairo_demo.h
index 86f64ee..358996e 100644
--- a/libc3/window/cairo/c3_window_cairo_demo.h
+++ b/libc3/window/cairo/c3_window_cairo_demo.h
@@ -10,11 +10,13 @@
* AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
* THIS SOFTWARE.
*/
-#ifndef C3_CAIRO_DEMO_H
-#define C3_CAIRO_DEMO_H
+#ifndef C3_WINDOW_CAIRO_DEMO_H
+#define C3_WINDOW_CAIRO_DEMO_H
#include <libc3/types.h>
+#include "types.h"
-bool c3_window_cairo_demo_render (cairo_t *cr);
+bool c3_window_cairo_demo_render (s_window_cairo *window, cairo_t *cr);
+bool c3_window_cairo_demo_resize (s_window_cairo *window, uw w, uw h);
-#endif /* C3_CAIRO_DEMO_H */
+#endif /* C3_WINDOW_CAIRO_DEMO_H */
diff --git a/libc3/window/cairo/types.h b/libc3/window/cairo/types.h
index 9fb9aa7..c4fc4a3 100644
--- a/libc3/window/cairo/types.h
+++ b/libc3/window/cairo/types.h
@@ -25,11 +25,11 @@
typedef struct window_cairo s_window_cairo;
/* return false to break event loop */
-typedef bool (*f_window_cairo_render) (s_cairo_window *window,
+typedef bool (*f_window_cairo_render) (s_window_cairo *window,
cairo_t *cr);
/* return false to break event loop */
-typedef bool (*f_window_cairo_resize) (s_cairo_window *window,
+typedef bool (*f_window_cairo_resize) (s_window_cairo *window,
uw w, uw h);
struct window_cairo {
@@ -38,8 +38,9 @@ struct window_cairo {
sw y;
uw w;
uw h;
- f_cairo_window_render render;
- f_cairo_window_resize resize;
+ const s8 *title;
+ f_window_cairo_render render;
+ f_window_cairo_resize resize;
cairo_t *cr;
};
diff --git a/libc3/window/cairo/window_cairo.c b/libc3/window/cairo/window_cairo.c
new file mode 100644
index 0000000..081d29a
--- /dev/null
+++ b/libc3/window/cairo/window_cairo.c
@@ -0,0 +1,45 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <assert.h>
+#include "window_cairo.h"
+
+s_window_cairo * window_cairo_init (s_window_cairo *window,
+ sw x, sw y, uw w, uw h,
+ const s8 *title)
+{
+ assert(window);
+ window->x = x;
+ window->y = y;
+ window->w = w;
+ window->h = h;
+ window->title = title ? title : "C3.Window.Cairo";
+ window->render = window_cairo_render_default;
+ window->resize = window_cairo_resize_default;
+ window->cr = NULL;
+ return window;
+}
+
+bool window_cairo_render_default (s_window_cairo *window, cairo_t *cr)
+{
+ (void) window;
+ (void) cr;
+ return true;
+}
+
+bool window_cairo_resize_default (s_window_cairo *window, uw w, uw h)
+{
+ (void) window;
+ (void) w;
+ (void) h;
+ return true;
+}
diff --git a/libc3/window/cairo/window_cairo.h b/libc3/window/cairo/window_cairo.h
index 884ac61..6c91351 100644
--- a/libc3/window/cairo/window_cairo.h
+++ b/libc3/window/cairo/window_cairo.h
@@ -15,11 +15,15 @@
#include <libc3/types.h>
#include <cairo/cairo.h>
+#include "types.h"
-typedef bool (*f_window_cairo_render) (cairo_t *cr);
+s_window_cairo * window_cairo_init (s_window_cairo *window,
+ sw x, sw y, uw w, uw h,
+ const s8 *title);
+bool window_cairo_run (s_window_cairo *window);
-bool window_cairo (sw x, sw y, sw w, sw h,
- const s8 *title,
- f_window_cairo_render render);
+/* callbacks */
+bool window_cairo_render_default (s_window_cairo *window, cairo_t *cr);
+bool window_cairo_resize_default (s_window_cairo *window, uw w, uw h);
#endif /* WINDOW_CAIRO_H */
diff --git a/libc3/window/cairo/xcb/configure b/libc3/window/cairo/xcb/configure
index 999181b..dbd8f6f 100755
--- a/libc3/window/cairo/xcb/configure
+++ b/libc3/window/cairo/xcb/configure
@@ -15,7 +15,7 @@ set -e
export SRC_TOP="$(dirname "$PWD")"
-. ../../../config.subr
+. ../../../../config.subr
LIB=libc3_window_cairo_xcb.la
LIB_ASAN=libc3_window_cairo_xcb_asan.la
@@ -39,7 +39,7 @@ LIBS="${LIBS} -rpath ${PREFIX}/lib"
# Common config for all targets
CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic -fPIC"
-CPPFLAGS="$CPPFLAGS -I../../../libffi/include -I../../.."
+CPPFLAGS="$CPPFLAGS -I../../../../libffi/include -I../../../.."
config_asan
config_gnu
pkg_config xcb
@@ -51,24 +51,24 @@ LIBS="$LIBS"
# Address Sanitizer config
CFLAGS_ASAN="$CFLAGS -O1 -fsanitize=address -fno-omit-frame-pointer -g"
LDFLAGS_ASAN="$LDFLAGS"
-LIBS_ASAN="../../../libc3/libc3_asan.la $LIBS"
+LIBS_ASAN="../../../libc3_asan.la $LIBS"
# Coverage config
CFLAGS_COV="$CFLAGS -ftest-coverage -fprofile-arcs -fprofile-generate"
LDFLAGS_COV="$LDFLAGS --coverage"
-LIBS_COV="../../../libc3/libc3_cov.la $LIBS"
+LIBS_COV="../../../libc3_cov.la $LIBS"
# Debug config
CFLAGS_DEBUG="$CFLAGS -DDEBUG -O0 -g"
LDFLAGS_DEBUG="$LDFLAGS"
-LIBS_DEBUG="../../../libc3/libc3_debug.la $LIBS"
+LIBS_DEBUG="../../../libc3_debug.la $LIBS"
# Main config
if [ "x$ENV_CFLAGS" = "x" ]; then
CFLAGS="$CFLAGS $DEFAULT_CFLAGS"
fi
CFLAGS="$CFLAGS -DNDEBUG"
-LIBS="../../../libc3/libc3.la $LIBS"
+LIBS="../../../libc3.la $LIBS"
echo "LIB = $LIB" >> ${CONFIG_MK}
echo "HAVE_ASAN = $HAVE_ASAN" >> ${CONFIG_MK}
diff --git a/libc3/window/cairo/xcb/demo/c3_window_cairo_demo.c b/libc3/window/cairo/xcb/demo/c3_window_cairo_demo.c
new file mode 100644
index 0000000..c609279
--- /dev/null
+++ b/libc3/window/cairo/xcb/demo/c3_window_cairo_demo.c
@@ -0,0 +1,13 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include "../../c3_window_cairo_demo.c"
diff --git a/libc3/window/cairo/xcb/demo/c3_window_cairo_xcb_demo.c b/libc3/window/cairo/xcb/demo/c3_window_cairo_xcb_demo.c
index fe9cf8f..e392615 100644
--- a/libc3/window/cairo/xcb/demo/c3_window_cairo_xcb_demo.c
+++ b/libc3/window/cairo/xcb/demo/c3_window_cairo_xcb_demo.c
@@ -19,9 +19,12 @@
int main ()
{
- if (! window_cairo_xcb(0, 0, 800, 600,
- "C3.Window.Cairo.XCB demo",
- c3_window_cairo_demo_render))
+ s_window_cairo window;
+ window_cairo_init(&window, 0, 0, 800, 600,
+ "C3.Window.Cairo.XCB demo");
+ window.render = c3_window_cairo_demo_render;
+ window.resize = c3_window_cairo_demo_resize;
+ if (! window_cairo_xcb_run(&window))
return 1;
return 0;
}
diff --git a/libc3/window/cairo/xcb/demo/configure b/libc3/window/cairo/xcb/demo/configure
index eadc0fd..bfa00a3 100755
--- a/libc3/window/cairo/xcb/demo/configure
+++ b/libc3/window/cairo/xcb/demo/configure
@@ -15,7 +15,7 @@ set -e
export SRC_TOP="$(dirname "$PWD")"
-. ../../../../config.subr
+. ../../../../../config.subr
PROG=c3_window_cairo_xcb_demo
PROG_ASAN=c3_window_cairo_xcb_demo_asan
@@ -24,7 +24,7 @@ PROG_DEBUG=c3_window_cairo_xcb_demo_debug
. ./sources.sh
-OBJECTS="$(c2lo "$SOURCES")"
+OBJECTS="$(c2ext .main.lo "$SOURCES")"
echo "OBJECTS = $OBJECTS" >> ${CONFIG_MK}
OBJECTS_ASAN="$(c2ext .asan.lo "$SOURCES")"
@@ -47,10 +47,11 @@ LIBS="${LIBS:-}"
# Common config for all targets
CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic"
-CPPFLAGS="$CPPFLAGS -I../../../../libffi/include -I../../../.."
+CPPFLAGS="$CPPFLAGS -I../../../../../libffi/include -I../../../../.."
config_asan
config_gnu
pkg_config xcb
+pkg_config cairo
LIBS="$LIBS"
# Asan config
@@ -118,8 +119,8 @@ echo " ${LIBTOOL} --tag=CC --mode=link \${CC} \${CFLAGS_DEBUG} \${LDFLAGS_DEBUG}
for SRC in $SOURCES; do
echo >> ${CONFIG_MK}
- SRC_LO="$(c2lo "$SRC")"
- lo_rule "$SRC" >> ${CONFIG_MK}
+ SRC_LO="$(c2ext .main.lo "$SRC")"
+ ext_rule .main.lo "$SRC" >> ${CONFIG_MK}
echo " ${LIBTOOL} --tag=CC --mode=compile \${CC} \${CPPFLAGS} \${CFLAGS} -c $SRC -o $SRC_LO" >> ${CONFIG_MK}
echo >> ${CONFIG_MK}
diff --git a/libc3/window/cairo/xcb/demo/sources.mk b/libc3/window/cairo/xcb/demo/sources.mk
index 6de0913..7e42efa 100644
--- a/libc3/window/cairo/xcb/demo/sources.mk
+++ b/libc3/window/cairo/xcb/demo/sources.mk
@@ -1,7 +1,8 @@
# sources.mk generated by update_sources
HEADERS = \
- ../../c3_window_cairo_demo.h \
+ \
SOURCES = \
- c3_window_cairo_xcb_demo.c ../../c3_window_cairo_demo.c \
+ c3_window_cairo_demo.c \
+ c3_window_cairo_xcb_demo.c \
diff --git a/libc3/window/cairo/xcb/demo/sources.sh b/libc3/window/cairo/xcb/demo/sources.sh
index 63623c7..6f38605 100644
--- a/libc3/window/cairo/xcb/demo/sources.sh
+++ b/libc3/window/cairo/xcb/demo/sources.sh
@@ -1,3 +1,3 @@
# sources.sh generated by update_sources
-HEADERS=' ../../c3_window_cairo_demo.h '
-SOURCES='c3_window_cairo_xcb_demo.c ../../c3_window_cairo_demo.c '
+HEADERS=' '
+SOURCES='c3_window_cairo_demo.c c3_window_cairo_xcb_demo.c '
diff --git a/libc3/window/cairo/xcb/demo/update_sources b/libc3/window/cairo/xcb/demo/update_sources
index 40521c4..eab00d6 100755
--- a/libc3/window/cairo/xcb/demo/update_sources
+++ b/libc3/window/cairo/xcb/demo/update_sources
@@ -11,15 +11,15 @@
## AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
## THIS SOFTWARE.
-. ../../../../config.subr
+. ../../../../../config.subr
echo "# sources.mk generated by update_sources" > ${SOURCES_MK}
echo "# sources.sh generated by update_sources" > ${SOURCES_SH}
-HEADERS="$(ls *.h | sort) ../../c3_window_cairo_demo.h"
+HEADERS="$(ls *.h | sort)"
sources HEADERS "$HEADERS"
-SOURCES="$(ls *.c | sort) ../../c3_window_cairo_demo.c"
+SOURCES="$(ls *.c | sort)"
sources SOURCES "$SOURCES"
update_sources_mk
diff --git a/libc3/window/cairo/xcb/sources.mk b/libc3/window/cairo/xcb/sources.mk
index 5a5f114..4d93565 100644
--- a/libc3/window/cairo/xcb/sources.mk
+++ b/libc3/window/cairo/xcb/sources.mk
@@ -4,5 +4,5 @@ HEADERS = \
window_cairo_xcb.h ../window_cairo.h \
SOURCES = \
- window_cairo_xcb.c \
+ window_cairo_xcb.c ../window_cairo.c \
diff --git a/libc3/window/cairo/xcb/sources.sh b/libc3/window/cairo/xcb/sources.sh
index 82c629f..0c8c926 100644
--- a/libc3/window/cairo/xcb/sources.sh
+++ b/libc3/window/cairo/xcb/sources.sh
@@ -1,3 +1,3 @@
# sources.sh generated by update_sources
HEADERS='config.h window_cairo_xcb.h ../window_cairo.h '
-SOURCES='window_cairo_xcb.c '
+SOURCES='window_cairo_xcb.c ../window_cairo.c '
diff --git a/libc3/window/cairo/xcb/update_sources b/libc3/window/cairo/xcb/update_sources
index e2e45b4..af50eab 100755
--- a/libc3/window/cairo/xcb/update_sources
+++ b/libc3/window/cairo/xcb/update_sources
@@ -11,7 +11,7 @@
## AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
## THIS SOFTWARE.
-. ../../../config.subr
+. ../../../../config.subr
echo "# sources.mk generated by update_sources" > ${SOURCES_MK}
echo "# sources.sh generated by update_sources" > ${SOURCES_SH}
@@ -19,7 +19,7 @@ echo "# sources.sh generated by update_sources" > ${SOURCES_SH}
HEADERS="$(ls *.h | sort) ../window_cairo.h"
sources HEADERS "$HEADERS"
-SOURCES="$(ls *.c | sort)"
+SOURCES="$(ls *.c | sort) ../window_cairo.c"
sources SOURCES "$SOURCES"
update_sources_mk
diff --git a/libc3/window/cairo/xcb/window_cairo_xcb.c b/libc3/window/cairo/xcb/window_cairo_xcb.c
index c395bf2..9e0fb4d 100644
--- a/libc3/window/cairo/xcb/window_cairo_xcb.c
+++ b/libc3/window/cairo/xcb/window_cairo_xcb.c
@@ -17,25 +17,20 @@
#include <xcb/xcb.h>
#include "window_cairo_xcb.h"
-bool window_cairo (sw x, sw y, sw w, sw h,
- const s8 *title,
- f_window_cairo_render render
- f_window_cairo_resize resize)
+bool window_cairo_run (s_window_cairo *window)
{
- return window_cairo_xcb(x, y, w, h, title, render, resize);
+ return window_cairo_xcb_run(window);
}
-bool window_cairo_xcb (sw x, sw y, sw w, sw h,
- const s8 *title,
- f_window_cairo_render render,
- f_window_cairo_resize resize)
+bool window_cairo_xcb_run (s_window_cairo *window)
{
+ xcb_configure_notify_event_t *configure_event;
xcb_connection_t *conn;
cairo_t *cr;
xcb_screen_t *screen;
xcb_visualtype_t *screen_visual;
cairo_surface_t *surface;
- xcb_window_t window;
+ xcb_window_t xcb_window;
xcb_generic_event_t *event;
conn = xcb_connect(NULL, NULL);
if (xcb_connection_has_error(conn)) {
@@ -44,30 +39,53 @@ bool window_cairo_xcb (sw x, sw y, sw w, sw h,
}
screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
screen_visual = xcb_screen_visual_type(screen);
- window = xcb_generate_id(conn);
- xcb_create_window(conn, XCB_COPY_FROM_PARENT, window, screen->root, x, y, w, h, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, 0, NULL);
- xcb_change_property(conn, XCB_PROP_MODE_REPLACE, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, 12, title);
- xcb_map_window(conn, window);
+ xcb_window = xcb_generate_id(conn);
+ uint32_t value_mask = XCB_CW_EVENT_MASK;
+ uint32_t value_list[1] = {XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY};
+ xcb_create_window(conn, XCB_COPY_FROM_PARENT, xcb_window, screen->root,
+ window->x, window->y, window->w, window->h, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ screen->root_visual,
+ value_mask, value_list);
+ xcb_change_property(conn, XCB_PROP_MODE_REPLACE, xcb_window,
+ XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, 12,
+ window->title);
+ xcb_map_window(conn, xcb_window);
xcb_flush(conn);
- surface = cairo_xcb_surface_create(conn, window, screen_visual, 800, 600);
+ surface = cairo_xcb_surface_create(conn, xcb_window, screen_visual, 800, 600);
cr = cairo_create(surface);
- if (render(cr)) {
+ window->cr = cr;
+ if (window->render(window, cr)) {
cairo_surface_flush(surface);
xcb_flush(conn);
while ((event = xcb_wait_for_event(conn))) {
- if ((event->response_type & ~0x80) == XCB_EXPOSE) {
- if (! render(cr))
- break;
+ switch (event->response_type & ~0x80) {
+ case XCB_EXPOSE:
+ if (! window->render(window, cr)) {
+ free(event);
+ goto exit_loop;
+ }
cairo_surface_flush(surface);
- xcb_flush(conn);
+ break;
+ case XCB_CONFIGURE_NOTIFY:
+ configure_event = (xcb_configure_notify_event_t *) event;
+ cairo_xcb_surface_set_size(surface, configure_event->width, configure_event->height);
+ if (! window->resize(window, configure_event->width,
+ configure_event->height)) {
+ free(event);
+ goto exit_loop;
+ }
+ break;
}
free(event);
+ xcb_flush(conn);
}
}
+ exit_loop:
cairo_destroy(cr);
cairo_surface_destroy(surface);
xcb_disconnect(conn);
- return 0;
+ return true;
}
xcb_visualtype_t * xcb_screen_visual_type (xcb_screen_t *screen)
diff --git a/libc3/window/cairo/xcb/window_cairo_xcb.h b/libc3/window/cairo/xcb/window_cairo_xcb.h
index ce601dc..6e5a1b6 100644
--- a/libc3/window/cairo/xcb/window_cairo_xcb.h
+++ b/libc3/window/cairo/xcb/window_cairo_xcb.h
@@ -15,11 +15,10 @@
#include <libc3/types.h>
#include <xcb/xcb.h>
+#include "../types.h"
#include "../window_cairo.h"
-bool window_cairo_xcb (sw x, sw y, sw w, sw h,
- const s8 *title,
- f_window_cairo_render render);
+bool window_cairo_xcb_run (s_window_cairo *window);
xcb_visualtype_t * xcb_screen_visual_type (xcb_screen_t *screen);
diff --git a/libc3/window/types.h b/libc3/window/types.h
index 3644829..ab0dcaa 100644
--- a/libc3/window/types.h
+++ b/libc3/window/types.h
@@ -35,6 +35,7 @@ struct window {
sw y;
uw w;
uw h;
+ const s8 *title;
f_window_render render;
f_window_resize resize;
void *render_context;