diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index 01ac5e4e..1189352c 100644 --- a/backend/CMakeLists.txt +++ b/backend/CMakeLists.txt @@ -6,6 +6,8 @@ include_directories( add_library(wlr-backend wayland/backend.c wayland/registry.c + wayland/wl_seat.c + wayland/wl_output.c ) target_link_libraries(wlr-backend diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index 8ea54058..4219c56c 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -36,8 +36,7 @@ struct wlr_wl_backend *wlr_wl_backend_init( wlr_log(L_ERROR, "Could not connect to remote display"); goto error; } - if (!(backend->remote_registry = wl_display_get_registry( - backend->remote_display))) { + if (!(backend->registry = wl_display_get_registry(backend->remote_display))) { wlr_log(L_ERROR, "Could not obtain reference to remote registry"); goto error; } diff --git a/backend/wayland/registry.c b/backend/wayland/registry.c index 35d386d3..a0cfb91f 100644 --- a/backend/wayland/registry.c +++ b/backend/wayland/registry.c @@ -1,18 +1,73 @@ -#include #include +#include +#include #include #include "backend/wayland.h" #include "common/log.h" -static void registry_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - //struct wlr_wl_backend *backend = data; - wlr_log(L_DEBUG, "Remote wayland global: %s v%d", interface, version); - // TODO +static void registry_wl_seat(struct wlr_wl_backend *backend, + struct wl_seat *wl_seat, struct wl_registry *registry, uint32_t version) { + struct wlr_wl_seat *seat; + if (!(seat = calloc(sizeof(struct wlr_wl_seat), 1))) { + wlr_log(L_ERROR, "Failed to allocate wlr_wl_seat"); + goto error; + } + if (!(seat->keyboards = list_create())) { + wlr_log(L_ERROR, "Failed to allocate wlr_wl_seat"); + goto error; + } + if (!(seat->pointers = list_create())) { + wlr_log(L_ERROR, "Failed to allocate wlr_wl_pointer"); + goto error; + } + seat->wl_seat = wl_seat; + wl_seat_add_listener(wl_seat, &seat_listener, seat); +error: + //wlr_wl_seat_free(seat); TODO + return; } -static void registry_global_remove(void *data, - struct wl_registry *registry, uint32_t name) { +static void registry_wl_output(struct wlr_wl_backend *backend, + struct wl_output *wl_output, struct wl_registry *registry, uint32_t version) { + struct wlr_wl_output *output; + if (!(output = calloc(sizeof(struct wlr_wl_output), 1))) { + wlr_log(L_ERROR, "Failed to allocate wlr_wl_output"); + return; + } + output->wl_output = wl_output; + output->scale = 1; + list_add(backend->outputs, output); + wl_output_set_user_data(wl_output, backend); + wl_output_add_listener(wl_output, &output_listener, output); +} + +static void registry_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) { + struct wlr_wl_backend *backend = data; + wlr_log(L_DEBUG, "Remote wayland global: %s v%d", interface, version); + + if (strcmp(interface, wl_compositor_interface.name) == 0) { + backend->compositor = wl_registry_bind(registry, name, + &wl_compositor_interface, version); + } else if (strcmp(interface, wl_shell_interface.name) == 0) { + backend->shell = wl_registry_bind(registry, name, + &wl_shell_interface, version); + } else if (strcmp(interface, wl_shm_interface.name) == 0) { + backend->shm = wl_registry_bind(registry, name, + &wl_shm_interface, version); + } else if (strcmp(interface, wl_seat_interface.name) == 0) { + struct wl_seat *wl_seat = wl_registry_bind(registry, name, + &wl_seat_interface, version); + registry_wl_seat(backend, wl_seat, registry, version); + } else if (strcmp(interface, wl_output_interface.name) == 0) { + struct wl_output *wl_output = wl_registry_bind(registry, name, + &wl_output_interface, version); + registry_wl_output(backend, wl_output, registry, version); + } +} + +static void registry_global_remove(void *data, struct wl_registry *registry, + uint32_t name) { // TODO } @@ -22,8 +77,8 @@ static const struct wl_registry_listener registry_listener = { }; void wlr_wlb_registry_poll(struct wlr_wl_backend *backend) { - wl_registry_add_listener(backend->remote_registry, - ®istry_listener, backend->remote_registry); + wl_registry_add_listener(backend->registry, + ®istry_listener, backend->registry); wl_display_dispatch(backend->remote_display); wl_display_roundtrip(backend->remote_display); } diff --git a/backend/wayland/wl_output.c b/backend/wayland/wl_output.c new file mode 100644 index 00000000..e38fbfeb --- /dev/null +++ b/backend/wayland/wl_output.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include "backend/wayland.h" + +static void wl_output_handle_mode(void *data, struct wl_output *wl_output, + uint32_t flags, int32_t width, int32_t height, int32_t refresh) { + struct wlr_wl_output *output = data; + assert(output->wl_output == wl_output); + struct wlr_wl_output_mode *mode = calloc(sizeof(struct wlr_wl_output_mode), 1); + mode->flags = flags; + mode->width = width; + mode->height = height; + mode->refresh = refresh; + list_add(output->modes, mode); +} + +static void wl_output_handle_geometry(void *data, struct wl_output *wl_output, + int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, + int32_t subpixel, const char *make, const char *model, int32_t transform) { + struct wlr_wl_output *output = data; + assert(output->wl_output == wl_output); + output->x = x; + output->y = y; + output->phys_width = physical_width; + output->phys_height = physical_height; + output->subpixel = subpixel; + output->make = make; + output->model = model; + output->transform = transform; +} + +static void wl_output_handle_scale(void *data, struct wl_output *wl_output, int32_t factor) { + struct wlr_wl_output *output = data; + assert(output->wl_output == wl_output); + output->scale = factor; +} + +static void wl_output_handle_done(void *data, struct wl_output *wl_output) { + // TODO: notify of changes? Probably not necessary for this backend +} + +const struct wl_output_listener output_listener = { + .mode = wl_output_handle_mode, + .geometry = wl_output_handle_geometry, + .scale = wl_output_handle_scale, + .done = wl_output_handle_done +}; diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c new file mode 100644 index 00000000..489c1e39 --- /dev/null +++ b/backend/wayland/wl_seat.c @@ -0,0 +1,19 @@ +#include +#include +#include "backend/wayland.h" + +static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, + enum wl_seat_capability caps) { + //struct wlr_wl_seat *seat = data; + // TODO +} + +static void seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name) { + struct wlr_wl_seat *seat = data; + seat->name = name; +} + +const struct wl_seat_listener seat_listener = { + .capabilities = seat_handle_capabilities, + .name = seat_handle_name, +}; diff --git a/include/backend/wayland.h b/include/backend/wayland.h index 368b0724..94aa0962 100644 --- a/include/backend/wayland.h +++ b/include/backend/wayland.h @@ -11,8 +11,8 @@ struct wlr_wl_backend { struct wl_display *local_display; /* remote state */ struct wl_display *remote_display; - struct wl_registry *remote_registry; - struct wl_compositor *remote_compositor; + struct wl_registry *registry; + struct wl_compositor *compositor; struct wl_shell *shell; struct wl_shm *shm; struct wlr_wl_seat *seat; @@ -21,4 +21,7 @@ struct wlr_wl_backend { void wlr_wlb_registry_poll(struct wlr_wl_backend *backend); +extern const struct wl_seat_listener seat_listener; +extern const struct wl_output_listener output_listener; + #endif diff --git a/include/wlr/wayland.h b/include/wlr/wayland.h index 1c0b30ae..0a6974ff 100644 --- a/include/wlr/wayland.h +++ b/include/wlr/wayland.h @@ -8,15 +8,28 @@ struct wlr_wl_seat { struct wl_seat *wl_seat; uint32_t capabilities; const char *name; - list_t *outputs; + list_t *keyboards; list_t *pointers; }; +struct wlr_wl_output_mode { + uint32_t flags; // enum wl_output_mode + int32_t width, height; + int32_t refresh; // mHz +}; + struct wlr_wl_output { struct wl_output *wl_output; uint32_t flags; - uint32_t width, height; + const char *make; + const char *model; uint32_t scale; + int32_t x, y; + int32_t phys_width, phys_height; // mm + int32_t subpixel; // enum wl_output_subpixel + int32_t transform; // enum wl_output_transform + list_t *modes; + struct wlr_wl_output_mode *current_mode; }; struct wlr_wl_keyboard {