swc

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

commit c5c473b88d45a9591c0bd80712ef822ff2813682
parent e672b60aa376d3ca1878073af877ea483d179e91
Author: Michael Forney <mforney@mforney.org>
Date:   Thu, 12 Sep 2013 20:00:27 -0700

Implement cursor surfaces

Diffstat:
Mlibswc/Makefile.am | 1+
Mlibswc/compositor.c | 27+++++++++++++++++++++++++++
Mlibswc/compositor.h | 2++
Alibswc/cursor_surface.c | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibswc/cursor_surface.h | 33+++++++++++++++++++++++++++++++++
Mlibswc/pointer.c | 7+++++--
Mlibswc/pointer.h | 7++++++-
Mlibswc/util.h | 9+++++++++
8 files changed, 195 insertions(+), 3 deletions(-)

diff --git a/libswc/Makefile.am b/libswc/Makefile.am @@ -12,6 +12,7 @@ libswc_la_SOURCES = \ plane.c plane.h \ surface.c surface.h \ compositor_surface.c compositor_surface.h \ + cursor_surface.c cursor_surface.h \ region.c region.h \ renderer.c renderer.h \ input_focus.c input_focus.h \ diff --git a/libswc/compositor.c b/libswc/compositor.c @@ -5,6 +5,7 @@ #include "compositor.h" #include "compositor_surface.h" +#include "cursor_surface.h" #include "tty.h" #include "output.h" #include "surface.h" @@ -300,6 +301,27 @@ static void handle_drm_event(struct wl_listener * listener, void * data) } } +static void handle_pointer_event(struct wl_listener * listener, void * data) +{ + struct swc_event * event = data; + struct swc_pointer_event_data * event_data = event->data; + struct swc_compositor * compositor; + + compositor = swc_container_of(listener, typeof(*compositor), + pointer_listener); + + switch (event->type) + { + case SWC_POINTER_CURSOR_CHANGED: + if (event_data->old) + swc_surface_set_class(event_data->old, NULL); + + if (event_data->new) + swc_surface_set_class(event_data->new, &compositor->cursor_class); + break; + } +} + static void handle_terminate(uint32_t time, uint32_t value, void * data) { struct wl_display * display = data; @@ -381,10 +403,13 @@ bool swc_compositor_initialize(struct swc_compositor * compositor, compositor->display = display; compositor->tty_listener.notify = &handle_tty_event; compositor->drm_listener.notify = &handle_drm_event; + compositor->pointer_listener.notify = &handle_pointer_event; compositor->scheduled_updates = 0; compositor->pending_flips = 0; compositor->compositor_class.interface = &swc_compositor_class_implementation; + compositor->cursor_class.interface = &swc_cursor_class_implementation; + compositor->udev = udev_new(); @@ -415,6 +440,8 @@ bool swc_compositor_initialize(struct swc_compositor * compositor, swc_seat_add_event_sources(&compositor->seat, event_loop); compositor->seat.keyboard.handler = &keyboard_handler; compositor->seat.pointer.handler = &pointer_handler; + wl_signal_add(&compositor->seat.pointer.event_signal, + &compositor->pointer_listener); /* TODO: configurable seat */ if (!swc_drm_initialize(&compositor->drm, compositor->udev, default_seat)) diff --git a/libswc/compositor.h b/libswc/compositor.h @@ -40,9 +40,11 @@ struct swc_compositor }; struct swc_surface_class compositor_class; + struct swc_surface_class cursor_class; struct wl_listener tty_listener; struct wl_listener drm_listener; + struct wl_listener pointer_listener; struct wl_signal destroy_signal; }; diff --git a/libswc/cursor_surface.c b/libswc/cursor_surface.c @@ -0,0 +1,112 @@ +/* swc: cursor_surface.c + * + * Copyright (c) 2013 Michael Forney + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "cursor_surface.h" +#include "compositor.h" + +#include <string.h> +#include <wld/wld.h> + +/* Cursor class */ +static const uint32_t cursor_buffer_size = 64 * 64 * 4; + +static void update_plane(struct swc_plane * plane, void * data) +{ + struct wld_drawable * drawable = swc_plane_get_buffer(plane); + + wld_write(drawable, data, cursor_buffer_size); + swc_plane_flip(plane); +} + +static void attach(struct swc_surface * surface, + struct wl_resource * resource) +{ + struct swc_compositor * compositor = swc_container_of + (surface->class, typeof(*compositor), cursor_class); + + if (pixman_region32_not_empty(&surface->state.damage)) + { + struct wl_shm_buffer * buffer = wl_shm_buffer_get(resource); + uint32_t width, height; + + if (!buffer) + return; + + width = wl_shm_buffer_get_width(buffer); + height = wl_shm_buffer_get_height(buffer); + + if (width <= 64 && height <= 64) + { + struct swc_output * output; + char data[cursor_buffer_size]; + + memset(data, 0, sizeof data); + pixman_blt(wl_shm_buffer_get_data(buffer), (uint32_t *) data, + wl_shm_buffer_get_stride(buffer) >> 2, 64, 32, 32, + 0, 0, 0, 0, width, height); + wl_buffer_send_release(resource); + pixman_region32_clear(&surface->state.damage); + + wl_list_for_each(output, &compositor->outputs, link) + { + if (swc_rectangle_overlap(&output->geometry, + &surface->geometry)) + { + update_plane(&output->cursor_plane, data); + } + } + } + } +} + +static void update(struct swc_surface * surface) +{ + swc_surface_send_frame_callbacks(surface, swc_time()); +} + +static void move(struct swc_surface * surface, int32_t x, int32_t y) +{ + struct swc_compositor * compositor = swc_container_of + (surface->class, typeof(*compositor), cursor_class); + struct swc_output * output; + + surface->geometry.x = x; + surface->geometry.y = y; + + wl_list_for_each(output, &compositor->outputs, link) + { + if (swc_rectangle_overlap(&output->geometry, &surface->geometry)) + { + swc_plane_move(&output->cursor_plane, + surface->geometry.x - output->geometry.x, + surface->geometry.y - output->geometry.y); + } + } +} + +const struct swc_surface_class_interface swc_cursor_class_implementation = { + .attach = &attach, + .update = &update, + .move = &move +}; + diff --git a/libswc/cursor_surface.h b/libswc/cursor_surface.h @@ -0,0 +1,33 @@ +/* swc: cursor_surface.h + * + * Copyright (c) 2013 Michael Forney + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef SWC_CURSOR_SURFACE_H +#define SWC_CURSOR_SURFACE_H 1 + +#include "surface.h" + +extern const struct swc_surface_class_interface + swc_cursor_class_implementation; + +#endif + diff --git a/libswc/pointer.c b/libswc/pointer.c @@ -88,8 +88,9 @@ static void set_cursor(struct wl_client * client, { struct swc_pointer * pointer = wl_resource_get_user_data(resource); struct swc_surface * surface; + struct swc_pointer_event_data data; - printf("set_cursor\n"); + data.old = pointer->cursor.surface; if (pointer->cursor.surface) wl_list_remove(&pointer->cursor.destroy_listener.link); @@ -109,7 +110,9 @@ static void set_cursor(struct wl_client * client, pointer->cursor.hotspot_x = hotspot_x; pointer->cursor.hotspot_y = hotspot_y; - swc_send_event(&pointer->event_signal, SWC_POINTER_CURSOR_CHANGED, pointer); + data.new = pointer->cursor.surface; + + swc_send_event(&pointer->event_signal, SWC_POINTER_CURSOR_CHANGED, &data); } struct wl_pointer_interface pointer_implementation = { diff --git a/libswc/pointer.h b/libswc/pointer.h @@ -16,11 +16,16 @@ struct swc_pointer_handler uint32_t button, uint32_t state); }; -enum swc_pointer_event +enum swc_pointer_event_type { SWC_POINTER_CURSOR_CHANGED }; +struct swc_pointer_event_data +{ + struct swc_surface * old, * new; +}; + struct swc_pointer { struct swc_input_focus focus; diff --git a/libswc/util.h b/libswc/util.h @@ -2,6 +2,7 @@ #define SWC_UTIL_H 1 #include <stdbool.h> +#include <sys/time.h> #include <sys/param.h> #include <wayland-server.h> #include <pixman.h> @@ -17,6 +18,14 @@ void swc_remove_resource(struct wl_resource * resource); +static inline uint32_t swc_time() +{ + struct timeval timeval; + + gettimeofday(&timeval, NULL); + return timeval.tv_sec * 1000 + timeval.tv_usec / 1000; +} + static inline bool swc_rectangle_contains_point (pixman_rectangle32_t * rectangle, int32_t x, int32_t y) {