diff --git a/CMakeLists.txt b/CMakeLists.txt index 939def0cb..dd4d99690 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,4 +59,6 @@ include_directories(include) add_subdirectory(backend) add_subdirectory(common) +add_subdirectory(wayland) + add_subdirectory(example) diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index 1189352cc..830a21584 100644 --- a/backend/CMakeLists.txt +++ b/backend/CMakeLists.txt @@ -12,5 +12,6 @@ add_library(wlr-backend target_link_libraries(wlr-backend wlr-common + wlr-wayland ${WAYLAND_LIBRARIES} ) diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index 4219c56ca..7f73c5015 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -9,7 +9,18 @@ void wlr_wl_backend_free(struct wlr_wl_backend *backend) { if (!backend) { return; } - // TODO: free more shit + // TODO: Free surfaces + for (size_t i = 0; backend->outputs && i < backend->outputs->length; ++i) { + struct wlr_wl_output *output = backend->outputs->items[i]; + wlr_wl_output_free(output); + } + list_free(backend->outputs); + if (backend->seat) wlr_wl_seat_free(backend->seat); + if (backend->shm) wl_shm_destroy(backend->shm); + if (backend->shell) wl_shell_destroy(backend->shell); + if (backend->compositor) wl_compositor_destroy(backend->compositor); + if (backend->registry) wl_registry_destroy(backend->registry); + if (backend->remote_display) wl_display_disconnect(backend->remote_display); free(backend); } diff --git a/backend/wayland/registry.c b/backend/wayland/registry.c index b3955bc11..4a639f627 100644 --- a/backend/wayland/registry.c +++ b/backend/wayland/registry.c @@ -25,7 +25,7 @@ static void registry_wl_seat(struct wlr_wl_backend *backend, wl_seat_add_listener(wl_seat, &seat_listener, seat); return; error: - //wlr_wl_seat_free(seat); TODO + wlr_wl_seat_free(seat); return; } @@ -47,7 +47,7 @@ static void registry_wl_output(struct wlr_wl_backend *backend, wl_output_add_listener(wl_output, &output_listener, output); return; error: - //wlr_wl_output_free(output); TODO + wlr_wl_output_free(output); return; } diff --git a/backend/wayland/wl_output.c b/backend/wayland/wl_output.c index e38fbfebf..cc4e9ccee 100644 --- a/backend/wayland/wl_output.c +++ b/backend/wayland/wl_output.c @@ -1,19 +1,30 @@ +#define _XOPEN_SOURCE 500 +#include #include #include #include #include #include "backend/wayland.h" +#include "common/log.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); + struct wlr_wl_output_mode *mode; + if (!(mode = calloc(sizeof(struct wlr_wl_output_mode), 1))) { + wlr_log(L_ERROR, "Failed to allocate wlr_wl_output_mode"); + return; + } mode->flags = flags; mode->width = width; mode->height = height; mode->refresh = refresh; list_add(output->modes, mode); + wlr_log(L_DEBUG, "Got mode for output %p: %dx%d @ %.2fHz%s%s", + wl_output, width, height, refresh / 1000.0, + (flags & WL_OUTPUT_MODE_PREFERRED) ? " (preferred)" : "", + (flags & WL_OUTPUT_MODE_CURRENT) ? " (current)" : ""); } static void wl_output_handle_geometry(void *data, struct wl_output *wl_output, @@ -26,15 +37,19 @@ static void wl_output_handle_geometry(void *data, struct wl_output *wl_output, output->phys_width = physical_width; output->phys_height = physical_height; output->subpixel = subpixel; - output->make = make; - output->model = model; + output->make = strdup(make); + output->model = strdup(model); output->transform = transform; + wlr_log(L_DEBUG, "Got info for output %p %dx%d (%dmm x %dmm) %s %s", + wl_output, (int)x, (int)y, (int)physical_width, (int)physical_height, + make, model); } 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; + wlr_log(L_DEBUG, "Got scale factor for output %p: %d", wl_output, factor); } static void wl_output_handle_done(void *data, struct wl_output *wl_output) { diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 5269d5fed..bc2b21a81 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -1,6 +1,8 @@ +#define _XOPEN_SOURCE 500 #include #include #include +#include #include #include "backend/wayland.h" #include "common/log.h" @@ -13,6 +15,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, assert(backend); if ((caps & WL_SEAT_CAPABILITY_POINTER)) { + wlr_log(L_DEBUG, "seat %p offered pointer", wl_seat); struct wl_pointer *wl_pointer = wl_seat_get_pointer(wl_seat); struct wlr_wl_pointer *pointer; if (!(pointer = calloc(sizeof(struct wlr_wl_pointer), 1))) { @@ -25,6 +28,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, } if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { + wlr_log(L_DEBUG, "seat %p offered keyboard", wl_seat); struct wl_keyboard *wl_keyboard = wl_seat_get_keyboard(wl_seat); struct wlr_wl_keyboard *keyboard; if (!(keyboard = calloc(sizeof(struct wlr_wl_pointer), 1))) { @@ -42,7 +46,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, static void seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name) { struct wlr_wl_seat *seat = data; assert(seat->wl_seat == wl_seat); - seat->name = name; + seat->name = strdup(name); } const struct wl_seat_listener seat_listener = { diff --git a/include/wlr/wayland.h b/include/wlr/wayland.h index 0a6974ff1..bbbd2457e 100644 --- a/include/wlr/wayland.h +++ b/include/wlr/wayland.h @@ -7,11 +7,13 @@ struct wlr_wl_seat { struct wl_seat *wl_seat; uint32_t capabilities; - const char *name; + char *name; list_t *keyboards; list_t *pointers; }; +void wlr_wl_seat_free(struct wlr_wl_seat *seat); + struct wlr_wl_output_mode { uint32_t flags; // enum wl_output_mode int32_t width, height; @@ -21,8 +23,8 @@ struct wlr_wl_output_mode { struct wlr_wl_output { struct wl_output *wl_output; uint32_t flags; - const char *make; - const char *model; + char *make; + char *model; uint32_t scale; int32_t x, y; int32_t phys_width, phys_height; // mm @@ -32,6 +34,8 @@ struct wlr_wl_output { struct wlr_wl_output_mode *current_mode; }; +void wlr_wl_output_free(struct wlr_wl_output *output); + struct wlr_wl_keyboard { struct wl_keyboard *wl_keyboard; }; diff --git a/wayland/CMakeLists.txt b/wayland/CMakeLists.txt new file mode 100644 index 000000000..be4a00de7 --- /dev/null +++ b/wayland/CMakeLists.txt @@ -0,0 +1,14 @@ +include_directories( + ${PROTOCOLS_INCLUDE_DIRS} + ${WAYLAND_INCLUDE_DIR} +) + +add_library(wlr-wayland + types/wlr_wl_seat.c + types/wlr_wl_output.c +) + +target_link_libraries(wlr-wayland + wlr-common + ${WAYLAND_LIBRARIES} +) diff --git a/wayland/types/wlr_wl_output.c b/wayland/types/wlr_wl_output.c new file mode 100644 index 000000000..32aaf0709 --- /dev/null +++ b/wayland/types/wlr_wl_output.c @@ -0,0 +1,16 @@ +#include +#include +#include "wlr/wayland.h" +#include "wlr/common/list.h" + +void wlr_wl_output_free(struct wlr_wl_output *output) { + if (!output) return; + if (output->wl_output) wl_output_destroy(output->wl_output); + if (output->make) free(output->make); + if (output->model) free(output->model); + for (size_t i = 0; output->modes && i < output->modes->length; ++i) { + free(output->modes->items[i]); + } + list_free(output->modes); + free(output); +} diff --git a/wayland/types/wlr_wl_seat.c b/wayland/types/wlr_wl_seat.c new file mode 100644 index 000000000..a5ef38539 --- /dev/null +++ b/wayland/types/wlr_wl_seat.c @@ -0,0 +1,19 @@ +#include +#include +#include "wlr/wayland.h" +#include "wlr/common/list.h" + +void wlr_wl_seat_free(struct wlr_wl_seat *seat) { + if (!seat) return; + if (seat->wl_seat) wl_seat_destroy(seat->wl_seat); + if (seat->name) free(seat->name); + if (seat->keyboards) { + // TODO: free children + list_free(seat->keyboards); + } + if (seat->pointers) { + // TODO: free children + list_free(seat->keyboards); + } + free(seat); +}