swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit f55d32f0a2223f509841e2ef638d63a53082573e
parent 1f66aeafbbbbe34c700f68efa4b6496f6c54d576
Author: Michael Forney <mforney@mforney.org>
Date:   Fri,  6 Dec 2013 23:54:33 -0800

surface: Set surface size to 0 when NULL buffer is attached

This fixes a NULL pointer dereference when a damaged buffer is
destroyed, and then the surface is repainted.

Diffstat:
Mlibswc/surface.c | 77+++++++++++++++++++++++++++++++++++++++++++----------------------------------
Mlibswc/surface.h | 1+
2 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/libswc/surface.c b/libswc/surface.c @@ -31,6 +31,37 @@ #include <stdio.h> #include <wld/wld.h> +static void set_size(struct swc_surface * surface, + uint32_t width, uint32_t height) +{ + /* Check if the surface was resized. */ + if (width != surface->geometry.width || height != surface->geometry.height) + { + struct swc_surface_event_data data = { + .surface = surface, + .resize = { + .old_width = surface->geometry.width, + .old_height = surface->geometry.height, + .new_width = width, + .new_height = height + } + }; + + surface->geometry.width = width; + surface->geometry.height = height; + + pixman_region32_intersect_rect + (&surface->state.opaque, &surface->state.opaque, + 0, 0, width, height); + pixman_region32_intersect_rect + (&surface->state.damage, &surface->state.damage, + 0, 0, width, height); + + swc_send_event(&surface->event_signal, + SWC_SURFACE_EVENT_TYPE_RESIZE, &data); + } +} + /** * Removes a buffer from a surface state. */ @@ -40,12 +71,21 @@ static void handle_buffer_destroy(struct wl_listener * listener, void * data) state = CONTAINER_OF(listener, typeof(*state), buffer_destroy_listener); state->buffer = NULL; + + if (state->current) + { + struct swc_surface * surface; + + surface = CONTAINER_OF(state, typeof(*surface), state); + set_size(surface, 0, 0); + } } -static void state_initialize(struct swc_surface_state * state) +static void state_initialize(struct swc_surface_state * state, bool current) { state->buffer = NULL; state->buffer_destroy_listener.notify = &handle_buffer_destroy; + state->current = current; pixman_region32_init(&state->damage); pixman_region32_init(&state->opaque); @@ -104,37 +144,6 @@ static bool state_set_buffer(struct swc_surface_state * state, return true; } -static void set_size(struct swc_surface * surface, - uint32_t width, uint32_t height) -{ - /* Check if the surface was resized. */ - if (width != surface->geometry.width || height != surface->geometry.height) - { - struct swc_surface_event_data data = { - .surface = surface, - .resize = { - .old_width = surface->geometry.width, - .old_height = surface->geometry.height, - .new_width = width, - .new_height = height - } - }; - - surface->geometry.width = width; - surface->geometry.height = height; - - pixman_region32_intersect_rect - (&surface->state.opaque, &surface->state.opaque, - 0, 0, width, height); - pixman_region32_intersect_rect - (&surface->state.damage, &surface->state.damage, - 0, 0, width, height); - - swc_send_event(&surface->event_signal, - SWC_SURFACE_EVENT_TYPE_RESIZE, &data); - } -} - static void destroy(struct wl_client * client, struct wl_resource * resource) { wl_resource_destroy(resource); @@ -368,8 +377,8 @@ struct swc_surface * swc_surface_new(struct wl_client * client, surface->class = NULL; surface->class_state = NULL; - state_initialize(&surface->state); - state_initialize(&surface->pending.state); + state_initialize(&surface->state, true); + state_initialize(&surface->pending.state, false); wl_signal_init(&surface->event_signal); diff --git a/libswc/surface.h b/libswc/surface.h @@ -57,6 +57,7 @@ struct swc_surface_state { struct wl_resource * buffer; struct wl_listener buffer_destroy_listener; + bool current; /* The region that needs to be repainted. */ pixman_region32_t damage;