diff --git a/cogl/cogl-onscreen-private.h b/cogl/cogl-onscreen-private.h index 7fc601939..2ac89911f 100644 --- a/cogl/cogl-onscreen-private.h +++ b/cogl/cogl-onscreen-private.h @@ -46,17 +46,16 @@ struct _CoglFrameClosure CoglUserDataDestroyCallback destroy; }; -typedef struct _CoglResizeNotifyEntry CoglResizeNotifyEntry; +COGL_TAILQ_HEAD (CoglOnscreenResizeCallbackList, CoglOnscreenResizeClosure); -COGL_TAILQ_HEAD (CoglResizeNotifyList, CoglResizeNotifyEntry); - -struct _CoglResizeNotifyEntry +struct _CoglOnscreenResizeClosure { - COGL_TAILQ_ENTRY (CoglResizeNotifyEntry) list_node; + COGL_TAILQ_ENTRY (CoglOnscreenResizeClosure) list_node; CoglOnscreenResizeCallback callback; + void *user_data; - unsigned int id; + CoglUserDataDestroyCallback destroy; }; typedef struct _CoglOnscreenEvent CoglOnscreenEvent; @@ -95,7 +94,7 @@ struct _CoglOnscreen CoglFrameCallbackList frame_closures; CoglBool resizable; - CoglResizeNotifyList resize_callbacks; + CoglOnscreenResizeCallbackList resize_closures; int64_t frame_counter; int64_t swap_frame_counter; /* frame counter at last all to diff --git a/cogl/cogl-onscreen.c b/cogl/cogl-onscreen.c index 23f62bac0..6175db70f 100644 --- a/cogl/cogl-onscreen.c +++ b/cogl/cogl-onscreen.c @@ -47,7 +47,7 @@ _cogl_onscreen_init_from_template (CoglOnscreen *onscreen, CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); COGL_TAILQ_INIT (&onscreen->frame_closures); - COGL_TAILQ_INIT (&onscreen->resize_callbacks); + COGL_TAILQ_INIT (&onscreen->resize_closures); framebuffer->config = onscreen_template->config; cogl_object_ref (framebuffer->config.swap_chain); @@ -115,24 +115,20 @@ _cogl_onscreen_free (CoglOnscreen *onscreen) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); - CoglResizeNotifyEntry *resize_entry; - CoglFrameClosure *frame_closure; CoglFrameInfo *frame_info; - while ((resize_entry = COGL_TAILQ_FIRST (&onscreen->resize_callbacks))) + while (!COGL_TAILQ_EMPTY (&onscreen->resize_closures)) { - COGL_TAILQ_REMOVE (&onscreen->resize_callbacks, resize_entry, list_node); - g_slice_free (CoglResizeNotifyEntry, resize_entry); + CoglOnscreenResizeClosure *resize_closure = + COGL_TAILQ_FIRST (&onscreen->resize_closures); + cogl_onscreen_remove_resize_callback (onscreen, resize_closure); } - while ((frame_closure = COGL_TAILQ_FIRST (&onscreen->frame_closures))) + while (!COGL_TAILQ_EMPTY (&onscreen->frame_closures)) { - COGL_TAILQ_REMOVE (&onscreen->frame_closures, frame_closure, list_node); - - if (frame_closure->destroy) - frame_closure->destroy (frame_closure->user_data); - - g_slice_free (CoglFrameClosure, frame_closure); + CoglFrameClosure *frame_closure = + COGL_TAILQ_FIRST (&onscreen->frame_closures); + cogl_onscreen_remove_frame_callback (onscreen, frame_closure); } while ((frame_info = g_queue_pop_tail (&onscreen->pending_frame_infos))) @@ -566,17 +562,17 @@ _cogl_onscreen_notify_complete (CoglOnscreen *onscreen, CoglFrameInfo *info) void _cogl_onscreen_notify_resize (CoglOnscreen *onscreen) { - CoglResizeNotifyEntry *entry, *tmp; + CoglOnscreenResizeClosure *closure, *tmp; CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - COGL_TAILQ_FOREACH_SAFE (entry, - &onscreen->resize_callbacks, + COGL_TAILQ_FOREACH_SAFE (closure, + &onscreen->resize_closures, list_node, tmp) - entry->callback (onscreen, - framebuffer->width, - framebuffer->height, - entry->user_data); + closure->callback (onscreen, + framebuffer->width, + framebuffer->height, + closure->user_data); } void @@ -620,38 +616,33 @@ cogl_onscreen_get_resizable (CoglOnscreen *onscreen) return onscreen->resizable; } -unsigned int -cogl_onscreen_add_resize_handler (CoglOnscreen *onscreen, - CoglOnscreenResizeCallback callback, - void *user_data) +CoglOnscreenResizeClosure * +cogl_onscreen_add_resize_callback (CoglOnscreen *onscreen, + CoglOnscreenResizeCallback callback, + void *user_data, + CoglUserDataDestroyCallback destroy) { - CoglResizeNotifyEntry *entry = g_slice_new (CoglResizeNotifyEntry); - static int next_resize_callback_id = 0; + CoglOnscreenResizeClosure *closure = g_slice_new (CoglOnscreenResizeClosure); - entry->callback = callback; - entry->user_data = user_data; - entry->id = next_resize_callback_id++; + closure->callback = callback; + closure->user_data = user_data; + closure->destroy = destroy; - COGL_TAILQ_INSERT_TAIL (&onscreen->resize_callbacks, entry, list_node); + COGL_TAILQ_INSERT_TAIL (&onscreen->resize_closures, closure, list_node); - return entry->id; + return closure; } void -cogl_onscreen_remove_resize_handler (CoglOnscreen *onscreen, - unsigned int id) +cogl_onscreen_remove_resize_callback (CoglOnscreen *onscreen, + CoglOnscreenResizeClosure *closure) { - CoglResizeNotifyEntry *entry; + if (closure->destroy) + closure->destroy (closure->user_data); - COGL_TAILQ_FOREACH (entry, &onscreen->resize_callbacks, list_node) - { - if (entry->id == id) - { - COGL_TAILQ_REMOVE (&onscreen->resize_callbacks, entry, list_node); - g_slice_free (CoglResizeNotifyEntry, entry); - break; - } - } + COGL_TAILQ_REMOVE (&onscreen->resize_closures, closure, list_node); + + g_slice_free (CoglOnscreenResizeClosure, closure); } int64_t diff --git a/cogl/cogl-onscreen.h b/cogl/cogl-onscreen.h index cf2f85d96..8b7973f3c 100644 --- a/cogl/cogl-onscreen.h +++ b/cogl/cogl-onscreen.h @@ -614,7 +614,7 @@ cogl_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, * will be automatically updated to match the new size of the * framebuffer with an origin of (0,0). If your application needs more * specialized control of the viewport it will need to register a - * resize handler using cogl_onscreen_add_resize_handler() so that it + * resize handler using cogl_onscreen_add_resize_callback() so that it * can track when the viewport has been changed automatically. * * Since: 2.0 @@ -655,10 +655,10 @@ cogl_onscreen_get_resizable (CoglOnscreen *onscreen); * @width: The new width of @onscreen * @height: The new height of @onscreen * @user_data: The private passed to - * cogl_onscreen_add_resize_handler() + * cogl_onscreen_add_resize_callback() * * Is a callback type used with the - * cogl_onscreen_add_resize_handler() allowing applications to be + * cogl_onscreen_add_resize_callback() allowing applications to be * notified whenever an @onscreen framebuffer is resized. * * Cogl automatically updates the viewport of an @onscreen @@ -679,18 +679,34 @@ typedef void (*CoglOnscreenResizeCallback) (CoglOnscreen *onscreen, void *user_data); /** - * cogl_onscreen_add_resize_handler: + * CoglOnscreenResizeClosure: + * + * An opaque type that tracks a #CoglOnscreenResizeCallback and + * associated user data. A #CoglOnscreenResizeClosure pointer will be + * returned from cogl_onscreen_add_resize_callback() and it allows you + * to remove a callback later using + * cogl_onscreen_remove_resize_callback(). + * + * Since: 2.0 + * Stability: unstable + */ +typedef struct _CoglOnscreenResizeClosure CoglOnscreenResizeClosure; + +/** + * cogl_onscreen_add_resize_callback: * @onscreen: A #CoglOnscreen framebuffer * @callback: A #CoglOnscreenResizeCallback to call when the @onscreen * changes size. * @user_data: Private data to be passed to @callback. + * @destroy: An optional callback to destroy @user_data when the + * @callback is removed or @onscreen is freed. * * Registers a @callback with @onscreen that will be called whenever * the @onscreen framebuffer changes size. * * The @callback can be removed using - * cogl_onscreen_remove_resize_handler() passing the same @callback - * and @user_data pair. + * cogl_onscreen_remove_resize_callback() passing the returned closure + * pointer. * * Since Cogl automatically updates the viewport of an @onscreen * framebuffer that is resized, a resize callback can also be used to @@ -704,29 +720,29 @@ typedef void (*CoglOnscreenResizeCallback) (CoglOnscreen *onscreen, * while an application might have arbitrary locks held for * example. * - * Return value: a unique identifier that can be used to remove to remove - * the callback later. - * + * Return value: a #CoglOnscreenResizeClosure pointer that can be used to + * remove the callback and associated @user_data later. * Since: 2.0 */ -unsigned int -cogl_onscreen_add_resize_handler (CoglOnscreen *onscreen, - CoglOnscreenResizeCallback callback, - void *user_data); +CoglOnscreenResizeClosure * +cogl_onscreen_add_resize_callback (CoglOnscreen *onscreen, + CoglOnscreenResizeCallback callback, + void *user_data, + CoglUserDataDestroyCallback destroy); /** - * cogl_onscreen_remove_resize_handler: + * cogl_onscreen_remove_resize_callback: * @onscreen: A #CoglOnscreen framebuffer - * @id: An identifier returned from cogl_onscreen_add_resize_handler() + * @closure: An identifier returned from cogl_onscreen_add_resize_callback() * * Removes a resize @callback and @user_data pair that were previously - * associated with @onscreen via cogl_onscreen_add_resize_handler(). + * associated with @onscreen via cogl_onscreen_add_resize_callback(). * * Since: 2.0 */ void -cogl_onscreen_remove_resize_handler (CoglOnscreen *onscreen, - unsigned int id); +cogl_onscreen_remove_resize_callback (CoglOnscreen *onscreen, + CoglOnscreenResizeClosure *closure); /** * cogl_is_onscreen: diff --git a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt index daead2c59..b923fd02f 100644 --- a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt +++ b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt @@ -609,6 +609,12 @@ CoglFrameClosure cogl_onscreen_add_frame_callback cogl_onscreen_remove_frame_callback + +CoglOnscreenResizeCallback +CoglOnscreenResizeClosure +cogl_onscreen_add_resize_callback +cogl_onscreen_remove_resize_callback + cogl_onscreen_swap_buffers cogl_onscreen_swap_region diff --git a/examples/cogl-x11-foreign.c b/examples/cogl-x11-foreign.c index a60397cd4..e9ac93d96 100644 --- a/examples/cogl-x11-foreign.c +++ b/examples/cogl-x11-foreign.c @@ -160,7 +160,7 @@ main (int argc, char **argv) fb = COGL_FRAMEBUFFER (onscreen); cogl_onscreen_set_resizable (onscreen, TRUE); - cogl_onscreen_add_resize_handler (onscreen, resize_handler, onscreen); + cogl_onscreen_add_resize_callback (onscreen, resize_handler, onscreen, NULL); triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES, 3, triangle_vertices);