swc

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

commit 9b3ddc49f9869eb04743efb2f57812d9f4810a03
parent 627e6427e56fa864a3228003e1b81dc2176c760e
Author: Michael Forney <mforney@mforney.org>
Date:   Sat, 18 Jan 2014 03:48:33 -0800

pointer: Implement cursor handling

Diffstat:
Mlibswc/pointer.c | 138+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mlibswc/pointer.h | 23++++++++++-------------
2 files changed, 134 insertions(+), 27 deletions(-)

diff --git a/libswc/pointer.c b/libswc/pointer.c @@ -1,10 +1,13 @@ #include "pointer.h" #include "event.h" +#include "internal.h" +#include "screen.h" +#include "shm.h" #include "util.h" -#include "view.h" #include <stdio.h> #include <assert.h> +#include <wld/wld.h> static void enter(struct swc_input_focus_handler * handler, struct wl_resource * resource, struct swc_surface * surface) @@ -49,12 +52,108 @@ static void handle_cursor_surface_destroy(struct wl_listener * listener, struct swc_pointer * pointer = CONTAINER_OF(listener, typeof(*pointer), cursor.destroy_listener); - pointer->cursor.surface = NULL; + swc_view_attach(&pointer->cursor.view, NULL); +} + +static bool update(struct swc_view * view) +{ + return true; +} + +static bool attach(struct swc_view * view, struct swc_buffer * buffer) +{ + struct swc_pointer * pointer + = CONTAINER_OF(view, typeof(*pointer), cursor.view); + struct swc_surface * surface = pointer->cursor.surface; + + if (surface && !pixman_region32_not_empty(&surface->state.damage)) + return true; + + wld_set_target_buffer(swc.shm->renderer, pointer->cursor.buffer.wld); + wld_fill_rectangle(swc.shm->renderer, 0x00000000, 0, 0, 64, 64); + wld_copy_rectangle(swc.shm->renderer, buffer->wld, 0, 0, 0, 0, + buffer->wld->width, buffer->wld->height); + wld_flush(swc.shm->renderer); + + if (surface) + pixman_region32_clear(&surface->state.damage); + + /* TODO: Send an early release to the buffer */ + + return true; +} + +static bool move(struct swc_view * view, int32_t x, int32_t y) +{ + return true; +} + +static const struct swc_view_impl view_impl = { + .update = &update, + .attach = &attach, + .move = &move, +}; + +static void handle_view_event(struct wl_listener * listener, void * data) +{ + struct swc_pointer * pointer + = CONTAINER_OF(listener, typeof(*pointer), cursor.view_listener); + struct swc_event * event = data; + struct swc_view_event_data * event_data = event->data; + struct swc_view * view = event_data->view; + + switch (event->type) + { + case SWC_VIEW_EVENT_MOVED: + { + struct swc_screen_internal * screen; + + wl_list_for_each(screen, &swc.screens, link) + { + if (view->screens & swc_screen_mask(screen)) + { + struct swc_pointer * pointer + = CONTAINER_OF(view, typeof(*pointer), cursor.view); + + swc_view_move(&screen->planes.cursor.view, + view->geometry.x - screen->base.geometry.x, + view->geometry.y - screen->base.geometry.y); + + if (!screen->planes.cursor.view.buffer) + { + swc_view_attach(&screen->planes.cursor.view, + &pointer->cursor.buffer); + } + } + else if (screen->planes.cursor.view.buffer) + swc_view_attach(&screen->planes.cursor.view, NULL); + } + break; + } + case SWC_VIEW_EVENT_SCREENS_CHANGED: + { + struct swc_screen_internal * screen; + uint32_t entered = event_data->screens_changed.entered, + left = event_data->screens_changed.left; + + wl_list_for_each(screen, &swc.screens, link) + { + if (entered & swc_screen_mask(screen)) + { + swc_view_attach(&screen->planes.cursor.view, + &pointer->cursor.buffer); + } + else if (left & swc_screen_mask(screen)) + swc_view_attach(&screen->planes.cursor.view, NULL); + } + break; + } + } } bool swc_pointer_initialize(struct swc_pointer * pointer) { - wl_signal_init(&pointer->event_signal); + struct wld_buffer * buffer; pointer->x = wl_fixed_from_int(0); pointer->y = wl_fixed_from_int(0); @@ -62,7 +161,18 @@ bool swc_pointer_initialize(struct swc_pointer * pointer) pointer->focus_handler.enter = &enter; pointer->focus_handler.leave = &leave; + swc_view_initialize(&pointer->cursor.view, &view_impl); + pointer->cursor.view_listener.notify = &handle_view_event; + wl_signal_add(&pointer->cursor.view.event_signal, + &pointer->cursor.view_listener); + pointer->cursor.surface = NULL; pointer->cursor.destroy_listener.notify = &handle_cursor_surface_destroy; + buffer = wld_create_buffer(swc.drm->context, 64, 64, WLD_FORMAT_ARGB8888); + + if (!buffer) + return false; + + swc_buffer_initialize(&pointer->cursor.buffer, buffer); swc_input_focus_initialize(&pointer->focus, &pointer->focus_handler); pixman_region32_init(&pointer->region); @@ -124,29 +234,25 @@ 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; - - data.old = pointer->cursor.surface; if (pointer->cursor.surface) wl_list_remove(&pointer->cursor.destroy_listener.link); surface = surface_resource ? wl_resource_get_user_data(surface_resource) : NULL; + pointer->cursor.surface = surface; + pointer->cursor.hotspot.x = hotspot_x; + pointer->cursor.hotspot.y = hotspot_y; if (surface) { + swc_surface_set_view(surface, &pointer->cursor.view); wl_resource_add_destroy_listener(surface->resource, &pointer->cursor.destroy_listener); + swc_view_move(&pointer->cursor.view, + wl_fixed_to_int(pointer->x) - hotspot_x, + wl_fixed_to_int(pointer->y) - hotspot_y); } - - pointer->cursor.surface = surface; - pointer->cursor.hotspot_x = hotspot_x; - pointer->cursor.hotspot_y = hotspot_y; - - data.new = pointer->cursor.surface; - - swc_send_event(&pointer->event_signal, SWC_POINTER_CURSOR_CHANGED, &data); } static struct wl_pointer_interface pointer_implementation = { @@ -224,5 +330,9 @@ void swc_pointer_handle_relative_motion wl_pointer_send_motion(pointer->focus.resource, time, surface_x, surface_y); } + + swc_view_move(&pointer->cursor.view, + wl_fixed_to_int(pointer->x) - pointer->cursor.hotspot.x, + wl_fixed_to_int(pointer->y) - pointer->cursor.hotspot.y); } diff --git a/libswc/pointer.h b/libswc/pointer.h @@ -1,8 +1,10 @@ #ifndef SWC_POINTER_H #define SWC_POINTER_H +#include "buffer.h" #include "input_focus.h" #include "surface.h" +#include "view.h" #include <wayland-server.h> #include <pixman.h> @@ -19,28 +21,23 @@ struct swc_pointer_handler enum wl_pointer_axis axis, wl_fixed_t amount); }; -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; struct swc_input_focus_handler focus_handler; - struct wl_signal event_signal; - struct { + struct swc_view view; + struct wl_listener view_listener; struct swc_surface * surface; - int32_t hotspot_x, hotspot_y; struct wl_listener destroy_listener; + struct swc_buffer buffer; + + struct + { + int32_t x, y; + } hotspot; } cursor; struct swc_pointer_handler * handler;