diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index acc1374..cb69aec 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -2384,6 +2384,34 @@ sw buf_parse_sym (s_buf *buf, const s_sym **dest)
return r;
}
+sw buf_parse_sym_str (s_buf *buf, s_str *str)
+{
+ character c = 0;
+ sw csize;
+ sw r;
+ sw result = 0;
+ s_buf_save save;
+ s8 t[SYM_MAX];
+ s_buf tmp;
+ buf_save_init(buf, &save);
+ buf_init(&tmp, false, sizeof(t), t);
+ while ((r = buf_peek_character_utf8(buf, &c)) > 0 &&
+ ! sym_character_is_reserved(c)) {
+ csize = r;
+ if ((r = buf_xfer(&tmp, buf, csize)) < 0)
+ goto restore;
+ result += csize;
+ }
+ buf_read_to_str(&tmp, str);
+ r = result;
+ goto clean;
+ restore:
+ buf_save_restore_rpos(buf, &save);
+ clean:
+ buf_save_clean(buf, &save);
+ return r;
+}
+
sw buf_parse_tag (s_buf *buf, s_tag *dest)
{
sw r;
diff --git a/libc3/buf_parse.h b/libc3/buf_parse.h
index 184c99f..8257f64 100644
--- a/libc3/buf_parse.h
+++ b/libc3/buf_parse.h
@@ -92,6 +92,7 @@ sw buf_parse_str_character (s_buf *buf, character *dest);
sw buf_parse_str_character_unicode (s_buf *buf, character *dest);
sw buf_parse_str_u8 (s_buf *buf, u8 *dest);
sw buf_parse_sym (s_buf *buf, const s_sym **dest);
+sw buf_parse_sym_str (s_buf *buf, s_str *dest);
sw buf_parse_tag (s_buf *buf, s_tag *dest);
sw buf_parse_tag_array (s_buf *buf, s_tag *dest);
sw buf_parse_tag_bool (s_buf *buf, s_tag *dest);
diff --git a/libc3/window/cairo/types.h b/libc3/window/cairo/types.h
index 664766b..2818b97 100644
--- a/libc3/window/cairo/types.h
+++ b/libc3/window/cairo/types.h
@@ -35,6 +35,10 @@ typedef bool (*f_window_cairo_key) (s_window_cairo *window, uw key);
typedef bool (*f_window_cairo_load) (s_window_cairo *window);
/* return false to break event loop */
+typedef bool (*f_window_cairo_motion) (s_window_cairo *window, sw x,
+ sw y);
+
+/* return false to break event loop */
typedef bool (*f_window_cairo_render) (s_window_cairo *window,
cairo_t *cr);
@@ -51,6 +55,7 @@ struct window_cairo {
f_window_cairo_button button;
f_window_cairo_key key;
f_window_cairo_load load;
+ f_window_cairo_motion motion;
f_window_cairo_render render;
cairo_t *cr;
f_window_cairo_resize resize;
diff --git a/libc3/window/cairo/window_cairo.c b/libc3/window/cairo/window_cairo.c
index 46d3fb4..d5668d8 100644
--- a/libc3/window/cairo/window_cairo.c
+++ b/libc3/window/cairo/window_cairo.c
@@ -27,6 +27,7 @@ s_window_cairo * window_cairo_init (s_window_cairo *window,
window->button = window_cairo_button_default;
window->key = window_cairo_key_default;
window->load = window_cairo_load_default;
+ window->motion = window_cairo_motion_default;
window->render = window_cairo_render_default;
window->resize = window_cairo_resize_default;
window->cr = NULL;
@@ -66,6 +67,14 @@ bool window_cairo_load_default (s_window_cairo *window)
return true;
}
+bool window_cairo_motion_default (s_window_cairo *window, sw x, sw y)
+{
+ assert(window);
+ (void) window;
+ printf("window_cairo_motion_default (%ld, %ld)\n", x, y);
+ return true;
+}
+
bool window_cairo_render_default (s_window_cairo *window, cairo_t *cr)
{
assert(window);
diff --git a/libc3/window/cairo/window_cairo.h b/libc3/window/cairo/window_cairo.h
index 85b89b7..16fd040 100644
--- a/libc3/window/cairo/window_cairo.h
+++ b/libc3/window/cairo/window_cairo.h
@@ -28,6 +28,7 @@ bool window_cairo_button_default (s_window_cairo *window, u8 button,
sw x, sw y);
bool window_cairo_key_default (s_window_cairo *window, uw key);
bool window_cairo_load_default (s_window_cairo *window);
+bool window_cairo_motion_default (s_window_cairo *window, sw x, sw y);
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);
diff --git a/libc3/window/cairo/xcb/window_cairo_xcb.c b/libc3/window/cairo/xcb/window_cairo_xcb.c
index 529207a..489451a 100644
--- a/libc3/window/cairo/xcb/window_cairo_xcb.c
+++ b/libc3/window/cairo/xcb/window_cairo_xcb.c
@@ -37,16 +37,12 @@ bool window_cairo_xcb_event (s_window_cairo *window,
event_button = (xcb_button_press_event_t *) event;
if (! window->button(window, event_button->detail,
event_button->event_x,
- event_button->event_y)) {
- free(event);
- return false;
- }
+ event_button->event_y))
+ goto ko;
break;
case XCB_EXPOSE:
- if (! window->render(window, cr)) {
- free(event);
- return false;
- }
+ if (! window->render(window, cr))
+ goto ko;
cairo_surface_flush(surface);
xcb_flush(conn);
break;
@@ -55,29 +51,30 @@ bool window_cairo_xcb_event (s_window_cairo *window,
cairo_xcb_surface_set_size(surface, event_config->width,
event_config->height);
if (! window->resize(window, event_config->width,
- event_config->height)) {
- free(event);
- return false;
- }
+ event_config->height))
+ goto ko;
window->w = event_config->width;
window->h = event_config->height;
break;
case XCB_KEY_PRESS:
event_key = (xcb_key_press_event_t *) event;
- if (! window->key(window, event_key->detail)) {
- free(event);
- return false;
- }
+ if (! window->key(window, event_key->detail))
+ goto ko;
break;
case XCB_MOTION_NOTIFY:
event_motion = (xcb_motion_notify_event_t *) event;
if (! window->motion(window, event_motion->event_x,
- event_motion->event_y)
+ event_motion->event_y))
+ goto ko;
+ break;
default:
printf("event type %d\n", event->response_type & ~0x80);
}
free(event);
return true;
+ ko:
+ free(event);
+ return false;
}
bool window_cairo_xcb_run (s_window_cairo *window)
diff --git a/libc3/window/types.h b/libc3/window/types.h
index 8e3e283..c75be2f 100644
--- a/libc3/window/types.h
+++ b/libc3/window/types.h
@@ -33,6 +33,9 @@ typedef bool (*f_window_key) (s_window *window, uw key);
typedef bool (*f_window_load) (s_window *window);
/* return false to break event loop */
+typedef bool (*f_window_motion) (s_window *window, sw x, sw y);
+
+/* return false to break event loop */
typedef bool (*f_window_render) (s_window *window,
void *render_context);
@@ -52,6 +55,7 @@ struct window {
f_window_button button;
f_window_key key;
f_window_load load;
+ f_window_motion motion;
f_window_render render;
void *render_context;
f_window_resize resize;