diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/egl_common.c | 122 | ||||
-rw-r--r-- | examples/egl_common.h | 19 | ||||
-rw-r--r-- | examples/embedded.c | 38 | ||||
-rw-r--r-- | examples/foreign-toplevel.c | 439 | ||||
-rw-r--r-- | examples/gamma-control.c | 194 | ||||
-rw-r--r-- | examples/idle-inhibit.c | 227 | ||||
-rw-r--r-- | examples/input-inhibitor.c | 187 | ||||
-rw-r--r-- | examples/input-method-keyboard-grab.c | 216 | ||||
-rw-r--r-- | examples/input-method.c | 401 | ||||
-rw-r--r-- | examples/keyboard-shortcuts-inhibit.c | 261 | ||||
-rw-r--r-- | examples/layer-shell.c | 668 | ||||
-rw-r--r-- | examples/meson.build | 183 | ||||
-rw-r--r-- | examples/output-power-management.c | 144 | ||||
-rw-r--r-- | examples/pointer-constraints.c | 258 | ||||
-rw-r--r-- | examples/screencopy-dmabuf.c | 360 | ||||
-rw-r--r-- | examples/screencopy.c | 266 | ||||
-rw-r--r-- | examples/text-input.c | 390 | ||||
-rw-r--r-- | examples/toplevel-decoration.c | 251 | ||||
-rw-r--r-- | examples/virtual-pointer.c | 138 |
19 files changed, 43 insertions, 4719 deletions
diff --git a/examples/egl_common.c b/examples/egl_common.c deleted file mode 100644 index f095a487..00000000 --- a/examples/egl_common.c +++ /dev/null @@ -1,122 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdbool.h> -#include <unistd.h> -#include <wayland-client.h> - -#include <EGL/egl.h> -#include <EGL/eglext.h> - -#include "egl_common.h" - -EGLDisplay egl_display; -EGLConfig egl_config; -EGLContext egl_context; - -PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT; -PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT; - -const EGLint config_attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_NONE, -}; - -const EGLint context_attribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE, -}; - -bool egl_init(struct wl_display *display) { - const char *client_exts_str = - eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - if (client_exts_str == NULL) { - if (eglGetError() == EGL_BAD_DISPLAY) { - fprintf(stderr, "EGL_EXT_client_extensions not supported\n"); - } else { - fprintf(stderr, "Failed to query EGL client extensions\n"); - } - return false; - } - - if (!strstr(client_exts_str, "EGL_EXT_platform_base")) { - fprintf(stderr, "EGL_EXT_platform_base not supported\n"); - return false; - } - - if (!strstr(client_exts_str, "EGL_EXT_platform_wayland")) { - fprintf(stderr, "EGL_EXT_platform_wayland not supported\n"); - return false; - } - - eglGetPlatformDisplayEXT = - (void *)eglGetProcAddress("eglGetPlatformDisplayEXT"); - if (eglGetPlatformDisplayEXT == NULL) { - fprintf(stderr, "Failed to get eglGetPlatformDisplayEXT\n"); - return false; - } - - eglCreatePlatformWindowSurfaceEXT = - (void *)eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); - if (eglCreatePlatformWindowSurfaceEXT == NULL) { - fprintf(stderr, "Failed to get eglCreatePlatformWindowSurfaceEXT\n"); - return false; - } - - egl_display = - eglGetPlatformDisplayEXT(EGL_PLATFORM_WAYLAND_EXT, - display, NULL); - if (egl_display == EGL_NO_DISPLAY) { - fprintf(stderr, "Failed to create EGL display\n"); - goto error; - } - - if (eglInitialize(egl_display, NULL, NULL) == EGL_FALSE) { - fprintf(stderr, "Failed to initialize EGL\n"); - goto error; - } - - EGLint matched = 0; - if (!eglChooseConfig(egl_display, config_attribs, - &egl_config, 1, &matched)) { - fprintf(stderr, "eglChooseConfig failed\n"); - goto error; - } - if (matched == 0) { - fprintf(stderr, "Failed to match an EGL config\n"); - goto error; - } - - egl_context = - eglCreateContext(egl_display, egl_config, - EGL_NO_CONTEXT, context_attribs); - if (egl_context == EGL_NO_CONTEXT) { - fprintf(stderr, "Failed to create EGL context\n"); - goto error; - } - - return true; - -error: - eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (egl_display) { - eglTerminate(egl_display); - } - eglReleaseThread(); - return false; -} - -void egl_finish(void) { - eglMakeCurrent(egl_display, EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglDestroyContext(egl_display, egl_context); - eglTerminate(egl_display); - eglReleaseThread(); -} diff --git a/examples/egl_common.h b/examples/egl_common.h deleted file mode 100644 index f12c05be..00000000 --- a/examples/egl_common.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _EGL_COMMON_H -#define _EGL_COMMON_H -#endif - -#include <stdbool.h> -#include <wayland-client.h> - -#include <EGL/egl.h> -#include <EGL/eglext.h> - -extern EGLDisplay egl_display; -extern EGLConfig egl_config; -extern EGLContext egl_context; - -extern PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT; - -bool egl_init(struct wl_display *display); - -void egl_finish(void); diff --git a/examples/embedded.c b/examples/embedded.c index 1bf11643..1e52e892 100644 --- a/examples/embedded.c +++ b/examples/embedded.c @@ -1,4 +1,6 @@ #define _POSIX_C_SOURCE 200112L +#include <EGL/egl.h> +#include <EGL/eglext.h> #include <GLES2/gl2.h> #include <stdio.h> #include <stdlib.h> @@ -13,7 +15,6 @@ #include <wlr/types/wlr_xdg_shell.h> #include <wlr/util/log.h> -#include "egl_common.h" #include "xdg-shell-client-protocol.h" static struct wl_display *remote_display = NULL; @@ -31,8 +32,12 @@ static struct wlr_scene_output *scene_output = NULL; static struct wl_listener new_surface = {0}; static struct wl_listener output_frame = {0}; -int width = 500; -int height = 500; +static EGLDisplay egl_display; +static EGLConfig egl_config; +static EGLContext egl_context; + +static int width = 500; +static int height = 500; static void draw_main_surface(void); @@ -120,6 +125,29 @@ static void handle_new_surface(struct wl_listener *listener, void *data) { wlr_scene_surface_create(&scene->tree, wlr_surface); } +static void init_egl(struct wl_display *display) { + egl_display = eglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, display, NULL); + eglInitialize(egl_display, NULL, NULL); + + EGLint matched = 0; + const EGLint config_attribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE, + }; + eglChooseConfig(egl_display, config_attribs, &egl_config, 1, &matched); + + const EGLint context_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE, + }; + egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, context_attribs); +} + int main(int argc, char *argv[]) { wlr_log_init(WLR_DEBUG, NULL); @@ -128,7 +156,7 @@ int main(int argc, char *argv[]) { wl_registry_add_listener(registry, ®istry_listener, NULL); wl_display_roundtrip(remote_display); - egl_init(remote_display); + init_egl(remote_display); struct wl_display *local_display = wl_display_create(); struct wlr_backend *backend = wlr_wl_backend_create(local_display, remote_display); @@ -152,7 +180,7 @@ int main(int argc, char *argv[]) { xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL); egl_window = wl_egl_window_create(main_surface, width, height); - egl_surface = eglCreatePlatformWindowSurfaceEXT(egl_display, + egl_surface = eglCreatePlatformWindowSurface(egl_display, egl_config, egl_window, NULL); struct wl_surface *child_surface = wl_compositor_create_surface(compositor); diff --git a/examples/foreign-toplevel.c b/examples/foreign-toplevel.c deleted file mode 100644 index 8bb62c83..00000000 --- a/examples/foreign-toplevel.c +++ /dev/null @@ -1,439 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#include <getopt.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <wayland-client.h> -#include "wlr-foreign-toplevel-management-unstable-v1-client-protocol.h" - -#define WLR_FOREIGN_TOPLEVEL_MANAGEMENT_VERSION 3 - - -static void print_help(void) { - static const char usage[] = - "Usage: foreign-toplevel [OPTIONS] ...\n" - "Manage and view information about toplevel windows.\n" - "\n" - " -f <id> focus\n" - " -s <id> fullscreen\n" - " -o <output_id> select output for fullscreen toplevel to appear on. Use this\n" - " option with -s. View available outputs with wayland-info.\n" - " -S <id> unfullscreen\n" - " -a <id> maximize\n" - " -u <id> unmaximize\n" - " -i <id> minimize\n" - " -r <id> restore(unminimize)\n" - " -c <id> close\n" - " -m continuously print changes to the list of opened toplevels\n" - " Can be used together with some of the previous options.\n" - " -h print help message and quit\n"; - fprintf(stderr, "%s", usage); -} - -enum toplevel_state_field { - TOPLEVEL_STATE_MAXIMIZED = (1 << 0), - TOPLEVEL_STATE_MINIMIZED = (1 << 1), - TOPLEVEL_STATE_ACTIVATED = (1 << 2), - TOPLEVEL_STATE_FULLSCREEN = (1 << 3), - TOPLEVEL_STATE_INVALID = (1 << 4), -}; - -static const uint32_t no_parent = (uint32_t)-1; -static struct wl_output *pref_output = NULL; -static uint32_t pref_output_id = UINT32_MAX; - -struct toplevel_state { - char *title; - char *app_id; - - uint32_t state; - uint32_t parent_id; -}; - -static void copy_state(struct toplevel_state *current, - struct toplevel_state *pending) { - if (current->title && pending->title) { - free(current->title); - } - if (current->app_id && pending->app_id) { - free(current->app_id); - } - - if (pending->title) { - current->title = pending->title; - pending->title = NULL; - } - if (pending->app_id) { - current->app_id = pending->app_id; - pending->app_id = NULL; - } - - if (!(pending->state & TOPLEVEL_STATE_INVALID)) { - current->state = pending->state; - } - - current->parent_id = pending->parent_id; - - pending->state = TOPLEVEL_STATE_INVALID; -} - -static uint32_t global_id = 0; -struct toplevel_v1 { - struct wl_list link; - struct zwlr_foreign_toplevel_handle_v1 *zwlr_toplevel; - - uint32_t id; - struct toplevel_state current, pending; -}; - -static void print_toplevel(struct toplevel_v1 *toplevel, bool print_endl) { - printf("-> %d. title=%s app_id=%s", toplevel->id, - toplevel->current.title ?: "(nil)", - toplevel->current.app_id ?: "(nil)"); - - if (toplevel->current.parent_id != no_parent) { - printf(" parent=%u", toplevel->current.parent_id); - } else { - printf(" no parent"); - } - - if (print_endl) { - printf("\n"); - } -} - -static void print_toplevel_state(struct toplevel_v1 *toplevel, bool print_endl) { - if (toplevel->current.state & TOPLEVEL_STATE_MAXIMIZED) { - printf(" maximized"); - } else { - printf(" unmaximized"); - } - if (toplevel->current.state & TOPLEVEL_STATE_MINIMIZED) { - printf(" minimized"); - } else { - printf(" unminimized"); - } - if (toplevel->current.state & TOPLEVEL_STATE_ACTIVATED) { - printf(" active"); - } else { - printf(" inactive"); - } - if (toplevel->current.state & TOPLEVEL_STATE_FULLSCREEN) { - printf(" fullscreen"); - } - - if (print_endl) { - printf("\n"); - } -} - -static void finish_toplevel_state(struct toplevel_state *state) { - free(state->title); - free(state->app_id); -} - -static void toplevel_handle_title(void *data, - struct zwlr_foreign_toplevel_handle_v1 *zwlr_toplevel, - const char *title) { - struct toplevel_v1 *toplevel = data; - free(toplevel->pending.title); - toplevel->pending.title = strdup(title); -} - -static void toplevel_handle_app_id(void *data, - struct zwlr_foreign_toplevel_handle_v1 *zwlr_toplevel, - const char *app_id) { - struct toplevel_v1 *toplevel = data; - free(toplevel->pending.app_id); - toplevel->pending.app_id = strdup(app_id); -} - -static void toplevel_handle_output_enter(void *data, - struct zwlr_foreign_toplevel_handle_v1 *zwlr_toplevel, - struct wl_output *output) { - struct toplevel_v1 *toplevel = data; - print_toplevel(toplevel, false); - printf(" enter output %u\n", - (uint32_t)(size_t)wl_output_get_user_data(output)); -} - -static void toplevel_handle_output_leave(void *data, - struct zwlr_foreign_toplevel_handle_v1 *zwlr_toplevel, - struct wl_output *output) { - struct toplevel_v1 *toplevel = data; - print_toplevel(toplevel, false); - printf(" leave output %u\n", - (uint32_t)(size_t)wl_output_get_user_data(output)); -} - -static uint32_t array_to_state(struct wl_array *array) { - uint32_t state = 0; - uint32_t *entry; - wl_array_for_each(entry, array) { - if (*entry == ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED) - state |= TOPLEVEL_STATE_MAXIMIZED; - if (*entry == ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED) - state |= TOPLEVEL_STATE_MINIMIZED; - if (*entry == ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED) - state |= TOPLEVEL_STATE_ACTIVATED; - if (*entry == ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN) - state |= TOPLEVEL_STATE_FULLSCREEN; - } - - return state; -} - -static void toplevel_handle_state(void *data, - struct zwlr_foreign_toplevel_handle_v1 *zwlr_toplevel, - struct wl_array *state) { - struct toplevel_v1 *toplevel = data; - toplevel->pending.state = array_to_state(state); -} - -static struct zwlr_foreign_toplevel_manager_v1 *toplevel_manager = NULL; -static struct wl_list toplevel_list; - -static void toplevel_handle_parent(void *data, - struct zwlr_foreign_toplevel_handle_v1 *zwlr_toplevel, - struct zwlr_foreign_toplevel_handle_v1 *zwlr_parent) { - struct toplevel_v1 *toplevel = data; - toplevel->pending.parent_id = no_parent; - if (zwlr_parent) { - struct toplevel_v1 *toplevel_tmp; - wl_list_for_each(toplevel_tmp, &toplevel_list, link) { - if (toplevel_tmp->zwlr_toplevel == zwlr_parent) { - toplevel->pending.parent_id = toplevel_tmp->id; - break; - } - } - if (toplevel->pending.parent_id == no_parent) { - fprintf(stderr, "Cannot find parent toplevel!\n"); - } - } -} - -static void toplevel_handle_done(void *data, - struct zwlr_foreign_toplevel_handle_v1 *zwlr_toplevel) { - struct toplevel_v1 *toplevel = data; - bool state_changed = toplevel->current.state != toplevel->pending.state; - - copy_state(&toplevel->current, &toplevel->pending); - - print_toplevel(toplevel, !state_changed); - if (state_changed) { - print_toplevel_state(toplevel, true); - } -} - -static void toplevel_handle_closed(void *data, - struct zwlr_foreign_toplevel_handle_v1 *zwlr_toplevel) { - struct toplevel_v1 *toplevel = data; - print_toplevel(toplevel, false); - printf(" closed\n"); - - zwlr_foreign_toplevel_handle_v1_destroy(zwlr_toplevel); - finish_toplevel_state(&toplevel->current); - finish_toplevel_state(&toplevel->pending); - free(toplevel); -} - -static const struct zwlr_foreign_toplevel_handle_v1_listener toplevel_impl = { - .title = toplevel_handle_title, - .app_id = toplevel_handle_app_id, - .output_enter = toplevel_handle_output_enter, - .output_leave = toplevel_handle_output_leave, - .state = toplevel_handle_state, - .done = toplevel_handle_done, - .closed = toplevel_handle_closed, - .parent = toplevel_handle_parent -}; - -static void toplevel_manager_handle_toplevel(void *data, - struct zwlr_foreign_toplevel_manager_v1 *toplevel_manager, - struct zwlr_foreign_toplevel_handle_v1 *zwlr_toplevel) { - struct toplevel_v1 *toplevel = calloc(1, sizeof(*toplevel)); - if (!toplevel) { - fprintf(stderr, "Failed to allocate memory for toplevel\n"); - return; - } - - toplevel->id = global_id++; - toplevel->zwlr_toplevel = zwlr_toplevel; - toplevel->current.parent_id = no_parent; - toplevel->pending.parent_id = no_parent; - wl_list_insert(&toplevel_list, &toplevel->link); - - zwlr_foreign_toplevel_handle_v1_add_listener(zwlr_toplevel, &toplevel_impl, - toplevel); -} - -static void toplevel_manager_handle_finished(void *data, - struct zwlr_foreign_toplevel_manager_v1 *toplevel_manager) { - zwlr_foreign_toplevel_manager_v1_destroy(toplevel_manager); -} - -static const struct zwlr_foreign_toplevel_manager_v1_listener toplevel_manager_impl = { - .toplevel = toplevel_manager_handle_toplevel, - .finished = toplevel_manager_handle_finished, -}; - -struct wl_seat *seat = NULL; -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, wl_output_interface.name) == 0) { - if (name == pref_output_id) { - pref_output = wl_registry_bind(registry, name, - &wl_output_interface, version); - - } - } else if (strcmp(interface, - zwlr_foreign_toplevel_manager_v1_interface.name) == 0) { - toplevel_manager = wl_registry_bind(registry, name, - &zwlr_foreign_toplevel_manager_v1_interface, - WLR_FOREIGN_TOPLEVEL_MANAGEMENT_VERSION); - - wl_list_init(&toplevel_list); - zwlr_foreign_toplevel_manager_v1_add_listener(toplevel_manager, - &toplevel_manager_impl, NULL); - } else if (strcmp(interface, wl_seat_interface.name) == 0 && seat == NULL) { - seat = wl_registry_bind(registry, name, &wl_seat_interface, version); - } -} - -static void handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) { - // who cares -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = handle_global_remove, -}; - -/* return NULL when id == -1 - * exit if the given ID cannot be found in the list of toplevels */ -static struct toplevel_v1 *toplevel_by_id_or_bail(int32_t id) { - if (id == -1) { - return NULL; - } - - struct toplevel_v1 *toplevel; - wl_list_for_each(toplevel, &toplevel_list, link) { - if (toplevel->id == (uint32_t)id) { - return toplevel; - } - } - - fprintf(stderr, "No toplevel with the given id: %d\n", id); - exit(EXIT_FAILURE); -} - -int main(int argc, char **argv) { - int focus_id = -1, close_id = -1; - int maximize_id = -1, unmaximize_id = -1; - int minimize_id = -1, restore_id = -1; - int fullscreen_id = -1, unfullscreen_id = -1; - int one_shot = 1; - int c; - - while ((c = getopt(argc, argv, "f:a:u:i:r:c:s:S:mo:h")) != -1) { - switch (c) { - case 'f': - focus_id = atoi(optarg); - break; - case 'a': - maximize_id = atoi(optarg); - break; - case 'u': - unmaximize_id = atoi(optarg); - break; - case 'i': - minimize_id = atoi(optarg); - break; - case 'r': - restore_id = atoi(optarg); - break; - case 'c': - close_id = atoi(optarg); - break; - case 's': - fullscreen_id = atoi(optarg); - break; - case 'S': - unfullscreen_id = atoi(optarg); - break; - case 'm': - one_shot = 0; - break; - case 'o': - pref_output_id = atoi(optarg); - break; - case '?': - print_help(); - return EXIT_FAILURE; - break; - case 'h': - print_help(); - return EXIT_SUCCESS; - break; - } - } - - struct wl_display *display = wl_display_connect(NULL); - if (display == NULL) { - fprintf(stderr, "Failed to create display\n"); - return EXIT_FAILURE; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (toplevel_manager == NULL) { - fprintf(stderr, "wlr-foreign-toplevel not available\n"); - return EXIT_FAILURE; - } - wl_display_roundtrip(display); // load list of toplevels - wl_display_roundtrip(display); // load toplevel details - - struct toplevel_v1 *toplevel; - if ((toplevel = toplevel_by_id_or_bail(focus_id))) { - zwlr_foreign_toplevel_handle_v1_activate(toplevel->zwlr_toplevel, seat); - } - if ((toplevel = toplevel_by_id_or_bail(maximize_id))) { - zwlr_foreign_toplevel_handle_v1_set_maximized(toplevel->zwlr_toplevel); - } - if ((toplevel = toplevel_by_id_or_bail(unmaximize_id))) { - zwlr_foreign_toplevel_handle_v1_unset_maximized(toplevel->zwlr_toplevel); - } - if ((toplevel = toplevel_by_id_or_bail(minimize_id))) { - zwlr_foreign_toplevel_handle_v1_set_minimized(toplevel->zwlr_toplevel); - } - if ((toplevel = toplevel_by_id_or_bail(restore_id))) { - zwlr_foreign_toplevel_handle_v1_unset_minimized(toplevel->zwlr_toplevel); - } - if ((toplevel = toplevel_by_id_or_bail(fullscreen_id))) { - if (pref_output_id != UINT32_MAX && pref_output == NULL) { - fprintf(stderr, "Could not find output %i\n", pref_output_id); - } - - zwlr_foreign_toplevel_handle_v1_set_fullscreen(toplevel->zwlr_toplevel, pref_output); - } - if ((toplevel = toplevel_by_id_or_bail(unfullscreen_id))) { - zwlr_foreign_toplevel_handle_v1_unset_fullscreen(toplevel->zwlr_toplevel); - } - if ((toplevel = toplevel_by_id_or_bail(close_id))) { - zwlr_foreign_toplevel_handle_v1_close(toplevel->zwlr_toplevel); - } - - wl_display_flush(display); - - if (one_shot == 0) { - while (wl_display_dispatch(display) != -1) { - // This space intentionally left blank - } - } - - return EXIT_SUCCESS; -} diff --git a/examples/gamma-control.c b/examples/gamma-control.c deleted file mode 100644 index 69d1cd75..00000000 --- a/examples/gamma-control.c +++ /dev/null @@ -1,194 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <unistd.h> -#include <wayland-client-protocol.h> -#include <wayland-client.h> -#include "wlr-gamma-control-unstable-v1-client-protocol.h" - -struct output { - struct wl_output *wl_output; - struct zwlr_gamma_control_v1 *gamma_control; - uint32_t ramp_size; - int table_fd; - uint16_t *table; - struct wl_list link; -}; - -static struct wl_list outputs; -static struct zwlr_gamma_control_manager_v1 *gamma_control_manager = NULL; - -static int create_anonymous_file(off_t size) { - char template[] = "/tmp/wlroots-shared-XXXXXX"; - int fd = mkstemp(template); - if (fd < 0) { - return -1; - } - - int ret; - do { - errno = 0; - ret = ftruncate(fd, size); - } while (errno == EINTR); - if (ret < 0) { - close(fd); - return -1; - } - - unlink(template); - return fd; -} - -static int create_gamma_table(uint32_t ramp_size, uint16_t **table) { - size_t table_size = ramp_size * 3 * sizeof(uint16_t); - int fd = create_anonymous_file(table_size); - if (fd < 0) { - fprintf(stderr, "failed to create anonymous file\n"); - return -1; - } - - void *data = - mmap(NULL, table_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (data == MAP_FAILED) { - fprintf(stderr, "failed to mmap()\n"); - close(fd); - return -1; - } - - *table = data; - return fd; -} - -static void gamma_control_handle_gamma_size(void *data, - struct zwlr_gamma_control_v1 *gamma_control, uint32_t ramp_size) { - struct output *output = data; - output->ramp_size = ramp_size; - output->table_fd = create_gamma_table(ramp_size, &output->table); - if (output->table_fd < 0) { - exit(EXIT_FAILURE); - } -} - -static void gamma_control_handle_failed(void *data, - struct zwlr_gamma_control_v1 *gamma_control) { - fprintf(stderr, "failed to set gamma table\n"); - exit(EXIT_FAILURE); -} - -static const struct zwlr_gamma_control_v1_listener gamma_control_listener = { - .gamma_size = gamma_control_handle_gamma_size, - .failed = gamma_control_handle_failed, -}; - -static void registry_handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, wl_output_interface.name) == 0) { - struct output *output = calloc(1, sizeof(*output)); - output->wl_output = wl_registry_bind(registry, name, - &wl_output_interface, 1); - wl_list_insert(&outputs, &output->link); - } else if (strcmp(interface, - zwlr_gamma_control_manager_v1_interface.name) == 0) { - gamma_control_manager = wl_registry_bind(registry, name, - &zwlr_gamma_control_manager_v1_interface, 1); - } -} - -static void registry_handle_global_remove(void *data, - struct wl_registry *registry, uint32_t name) { - // Who cares? -} - -static const struct wl_registry_listener registry_listener = { - .global = registry_handle_global, - .global_remove = registry_handle_global_remove, -}; - -static void fill_gamma_table(uint16_t *table, uint32_t ramp_size, - double contrast, double brightness, double gamma) { - uint16_t *r = table; - uint16_t *g = table + ramp_size; - uint16_t *b = table + 2 * ramp_size; - for (uint32_t i = 0; i < ramp_size; ++i) { - double val = (double)i / (ramp_size - 1); - val = contrast * pow(val, 1.0 / gamma) + (brightness - 1); - if (val > 1.0) { - val = 1.0; - } else if (val < 0.0) { - val = 0.0; - } - r[i] = g[i] = b[i] = (uint16_t)(UINT16_MAX * val); - } -} - -static const char usage[] = "usage: gamma-control [options]\n" - " -h show this help message\n" - " -c <value> set contrast (default: 1)\n" - " -b <value> set brightness (default: 1)\n" - " -g <value> set gamma (default: 1)\n"; - -int main(int argc, char *argv[]) { - wl_list_init(&outputs); - - double contrast = 1, brightness = 1, gamma = 1; - int opt; - while ((opt = getopt(argc, argv, "hc:b:g:")) != -1) { - switch (opt) { - case 'c': - contrast = strtod(optarg, NULL); - break; - case 'b': - brightness = strtod(optarg, NULL); - break; - case 'g': - gamma = strtod(optarg, NULL); - break; - case 'h': - default: - fprintf(stderr, usage); - return opt == 'h' ? EXIT_SUCCESS : EXIT_FAILURE; - } - } - - struct wl_display *display = wl_display_connect(NULL); - if (display == NULL) { - fprintf(stderr, "failed to create display\n"); - return -1; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (gamma_control_manager == NULL) { - fprintf(stderr, - "compositor doesn't support wlr-gamma-control-unstable-v1\n"); - return EXIT_FAILURE; - } - - struct output *output; - wl_list_for_each(output, &outputs, link) { - output->gamma_control = zwlr_gamma_control_manager_v1_get_gamma_control( - gamma_control_manager, output->wl_output); - zwlr_gamma_control_v1_add_listener(output->gamma_control, - &gamma_control_listener, output); - } - wl_display_roundtrip(display); - - wl_list_for_each(output, &outputs, link) { - fill_gamma_table(output->table, output->ramp_size, - contrast, brightness, gamma); - zwlr_gamma_control_v1_set_gamma(output->gamma_control, - output->table_fd); - } - - while (wl_display_dispatch(display) != -1) { - // This space is intentionnally left blank - } - - return EXIT_SUCCESS; -} diff --git a/examples/idle-inhibit.c b/examples/idle-inhibit.c deleted file mode 100644 index ff5a879e..00000000 --- a/examples/idle-inhibit.c +++ /dev/null @@ -1,227 +0,0 @@ -#include <GLES2/gl2.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <wayland-client.h> -#include <wayland-egl.h> -#include "egl_common.h" -#include "idle-inhibit-unstable-v1-client-protocol.h" -#include "xdg-shell-client-protocol.h" - -#include <linux/input-event-codes.h> - -/** - * Usage: idle-inhibit - * Creates a xdg-toplevel using the idle-inhibit protocol. - * It will be solid green, when it has an idle inhibitor, and solid yellow if - * it does not. - * Left click with a pointer will toggle this state. (Touch is not supported - * for now). - */ - -static int width = 500, height = 300; - -static struct wl_compositor *compositor = NULL; -static struct wl_seat *seat = NULL; -static struct xdg_wm_base *wm_base = NULL; -static struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager = NULL; -static struct zwp_idle_inhibitor_v1 *idle_inhibitor = NULL; - -struct wl_egl_window *egl_window; -struct wlr_egl_surface *egl_surface; - -static void draw(void) { - eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context); - - float color[] = {1.0, 1.0, 0.0, 1.0}; - if (idle_inhibitor) { - color[0] = 0.0; - } - - glViewport(0, 0, width, height); - glClearColor(color[0], color[1], color[2], 1.0); - glClear(GL_COLOR_BUFFER_BIT); - - eglSwapBuffers(egl_display, egl_surface); -} - -static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, - uint32_t time, uint32_t button, uint32_t state_w) { - struct wl_surface *surface = data; - - if (button == BTN_LEFT && state_w == WL_POINTER_BUTTON_STATE_PRESSED) { - if (idle_inhibitor) { - zwp_idle_inhibitor_v1_destroy(idle_inhibitor); - idle_inhibitor = NULL; - } else { - idle_inhibitor = zwp_idle_inhibit_manager_v1_create_inhibitor( - idle_inhibit_manager, surface); - } - } - - draw(); -} - -static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface, - wl_fixed_t surface_x, wl_fixed_t surface_y) { - // This space intentionally left blank -} - -static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface) { - // This space intentionally left blank -} - -static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, - uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { - // This space intentionally left blank -} - -static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, - uint32_t time, uint32_t axis, wl_fixed_t value) { - // This space intentionally left blank -} - -static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) { - // This space intentionally left blank -} - -static void pointer_handle_axis_source(void *data, - struct wl_pointer *wl_pointer, uint32_t axis_source) { - // This space intentionally left blank -} - -static void pointer_handle_axis_stop(void *data, - struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis) { - // This space intentionally left blank -} - -static void pointer_handle_axis_discrete(void *data, - struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete) { - // This space intentionally left blank -} - -static const struct wl_pointer_listener pointer_listener = { - .enter = pointer_handle_enter, - .leave = pointer_handle_leave, - .motion = pointer_handle_motion, - .button = pointer_handle_button, - .axis = pointer_handle_axis, - .frame = pointer_handle_frame, - .axis_source = pointer_handle_axis_source, - .axis_stop = pointer_handle_axis_stop, - .axis_discrete = pointer_handle_axis_discrete, -}; - -static void xdg_surface_handle_configure(void *data, - struct xdg_surface *xdg_surface, uint32_t serial) { - xdg_surface_ack_configure(xdg_surface, serial); - wl_egl_window_resize(egl_window, width, height, 0, 0); - draw(); -} - -static const struct xdg_surface_listener xdg_surface_listener = { - .configure = xdg_surface_handle_configure, -}; - -static void xdg_toplevel_handle_configure(void *data, - struct xdg_toplevel *xdg_toplevel, int32_t w, int32_t h, - struct wl_array *states) { - width = w; - height = h; -} - -static void xdg_toplevel_handle_close(void *data, - struct xdg_toplevel *xdg_toplevel) { - exit(EXIT_SUCCESS); -} - -static const struct xdg_toplevel_listener xdg_toplevel_listener = { - .configure = xdg_toplevel_handle_configure, - .close = xdg_toplevel_handle_close, -}; - -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, "wl_compositor") == 0) { - compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 1); - } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { - wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); - } else if (strcmp(interface, zwp_idle_inhibit_manager_v1_interface.name) == 0) { - idle_inhibit_manager = wl_registry_bind(registry, name, - &zwp_idle_inhibit_manager_v1_interface, 1); - } else if (strcmp(interface, wl_seat_interface.name) == 0) { - seat = wl_registry_bind(registry, name, &wl_seat_interface, version); - } -} - -static void handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) { - // who cares -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = handle_global_remove, -}; - -int main(int argc, char **argv) { - struct wl_display *display = wl_display_connect(NULL); - if (display == NULL) { - fprintf(stderr, "Failed to create display\n"); - return EXIT_FAILURE; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (compositor == NULL) { - fprintf(stderr, "wl-compositor not available\n"); - return EXIT_FAILURE; - } - if (wm_base == NULL) { - fprintf(stderr, "xdg-shell not available\n"); - return EXIT_FAILURE; - } - if (idle_inhibit_manager == NULL) { - fprintf(stderr, "idle-inhibit not available\n"); - return EXIT_FAILURE; - } - - egl_init(display); - - struct wl_surface *surface = wl_compositor_create_surface(compositor); - struct xdg_surface *xdg_surface = - xdg_wm_base_get_xdg_surface(wm_base, surface); - struct xdg_toplevel *xdg_toplevel = xdg_surface_get_toplevel(xdg_surface); - - idle_inhibitor = - zwp_idle_inhibit_manager_v1_create_inhibitor(idle_inhibit_manager, - surface); - - struct wl_pointer *pointer = wl_seat_get_pointer(seat); - wl_pointer_add_listener(pointer, &pointer_listener, surface); - - - xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL); - xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL); - - wl_surface_commit(surface); - - egl_window = wl_egl_window_create(surface, width, height); - egl_surface = eglCreatePlatformWindowSurfaceEXT( - egl_display, egl_config, egl_window, NULL); - - wl_display_roundtrip(display); - - draw(); - - while (wl_display_dispatch(display) != -1) { - // This space intentionally left blank - } - - return EXIT_SUCCESS; -} diff --git a/examples/input-inhibitor.c b/examples/input-inhibitor.c deleted file mode 100644 index 6440b2b7..00000000 --- a/examples/input-inhibitor.c +++ /dev/null @@ -1,187 +0,0 @@ -#include <GLES2/gl2.h> -#include <assert.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <wayland-client.h> -#include <wayland-egl.h> -#include "egl_common.h" -#include "wlr-input-inhibitor-unstable-v1-client-protocol.h" -#include "xdg-shell-client-protocol.h" - -static int width = 500, height = 300; -static int keys = 0; - -static struct wl_compositor *compositor = NULL; -static struct wl_seat *seat = NULL; -static struct xdg_wm_base *wm_base = NULL; -static struct zwlr_input_inhibit_manager_v1 *input_inhibit_manager = NULL; -static struct zwlr_input_inhibitor_v1 *input_inhibitor = NULL; - -struct wl_egl_window *egl_window; -struct wlr_egl_surface *egl_surface; - -static void render_frame(void) { - eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context); - - glViewport(0, 0, width, height); - if (keys) { - glClearColor(1.0, 1.0, 1.0, 1.0); - } else { - glClearColor(0.8, 0.4, 1.0, 1.0); - } - glClear(GL_COLOR_BUFFER_BIT); - - eglSwapBuffers(egl_display, egl_surface); -} - -static void xdg_surface_handle_configure(void *data, - struct xdg_surface *xdg_surface, uint32_t serial) { - xdg_surface_ack_configure(xdg_surface, serial); - wl_egl_window_resize(egl_window, width, height, 0, 0); - render_frame(); -} - -static const struct xdg_surface_listener xdg_surface_listener = { - .configure = xdg_surface_handle_configure, -}; - -static void xdg_toplevel_handle_configure(void *data, - struct xdg_toplevel *xdg_toplevel, int32_t w, int32_t h, - struct wl_array *states) { - width = w; - height = h; -} - -static void xdg_toplevel_handle_close(void *data, - struct xdg_toplevel *xdg_toplevel) { - exit(0); -} - -static const struct xdg_toplevel_listener xdg_toplevel_listener = { - .configure = xdg_toplevel_handle_configure, - .close = xdg_toplevel_handle_close, -}; - -static void wl_keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, - uint32_t format, int32_t fd, uint32_t size) { -} -static void wl_keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, struct wl_surface *surface, struct wl_array *keys) { -} -static void wl_keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, struct wl_surface *surface) { -} -static void wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { -} -static void wl_keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, - int32_t rate, int32_t delay) { -} - -static void wl_keyboard_key(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { - if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { - ++keys; - } else { - --keys; - } - render_frame(); -} - -static struct wl_keyboard_listener keyboard_listener = { - .keymap = wl_keyboard_keymap, - .enter = wl_keyboard_enter, - .leave = wl_keyboard_leave, - .key = wl_keyboard_key, - .modifiers = wl_keyboard_modifiers, - .repeat_info = wl_keyboard_repeat_info, -}; - -static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, - enum wl_seat_capability caps) { - if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { - struct wl_keyboard *keyboard = wl_seat_get_keyboard(wl_seat); - wl_keyboard_add_listener(keyboard, &keyboard_listener, NULL); - } -} - -static void seat_handle_name(void *data, struct wl_seat *wl_seat, - const char *name) { - // Who cares -} - -const struct wl_seat_listener seat_listener = { - .capabilities = seat_handle_capabilities, - .name = seat_handle_name, -}; - -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, wl_compositor_interface.name) == 0) { - compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 1); - } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { - wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); - } else if (strcmp(interface, zwlr_input_inhibit_manager_v1_interface.name) == 0) { - input_inhibit_manager = wl_registry_bind(registry, name, - &zwlr_input_inhibit_manager_v1_interface, 1); - } else if (strcmp(interface, wl_seat_interface.name) == 0) { - seat = wl_registry_bind(registry, name, &wl_seat_interface, version); - wl_seat_add_listener(seat, &seat_listener, seat); - } -} - -static void handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) { - // who cares -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = handle_global_remove, -}; - -int main(int argc, char **argv) { - struct wl_display *display = wl_display_connect(NULL); - assert(display); - struct wl_registry *registry = wl_display_get_registry(display); - assert(registry); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - assert(compositor && seat && wm_base && input_inhibit_manager); - - input_inhibitor = zwlr_input_inhibit_manager_v1_get_inhibitor( - input_inhibit_manager); - assert(input_inhibitor); - - egl_init(display); - - struct wl_surface *surface = wl_compositor_create_surface(compositor); - assert(surface); - struct xdg_surface *xdg_surface = - xdg_wm_base_get_xdg_surface(wm_base, surface); - assert(xdg_surface); - struct xdg_toplevel *xdg_toplevel = xdg_surface_get_toplevel(xdg_surface); - assert(xdg_toplevel); - - xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL); - xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL); - - wl_surface_commit(surface); - - egl_window = wl_egl_window_create(surface, width, height); - egl_surface = eglCreatePlatformWindowSurfaceEXT( - egl_display, egl_config, egl_window, NULL); - - wl_display_roundtrip(display); - - render_frame(); - - while (wl_display_dispatch(display) != -1) { - // This space intentionally left blank - } - - return 0; -} diff --git a/examples/input-method-keyboard-grab.c b/examples/input-method-keyboard-grab.c deleted file mode 100644 index 055abeab..00000000 --- a/examples/input-method-keyboard-grab.c +++ /dev/null @@ -1,216 +0,0 @@ -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/mman.h> -#include <unistd.h> -#include <wayland-client.h> -#include <xkbcommon/xkbcommon.h> -#include "input-method-unstable-v2-client-protocol.h" - -static struct wl_display *display = NULL; -static struct wl_seat *seat = NULL; -static struct zwp_input_method_manager_v2 *input_method_manager = NULL; -static struct zwp_input_method_v2 *input_method = NULL; -static struct zwp_input_method_keyboard_grab_v2 *kb_grab = NULL; - -static bool active = false; -static bool pending_active = false; - -static struct xkb_context *xkb_context = NULL; -static struct xkb_keymap *keymap = NULL; -static struct xkb_state *xkb_state = NULL; - -static void handle_key(void *data, - struct zwp_input_method_keyboard_grab_v2 *im_keyboard_grab, - uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { - printf("handle_key %u %u %u %u\n", serial, time, key, state); - xkb_keysym_t keysym = xkb_state_key_get_one_sym(xkb_state, key + 8); - char keysym_name[64]; - xkb_keysym_get_name(keysym, keysym_name, sizeof(keysym_name)); - printf("xkb translated to %s\n", keysym_name); - if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { - if (keysym == XKB_KEY_KP_Enter || keysym == XKB_KEY_Return) { - printf("Stopping grab\n"); - zwp_input_method_keyboard_grab_v2_release(kb_grab); - kb_grab = NULL; - } - } - -} - -static void handle_modifiers(void *data, - struct zwp_input_method_keyboard_grab_v2 *im_keyboard_grab, - uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { - printf("handle_modifiers %u %u %u %u %u\n", serial, mods_depressed, - mods_latched, mods_locked, group); - xkb_state_update_mask(xkb_state, mods_depressed, mods_latched, - mods_locked, 0, 0, group); -} - -static void handle_keymap(void *data, - struct zwp_input_method_keyboard_grab_v2 *im_keyboard_grab, - uint32_t format, int32_t fd, uint32_t size) { - printf("handle_keymap\n"); - char *keymap_string = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); - xkb_keymap_unref(keymap); - keymap = xkb_keymap_new_from_string(xkb_context, keymap_string, - XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); - munmap(keymap_string, size); - close(fd); - xkb_state_unref(xkb_state); - xkb_state = xkb_state_new(keymap); -} - -static void handle_repeat_info(void *data, - struct zwp_input_method_keyboard_grab_v2 *im_keyboard_grab, - int32_t rate, int32_t delay) { - printf("handle_repeat_info %d %d", rate, delay); -} - - -static const struct zwp_input_method_keyboard_grab_v2_listener grab_listener = { - .key = handle_key, - .modifiers = handle_modifiers, - .keymap = handle_keymap, - .repeat_info = handle_repeat_info, -}; - -static void handle_activate(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2) { - pending_active = true; -} - -static void handle_deactivate(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2) { - pending_active = false; -} - -static void handle_unavailable(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2) { - printf("IM unavailable\n"); - zwp_input_method_v2_destroy(zwp_input_method_v2); - input_method = NULL; -} - -static void im_activate(void *data, - struct zwp_input_method_v2 *id) { - kb_grab = zwp_input_method_v2_grab_keyboard(input_method); - if (kb_grab == NULL) { - fprintf(stderr, "Failed to grab\n"); - exit(EXIT_FAILURE); - } - zwp_input_method_keyboard_grab_v2_add_listener(kb_grab, &grab_listener, - NULL); - printf("Started grab, press enter to stop grab\n"); -} - -static void im_deactivate(void *data, - struct zwp_input_method_v2 *context) { - if (kb_grab != NULL) { - zwp_input_method_keyboard_grab_v2_release(kb_grab); - kb_grab = NULL; - } -} - -static void handle_done(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2) { - bool prev_active = active; - if (active != pending_active) { - printf("Now %s\n", pending_active ? "active" : "inactive"); - } - active = pending_active; - if (active && !prev_active) { - im_activate(data, zwp_input_method_v2); - } else if (!active && prev_active) { - im_deactivate(data, zwp_input_method_v2); - } -} - -static void handle_surrounding_text(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2, - const char *text, uint32_t cursor, uint32_t anchor) { - // not for this test -} - -static void handle_text_change_cause(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2, - uint32_t cause) { - // not for this test -} - -static void handle_content_type(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2, - uint32_t hint, uint32_t purpose) { - // not for this test -} - -static const struct zwp_input_method_v2_listener im_listener = { - .activate = handle_activate, - .deactivate = handle_deactivate, - .surrounding_text = handle_surrounding_text, - .text_change_cause = handle_text_change_cause, - .content_type = handle_content_type, - .done = handle_done, - .unavailable = handle_unavailable, -}; - -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, zwp_input_method_manager_v2_interface.name) == 0) { - input_method_manager = wl_registry_bind(registry, name, - &zwp_input_method_manager_v2_interface, 1); - } else if (strcmp(interface, wl_seat_interface.name) == 0) { - seat = wl_registry_bind(registry, name, &wl_seat_interface, version); - } -} - -static void handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) { - // who cares -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = handle_global_remove, -}; - -int main(int argc, char **argv) { - xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - if (xkb_context == NULL) { - fprintf(stderr, "Failed to create xkb context\n"); - return EXIT_FAILURE; - } - - display = wl_display_connect(NULL); - if (display == NULL) { - fprintf(stderr, "Failed to create display\n"); - return EXIT_FAILURE; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (input_method_manager == NULL) { - fprintf(stderr, "input-method not available\n"); - return EXIT_FAILURE; - } - if (seat == NULL) { - fprintf(stderr, "seat not available\n"); - return EXIT_FAILURE; - } - - input_method = zwp_input_method_manager_v2_get_input_method( - input_method_manager, seat); - zwp_input_method_v2_add_listener(input_method, &im_listener, NULL); - - wl_display_roundtrip(display); - - while (wl_display_dispatch(display) != -1) { - // This space is intentionally left blank - }; - - return EXIT_SUCCESS; -} diff --git a/examples/input-method.c b/examples/input-method.c deleted file mode 100644 index 849971b9..00000000 --- a/examples/input-method.c +++ /dev/null @@ -1,401 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#include <assert.h> -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/epoll.h> -#include <sys/timerfd.h> -#include <unistd.h> -#include <wayland-client.h> -#include <wayland-egl.h> -#include "input-method-unstable-v2-client-protocol.h" -#include "text-input-unstable-v3-client-protocol.h" -#include "xdg-shell-client-protocol.h" - -const char usage[] = "Usage: input-method [seconds]\n\ -\n\ -Creates an input method using the input-method protocol.\n\ -\n\ -Whenever a text input is activated, this program sends a few sequences of\n\ -commands and checks the validity of the responses, relying on returned\n\ -surrounding text.\n\ -\n\ -The \"seconds\" argument is optional and defines the maximum delay between\n\ -stages."; - -struct input_method_state { - enum zwp_text_input_v3_change_cause change_cause; - struct { - enum zwp_text_input_v3_content_hint hint; - enum zwp_text_input_v3_content_purpose purpose; - } content_type; - struct { - char *text; - uint32_t cursor; - uint32_t anchor; - } surrounding; -}; - -static int sleeptime = 0; - -static struct wl_display *display = NULL; -static struct wl_compositor *compositor = NULL; -static struct wl_seat *seat = NULL; -static struct zwp_input_method_manager_v2 *input_method_manager = NULL; -static struct zwp_input_method_v2 *input_method = NULL; - -struct input_method_state pending; -struct input_method_state current; - -static uint32_t serial = 0; -bool active = false; -bool pending_active = false; -bool unavailable = false; -bool running = false; - -uint32_t update_stage = 0; - -int timer_fd = 0; - -static void print_state_diff(struct input_method_state previous, - struct input_method_state future) { - if (previous.content_type.hint != future.content_type.hint) { - char *strs[] = { "COMPLETION", "SPELLCHECK", "AUTO_CAPITALIZATION", - "LOWERCASE", "UPPERCASE", "TITLECASE", "HIDDEN_TEXT", - "SENSITIVE_DATA", "LATIN", "MULTILINE"}; - printf("content_type.hint:"); - uint32_t hint = future.content_type.hint; - if (!hint) { - printf(" NONE"); - } - for (unsigned i = 0; i < sizeof(strs) / sizeof(*strs); i++) { - if (hint & 1 << i) { - printf(" %s", strs[i]); - } - } - printf("\n"); - } - if (previous.content_type.purpose != future.content_type.purpose) { - char *strs[] = { "NORMAL", "ALPHA", "DIGITS", "NUMBER", "PHONE", "URL", - "EMAIL", "NAME", "PASSWORD", "PIN", "DATE", "TIME", "DATETIME", - "TERMINAL" }; - printf("content_type.purpose: %s\n", strs[future.content_type.purpose]); - } - if (!!previous.surrounding.text != !!future.surrounding.text - || (previous.surrounding.text && future.surrounding.text - && strcmp(previous.surrounding.text, future.surrounding.text) != 0) - || previous.surrounding.anchor != future.surrounding.anchor - || previous.surrounding.cursor != future.surrounding.cursor) { - char *text = future.surrounding.text; - if (!text) { - printf("Removed surrounding text\n"); - } else { - printf("Surrounding text: %s\n", text); - uint32_t anchor = future.surrounding.anchor; - uint32_t cursor = future.surrounding.cursor; - if (cursor == anchor) { - char *temp = strndup(text, cursor); - printf("Cursor after %d: %s\n", cursor, temp); - free(temp); - } else { - if (cursor > anchor) { - uint32_t tmp = anchor; - anchor = cursor; - cursor = tmp; - } - char *temp = strndup(&text[cursor], anchor - cursor); - printf("Selection: %s\n", temp); - free(temp); - } - } - } - if (previous.change_cause != future.change_cause) { - char *strs[] = { "INPUT_METHOD", "OTHER" }; - printf("Change cause: %s\n", strs[future.change_cause]); - } -} - -static void handle_content_type(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2, - uint32_t hint, uint32_t purpose) { - pending.content_type.hint = hint; - pending.content_type.purpose = purpose; -} - -static void handle_surrounding_text(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2, - const char *text, uint32_t cursor, uint32_t anchor) { - free(pending.surrounding.text); - pending.surrounding.text = strdup(text); - pending.surrounding.cursor = cursor; - pending.surrounding.anchor = anchor; -} - -static void handle_text_change_cause(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2, - uint32_t cause) { - pending.change_cause = cause; -} - -static void handle_activate(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2) { - pending_active = true; -} - -static void handle_deactivate(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2) { - pending_active = false; -} - -static void handle_unavailable(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2) { - printf("IM disappeared\n"); - zwp_input_method_v2_destroy(zwp_input_method_v2); - input_method = NULL; - running = false; -} - -static void im_activate(void *data, - struct zwp_input_method_v2 *id) { - update_stage = 0; -} - -static void timer_arm(unsigned seconds) { - printf("Timer armed\n"); - struct itimerspec spec = { - .it_interval = {0}, - .it_value = { - .tv_sec = seconds, - .tv_nsec = 0 - } - }; - if (timerfd_settime(timer_fd, 0, &spec, NULL)) { - fprintf(stderr, "Failed to arm timer: %s\n", strerror(errno)); - } -} - -static void do_updates(void) { - printf("Update %d\n", update_stage); - switch (update_stage) { - case 0: - // TODO: remember initial surrounding text - zwp_input_method_v2_set_preedit_string(input_method, "Preedit", 2, 4); - zwp_input_method_v2_commit(input_method, serial); - // don't expect an answer, preedit doesn't change anything visible - timer_arm(sleeptime); - update_stage++; - return; - case 1: - zwp_input_method_v2_set_preedit_string(input_method, "Præedit2", strlen("Pr"), strlen("Præed")); - zwp_input_method_v2_commit_string(input_method, "_Commit_"); - zwp_input_method_v2_commit(input_method, serial); - update_stage++; - break; - case 2: - if (current.surrounding.text && strcmp(current.surrounding.text, "_Commit_") != 0) { - return; - } - zwp_input_method_v2_commit_string(input_method, "_CommitNoPreed_"); - zwp_input_method_v2_commit(input_method, serial); - timer_arm(sleeptime); - update_stage++; - break; - case 3: - if (current.surrounding.text && strcmp(current.surrounding.text, "_Commit__CommitNoPreed_") != 0) { - return; - } - zwp_input_method_v2_commit_string(input_method, "_WaitNo_"); - zwp_input_method_v2_delete_surrounding_text(input_method, strlen("_CommitNoPreed_"), 0); - zwp_input_method_v2_commit(input_method, serial); - update_stage++; - break; - case 4: - if (current.surrounding.text && strcmp(current.surrounding.text, "_Commit__WaitNo_") != 0) { - return; - } - zwp_input_method_v2_set_preedit_string(input_method, "PreedWithDel", strlen("Preed"), strlen("Preed")); - zwp_input_method_v2_delete_surrounding_text(input_method, strlen("_WaitNo_"), 0); - zwp_input_method_v2_commit(input_method, serial); - update_stage++; - break; - case 5: - if (current.surrounding.text && strcmp(current.surrounding.text, "_Commit_") != 0) { - return; - } - zwp_input_method_v2_delete_surrounding_text(input_method, strlen("mit_"), 0); - zwp_input_method_v2_commit(input_method, serial); - update_stage++; - break; - case 6: - if (current.surrounding.text && strcmp(current.surrounding.text, "_Com") != 0) { - printf("Failed\n"); - } - update_stage++; - break; - default: - printf("Submitted everything\n"); - return; - }; -} - -static void handle_timer(void) { - printf("Timer dispatched at %d\n", update_stage); - do_updates(); -} - -static void im_deactivate(void *data, - struct zwp_input_method_v2 *context) { - // No special action needed -} - -static void handle_done(void *data, - struct zwp_input_method_v2 *zwp_input_method_v2) { - bool prev_active = active; - serial++; - printf("Handle serial %d\n", serial); - if (active != pending_active) { - printf("Now %s\n", pending_active ? "active" : "inactive"); - } - if (pending_active) { - print_state_diff(current, pending); - } - active = pending_active; - free(current.surrounding.text); - struct input_method_state default_state = {0}; - current = pending; - pending = default_state; - if (active && !prev_active) { - im_activate(data, zwp_input_method_v2); - } else if (!active && prev_active) { - im_deactivate(data, zwp_input_method_v2); - } - - do_updates(); -} - -static const struct zwp_input_method_v2_listener im_listener = { - .activate = handle_activate, - .deactivate = handle_deactivate, - .surrounding_text = handle_surrounding_text, - .text_change_cause = handle_text_change_cause, - .content_type = handle_content_type, - .done = handle_done, - .unavailable = handle_unavailable, -}; - -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, "wl_compositor") == 0) { - compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 1); - } else if (strcmp(interface, zwp_input_method_manager_v2_interface.name) == 0) { - input_method_manager = wl_registry_bind(registry, name, - &zwp_input_method_manager_v2_interface, 1); - } else if (strcmp(interface, wl_seat_interface.name) == 0) { - seat = wl_registry_bind(registry, name, &wl_seat_interface, version); - } -} - -static void handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) { - // who cares -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = handle_global_remove, -}; - -int main(int argc, char **argv) { - if (argc > 1) { - if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) { - printf(usage); - return 0; - } - sleeptime = atoi(argv[1]); - } - display = wl_display_connect(NULL); - if (display == NULL) { - fprintf(stderr, "Failed to create display\n"); - return EXIT_FAILURE; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (compositor == NULL) { - fprintf(stderr, "wl-compositor not available\n"); - return EXIT_FAILURE; - } - if (input_method_manager == NULL) { - fprintf(stderr, "input-method not available\n"); - return EXIT_FAILURE; - } - if (seat == NULL) { - fprintf(stderr, "seat not available\n"); - return EXIT_FAILURE; - } - - input_method = zwp_input_method_manager_v2_get_input_method( - input_method_manager, seat); - running = true; - zwp_input_method_v2_add_listener(input_method, &im_listener, NULL); - - int display_fd = wl_display_get_fd(display); - timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); - if (timer_fd < 0) { - fprintf(stderr, "Failed to start timer\n"); - return EXIT_FAILURE; - } - int epoll = epoll_create1(EPOLL_CLOEXEC); - if (epoll < 0) { - fprintf(stderr, "Failed to start epoll\n"); - return EXIT_FAILURE; - } - - struct epoll_event epoll_display = { - .events = EPOLLIN | EPOLLOUT, - .data = {.fd = display_fd}, - }; - if (epoll_ctl(epoll, EPOLL_CTL_ADD, display_fd, &epoll_display)) { - fprintf(stderr, "Failed to epoll display\n"); - return EXIT_FAILURE; - } - - wl_display_roundtrip(display); // timer may be armed here - - struct epoll_event epoll_timer = { - .events = EPOLLIN, - .data = {.fd = timer_fd}, - }; - if (epoll_ctl(epoll, EPOLL_CTL_ADD, timer_fd, &epoll_timer)) { - fprintf(stderr, "Failed to epoll timer\n"); - return EXIT_FAILURE; - } - - timer_arm(2); - - struct epoll_event caught; - while (epoll_wait(epoll, &caught, 1, -1)) { - if (!running) { - printf("Exiting\n"); - return EXIT_SUCCESS; - } - if (caught.data.fd == display_fd) { - if (wl_display_dispatch(display) == -1) { - break; - } - } else if (caught.data.fd == timer_fd) { - uint64_t expirations; - ssize_t n = read(timer_fd, &expirations, sizeof(expirations)); - assert(n >= 0); - handle_timer(); - } else { - printf("Unknown source\n"); - } - } - return EXIT_SUCCESS; -} diff --git a/examples/keyboard-shortcuts-inhibit.c b/examples/keyboard-shortcuts-inhibit.c deleted file mode 100644 index ab64277e..00000000 --- a/examples/keyboard-shortcuts-inhibit.c +++ /dev/null @@ -1,261 +0,0 @@ -#include <GLES2/gl2.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <wayland-client.h> -#include <wayland-egl.h> -#include "egl_common.h" -#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h" -#include "xdg-shell-client-protocol.h" - -#include <linux/input-event-codes.h> - -/** - * Usage: keyboard-shortcuts-inhibit - * Creates a xdg-toplevel using the keyboard-shortcuts-inhibit protocol. - * It will be solid green, when it has an keyboard shortcuts inhibitor, and - * solid yellow if it does not. - * Left click with a pointer will toggle this state. (Touch is not supported - * for now). - * The compositor (de-)activating the inhibitor will also toggle state. - * With a compositor supporting the protocol, compositor shortcuts will be - * suspended while the inhibitor is active and the window has focus. - */ - -static int width = 500, height = 300; - -static struct wl_compositor *compositor = NULL; -static struct wl_seat *seat = NULL; -static struct xdg_wm_base *wm_base = NULL; -static struct zwp_keyboard_shortcuts_inhibit_manager_v1 * - keyboard_shortcuts_inhibit_manager = NULL; -static struct zwp_keyboard_shortcuts_inhibitor_v1 * - keyboard_shortcuts_inhibitor = NULL; -static bool active = false; - -struct wl_egl_window *egl_window; -struct wlr_egl_surface *egl_surface; - -static void draw(void) { - eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context); - - float color[] = {1.0, 1.0, 0.0, 1.0}; - if (keyboard_shortcuts_inhibitor) { - color[0] = 0.0; - } - - glViewport(0, 0, width, height); - glClearColor(color[0], color[1], color[2], 1.0); - glClear(GL_COLOR_BUFFER_BIT); - - eglSwapBuffers(egl_display, egl_surface); -} - -static void keyboard_shortcuts_inhibit_handle_active(void *data, - struct zwp_keyboard_shortcuts_inhibitor_v1 * - zwp_keyboard_shortcuts_inhibitor_v1) { - active = 1; - draw(); -} - -static void keyboard_shortcuts_inhibit_handle_inactive(void *data, - struct zwp_keyboard_shortcuts_inhibitor_v1 * - zwp_keyboard_shortcuts_inhibitor_v1) { - active = 0; - draw(); -} - -static const struct zwp_keyboard_shortcuts_inhibitor_v1_listener -keyboard_shortcuts_inhibitor_listener = { - .active = keyboard_shortcuts_inhibit_handle_active, - .inactive = keyboard_shortcuts_inhibit_handle_inactive, -}; - -static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, - uint32_t time, uint32_t button, uint32_t state_w) { - struct wl_surface *surface = data; - - if (button == BTN_LEFT && state_w == WL_POINTER_BUTTON_STATE_PRESSED) { - if (keyboard_shortcuts_inhibitor) { - zwp_keyboard_shortcuts_inhibitor_v1_destroy( - keyboard_shortcuts_inhibitor); - keyboard_shortcuts_inhibitor = NULL; - active = false; - } else { - keyboard_shortcuts_inhibitor = - zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts( - keyboard_shortcuts_inhibit_manager, surface, seat); - zwp_keyboard_shortcuts_inhibitor_v1_add_listener( - keyboard_shortcuts_inhibitor, - &keyboard_shortcuts_inhibitor_listener, NULL); - } - } - - draw(); -} - -static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface, - wl_fixed_t surface_x, wl_fixed_t surface_y) { - // This space intentionally left blank -} - -static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface) { - // This space intentionally left blank -} - -static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, - uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { - // This space intentionally left blank -} - -static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, - uint32_t time, uint32_t axis, wl_fixed_t value) { - // This space intentionally left blank -} - -static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) { - // This space intentionally left blank -} - -static void pointer_handle_axis_source(void *data, - struct wl_pointer *wl_pointer, uint32_t axis_source) { - // This space intentionally left blank -} - -static void pointer_handle_axis_stop(void *data, - struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis) { - // This space intentionally left blank -} - -static void pointer_handle_axis_discrete(void *data, - struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete) { - // This space intentionally left blank -} - -static const struct wl_pointer_listener pointer_listener = { - .enter = pointer_handle_enter, - .leave = pointer_handle_leave, - .motion = pointer_handle_motion, - .button = pointer_handle_button, - .axis = pointer_handle_axis, - .frame = pointer_handle_frame, - .axis_source = pointer_handle_axis_source, - .axis_stop = pointer_handle_axis_stop, - .axis_discrete = pointer_handle_axis_discrete, -}; - -static void xdg_surface_handle_configure(void *data, - struct xdg_surface *xdg_surface, uint32_t serial) { - xdg_surface_ack_configure(xdg_surface, serial); - wl_egl_window_resize(egl_window, width, height, 0, 0); - draw(); -} - -static const struct xdg_surface_listener xdg_surface_listener = { - .configure = xdg_surface_handle_configure, -}; - -static void xdg_toplevel_handle_configure(void *data, - struct xdg_toplevel *xdg_toplevel, int32_t w, int32_t h, - struct wl_array *states) { - width = w; - height = h; -} - -static void xdg_toplevel_handle_close(void *data, - struct xdg_toplevel *xdg_toplevel) { - exit(EXIT_SUCCESS); -} - -static const struct xdg_toplevel_listener xdg_toplevel_listener = { - .configure = xdg_toplevel_handle_configure, - .close = xdg_toplevel_handle_close, -}; - -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, "wl_compositor") == 0) { - compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 1); - } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { - wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); - } else if (strcmp(interface, zwp_keyboard_shortcuts_inhibit_manager_v1_interface.name) == 0) { - keyboard_shortcuts_inhibit_manager = wl_registry_bind(registry, name, - &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1); - } else if (strcmp(interface, wl_seat_interface.name) == 0) { - seat = wl_registry_bind(registry, name, &wl_seat_interface, version); - } -} - -static void handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) { - // who cares -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = handle_global_remove, -}; - -int main(int argc, char **argv) { - struct wl_display *display = wl_display_connect(NULL); - if (display == NULL) { - fprintf(stderr, "Failed to create display\n"); - return EXIT_FAILURE; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (compositor == NULL) { - fprintf(stderr, "wl-compositor not available\n"); - return EXIT_FAILURE; - } - if (wm_base == NULL) { - fprintf(stderr, "xdg-shell not available\n"); - return EXIT_FAILURE; - } - if (keyboard_shortcuts_inhibit_manager == NULL) { - fprintf(stderr, "keyboard-shortcuts-inhibit not available\n"); - return EXIT_FAILURE; - } - - egl_init(display); - - struct wl_surface *surface = wl_compositor_create_surface(compositor); - struct xdg_surface *xdg_surface = - xdg_wm_base_get_xdg_surface(wm_base, surface); - struct xdg_toplevel *xdg_toplevel = xdg_surface_get_toplevel(xdg_surface); - - struct wl_pointer *pointer = wl_seat_get_pointer(seat); - wl_pointer_add_listener(pointer, &pointer_listener, surface); - - xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL); - xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL); - - wl_surface_commit(surface); - - egl_window = wl_egl_window_create(surface, width, height); - egl_surface = eglCreatePlatformWindowSurfaceEXT( - egl_display, egl_config, egl_window, NULL); - - wl_display_roundtrip(display); - - keyboard_shortcuts_inhibitor = - zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts( - keyboard_shortcuts_inhibit_manager, surface, seat); - zwp_keyboard_shortcuts_inhibitor_v1_add_listener( - keyboard_shortcuts_inhibitor, - &keyboard_shortcuts_inhibitor_listener, NULL); - - draw(); - - while (wl_display_dispatch(display) != -1) { - // This space intentionally left blank - } - - return EXIT_SUCCESS; -} diff --git a/examples/layer-shell.c b/examples/layer-shell.c deleted file mode 100644 index 5f86be8d..00000000 --- a/examples/layer-shell.c +++ /dev/null @@ -1,668 +0,0 @@ -#define _POSIX_C_SOURCE 200112L -#include <linux/input-event-codes.h> -#include <assert.h> -#include <GLES2/gl2.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include <wayland-client.h> -#include <wayland-cursor.h> -#include <wayland-egl.h> -#include "egl_common.h" -#include "wlr-layer-shell-unstable-v1-client-protocol.h" -#include "xdg-shell-client-protocol.h" - -static struct wl_display *display; -static struct wl_compositor *compositor; -static struct wl_seat *seat; -static struct wl_shm *shm; -static struct wl_pointer *pointer; -static struct wl_keyboard *keyboard; -static struct xdg_wm_base *xdg_wm_base; -static struct zwlr_layer_shell_v1 *layer_shell; - -struct zwlr_layer_surface_v1 *layer_surface; -static struct wl_output *wl_output; - -struct wl_surface *wl_surface; -struct wl_egl_window *egl_window; -struct wlr_egl_surface *egl_surface; -struct wl_callback *frame_callback; - -static uint32_t output = UINT32_MAX; -struct xdg_popup *popup; -struct wl_surface *popup_wl_surface; -struct wl_egl_window *popup_egl_window; -static uint32_t popup_width = 256, popup_height = 256; -struct wlr_egl_surface *popup_egl_surface; -struct wl_callback *popup_frame_callback; -float popup_alpha = 1.0, popup_red = 0.5f; - -static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; -static uint32_t anchor = 0; -static uint32_t width = 256, height = 256; -static int32_t margin_top = 0; -static double alpha = 1.0; -static bool run_display = true; -static bool animate = false; -static enum zwlr_layer_surface_v1_keyboard_interactivity keyboard_interactive = - ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE; -static double frame = 0; -static int cur_x = -1, cur_y = -1; -static int buttons = 0; - -struct wl_cursor_image *cursor_image; -struct wl_cursor_image *popup_cursor_image; -struct wl_surface *cursor_surface, *input_surface; - -static struct { - struct timespec last_frame; - float color[3]; - int dec; -} demo; - -static void draw(void); -static void draw_popup(void); - -static void surface_frame_callback( - void *data, struct wl_callback *cb, uint32_t time) { - wl_callback_destroy(cb); - frame_callback = NULL; - draw(); -} - -static struct wl_callback_listener frame_listener = { - .done = surface_frame_callback -}; - -static void popup_surface_frame_callback( - void *data, struct wl_callback *cb, uint32_t time) { - wl_callback_destroy(cb); - popup_frame_callback = NULL; - if (popup) { - draw_popup(); - } -} - -static struct wl_callback_listener popup_frame_listener = { - .done = popup_surface_frame_callback -}; - -static void draw(void) { - eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context); - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - - long ms = (ts.tv_sec - demo.last_frame.tv_sec) * 1000 + - (ts.tv_nsec - demo.last_frame.tv_nsec) / 1000000; - int inc = (demo.dec + 1) % 3; - - if (!buttons) { - demo.color[inc] += ms / 2000.0f; - demo.color[demo.dec] -= ms / 2000.0f; - - if (demo.color[demo.dec] < 0.0f) { - demo.color[inc] = 1.0f; - demo.color[demo.dec] = 0.0f; - demo.dec = inc; - } - } - - if (animate) { - frame += ms / 50.0; - int32_t old_top = margin_top; - margin_top = -(20 - ((int)frame % 20)); - if (old_top != margin_top) { - zwlr_layer_surface_v1_set_margin(layer_surface, - margin_top, 0, 0, 0); - wl_surface_commit(wl_surface); - } - } - - glViewport(0, 0, width, height); - if (buttons) { - glClearColor(alpha, alpha, alpha, alpha); - } else { - glClearColor(demo.color[0] * alpha, demo.color[1] * alpha, - demo.color[2] * alpha, alpha); - } - glClear(GL_COLOR_BUFFER_BIT); - - if (cur_x != -1 && cur_y != -1) { - glEnable(GL_SCISSOR_TEST); - glScissor(cur_x, height - cur_y, 5, 5); - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - glDisable(GL_SCISSOR_TEST); - } - - frame_callback = wl_surface_frame(wl_surface); - wl_callback_add_listener(frame_callback, &frame_listener, NULL); - - eglSwapBuffers(egl_display, egl_surface); - - demo.last_frame = ts; -} - -static void draw_popup(void) { - static float alpha_mod = -0.01; - - eglMakeCurrent(egl_display, popup_egl_surface, popup_egl_surface, egl_context); - glViewport(0, 0, popup_width, popup_height); - glClearColor(popup_red * popup_alpha, 0.5f * popup_alpha, - 0.5f * popup_alpha, popup_alpha); - popup_alpha += alpha_mod; - if (popup_alpha < 0.01 || popup_alpha >= 1.0f) { - alpha_mod *= -1.0; - } - glClear(GL_COLOR_BUFFER_BIT); - - popup_frame_callback = wl_surface_frame(popup_wl_surface); - assert(popup_frame_callback); - wl_callback_add_listener(popup_frame_callback, &popup_frame_listener, NULL); - eglSwapBuffers(egl_display, popup_egl_surface); - wl_surface_commit(popup_wl_surface); -} - -static void xdg_surface_handle_configure(void *data, - struct xdg_surface *xdg_surface, uint32_t serial) { - xdg_surface_ack_configure(xdg_surface, serial); -} - -static const struct xdg_surface_listener xdg_surface_listener = { - .configure = xdg_surface_handle_configure, -}; - -static void xdg_popup_configure(void *data, struct xdg_popup *xdg_popup, - int32_t x, int32_t y, int32_t width, int32_t height) { - fprintf(stderr, "Popup configured %dx%d@%d,%d\n", width, height, x, y); - popup_width = width; - popup_height = height; - if (popup_egl_window) { - wl_egl_window_resize(popup_egl_window, width, height, 0, 0); - } -} - -static void popup_destroy(void) { - eglDestroySurface(egl_display, popup_egl_surface); - wl_egl_window_destroy(popup_egl_window); - xdg_popup_destroy(popup); - wl_surface_destroy(popup_wl_surface); - popup_wl_surface = NULL; - popup = NULL; - popup_egl_window = NULL; -} - -static void xdg_popup_done(void *data, struct xdg_popup *xdg_popup) { - fprintf(stderr, "Popup done\n"); - popup_destroy(); -} - -static const struct xdg_popup_listener xdg_popup_listener = { - .configure = xdg_popup_configure, - .popup_done = xdg_popup_done, -}; - -static void create_popup(uint32_t serial) { - if (popup) { - return; - } - struct wl_surface *surface = wl_compositor_create_surface(compositor); - assert(xdg_wm_base && surface); - struct xdg_surface *xdg_surface = - xdg_wm_base_get_xdg_surface(xdg_wm_base, surface); - struct xdg_positioner *xdg_positioner = - xdg_wm_base_create_positioner(xdg_wm_base); - assert(xdg_surface && xdg_positioner); - - xdg_positioner_set_size(xdg_positioner, popup_width, popup_height); - xdg_positioner_set_offset(xdg_positioner, 0, 0); - xdg_positioner_set_anchor_rect(xdg_positioner, cur_x, cur_y, 1, 1); - xdg_positioner_set_anchor(xdg_positioner, XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT); - - popup = xdg_surface_get_popup(xdg_surface, NULL, xdg_positioner); - xdg_popup_grab(popup, seat, serial); - - assert(popup); - - zwlr_layer_surface_v1_get_popup(layer_surface, popup); - - xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL); - xdg_popup_add_listener(popup, &xdg_popup_listener, NULL); - - wl_surface_commit(surface); - wl_display_roundtrip(display); - - xdg_positioner_destroy(xdg_positioner); - - popup_wl_surface = surface; - popup_egl_window = wl_egl_window_create(surface, popup_width, popup_height); - assert(popup_egl_window); - popup_egl_surface = eglCreatePlatformWindowSurfaceEXT( - egl_display, egl_config, popup_egl_window, NULL); - assert(popup_egl_surface != EGL_NO_SURFACE); - draw_popup(); -} - -static void layer_surface_configure(void *data, - struct zwlr_layer_surface_v1 *surface, - uint32_t serial, uint32_t w, uint32_t h) { - width = w; - height = h; - if (egl_window) { - wl_egl_window_resize(egl_window, width, height, 0, 0); - } - zwlr_layer_surface_v1_ack_configure(surface, serial); -} - -static void layer_surface_closed(void *data, - struct zwlr_layer_surface_v1 *surface) { - eglDestroySurface(egl_display, egl_surface); - wl_egl_window_destroy(egl_window); - zwlr_layer_surface_v1_destroy(surface); - wl_surface_destroy(wl_surface); - run_display = false; -} - -struct zwlr_layer_surface_v1_listener layer_surface_listener = { - .configure = layer_surface_configure, - .closed = layer_surface_closed, -}; - -static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface, - wl_fixed_t surface_x, wl_fixed_t surface_y) { - struct wl_cursor_image *image; - if (surface == popup_wl_surface) { - image = popup_cursor_image; - } else { - image = cursor_image; - } - wl_surface_attach(cursor_surface, - wl_cursor_image_get_buffer(image), 0, 0); - wl_surface_damage(cursor_surface, 1, 0, - image->width, image->height); - wl_surface_commit(cursor_surface); - wl_pointer_set_cursor(wl_pointer, serial, cursor_surface, - image->hotspot_x, image->hotspot_y); - input_surface = surface; -} - -static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface) { - cur_x = cur_y = -1; - buttons = 0; -} - -static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, - uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { - cur_x = wl_fixed_to_int(surface_x); - cur_y = wl_fixed_to_int(surface_y); -} - -static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { - if (input_surface == wl_surface) { - if (state == WL_POINTER_BUTTON_STATE_PRESSED) { - if (button == BTN_RIGHT) { - if (popup_wl_surface) { - popup_destroy(); - } else { - create_popup(serial); - } - } else { - buttons++; - } - } else { - if (button != BTN_RIGHT) { - buttons--; - } - } - } else if (input_surface == popup_wl_surface) { - if (state == WL_POINTER_BUTTON_STATE_PRESSED) { - if (button == BTN_LEFT && popup_red <= 0.9f) { - popup_red += 0.1; - } else if (button == BTN_RIGHT && popup_red >= 0.1f) { - popup_red -= 0.1; - } - } - } else { - assert(false && "Unknown surface"); - } -} - -static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, - uint32_t time, uint32_t axis, wl_fixed_t value) { - // Who cares -} - -static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) { - // Who cares -} - -static void wl_pointer_axis_source(void *data, struct wl_pointer *wl_pointer, - uint32_t axis_source) { - // Who cares -} - -static void wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, - uint32_t time, uint32_t axis) { - // Who cares -} - -static void wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, - uint32_t axis, int32_t discrete) { - // Who cares -} - -struct wl_pointer_listener pointer_listener = { - .enter = wl_pointer_enter, - .leave = wl_pointer_leave, - .motion = wl_pointer_motion, - .button = wl_pointer_button, - .axis = wl_pointer_axis, - .frame = wl_pointer_frame, - .axis_source = wl_pointer_axis_source, - .axis_stop = wl_pointer_axis_stop, - .axis_discrete = wl_pointer_axis_discrete, -}; - -static void wl_keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, - uint32_t format, int32_t fd, uint32_t size) { - // Who cares -} - -static void wl_keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, struct wl_surface *surface, struct wl_array *keys) { - fprintf(stderr, "Keyboard enter\n"); -} - -static void wl_keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, struct wl_surface *surface) { - fprintf(stderr, "Keyboard leave\n"); -} - -static void wl_keyboard_key(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { - fprintf(stderr, "Key event: %d %d\n", key, state); -} - -static void wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { - // Who cares -} - -static void wl_keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, - int32_t rate, int32_t delay) { - // Who cares -} - -static struct wl_keyboard_listener keyboard_listener = { - .keymap = wl_keyboard_keymap, - .enter = wl_keyboard_enter, - .leave = wl_keyboard_leave, - .key = wl_keyboard_key, - .modifiers = wl_keyboard_modifiers, - .repeat_info = wl_keyboard_repeat_info, -}; - -static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, - enum wl_seat_capability caps) { - if ((caps & WL_SEAT_CAPABILITY_POINTER)) { - pointer = wl_seat_get_pointer(wl_seat); - wl_pointer_add_listener(pointer, &pointer_listener, NULL); - } - if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { - keyboard = wl_seat_get_keyboard(wl_seat); - wl_keyboard_add_listener(keyboard, &keyboard_listener, NULL); - } -} - -static void seat_handle_name(void *data, struct wl_seat *wl_seat, - const char *name) { - // Who cares -} - -const struct wl_seat_listener seat_listener = { - .capabilities = seat_handle_capabilities, - .name = seat_handle_name, -}; - -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, wl_compositor_interface.name) == 0) { - compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 1); - } else if (strcmp(interface, wl_shm_interface.name) == 0) { - shm = wl_registry_bind(registry, name, - &wl_shm_interface, 1); - } else if (strcmp(interface, "wl_output") == 0) { - if (output != UINT32_MAX) { - if (!wl_output) { - wl_output = wl_registry_bind(registry, name, - &wl_output_interface, 1); - } else { - output--; - } - } - } else if (strcmp(interface, wl_seat_interface.name) == 0) { - seat = wl_registry_bind(registry, name, - &wl_seat_interface, 1); - wl_seat_add_listener(seat, &seat_listener, NULL); - } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { - layer_shell = wl_registry_bind(registry, name, - &zwlr_layer_shell_v1_interface, version < 4 ? version : 4); - } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { - xdg_wm_base = wl_registry_bind( - registry, name, &xdg_wm_base_interface, 1); - } -} - -static void handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) { - // who cares -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = handle_global_remove, -}; - -int main(int argc, char **argv) { - char *namespace = "wlroots"; - int exclusive_zone = 0; - int32_t margin_right = 0, margin_bottom = 0, margin_left = 0; - bool found; - int c; - while ((c = getopt(argc, argv, "k:nw:h:o:l:a:x:m:t:")) != -1) { - switch (c) { - case 'o': - output = atoi(optarg); - break; - case 'w': - width = atoi(optarg); - break; - case 'h': - height = atoi(optarg); - break; - case 'x': - exclusive_zone = atoi(optarg); - break; - case 'l': { - struct { - char *name; - enum zwlr_layer_shell_v1_layer value; - } layers[] = { - { "background", ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND }, - { "bottom", ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM }, - { "top", ZWLR_LAYER_SHELL_V1_LAYER_TOP }, - { "overlay", ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY }, - }; - found = false; - for (size_t i = 0; i < sizeof(layers) / sizeof(layers[0]); ++i) { - if (strcmp(optarg, layers[i].name) == 0) { - layer = layers[i].value; - found = true; - break; - } - } - if (!found) { - fprintf(stderr, "invalid layer %s\n", optarg); - return 1; - } - break; - } - case 'a': { - struct { - char *name; - uint32_t value; - } anchors[] = { - { "top", ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP }, - { "bottom", ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM }, - { "left", ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT }, - { "right", ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT }, - }; - found = false; - for (size_t i = 0; i < sizeof(anchors) / sizeof(anchors[0]); ++i) { - if (strcmp(optarg, anchors[i].name) == 0) { - anchor |= anchors[i].value; - found = true; - break; - } - } - if (!found) { - fprintf(stderr, "invalid anchor %s\n", optarg); - return 1; - } - break; - } - case 't': - alpha = atof(optarg); - break; - case 'm': { - char *endptr = optarg; - margin_top = strtol(endptr, &endptr, 10); - assert(*endptr == ','); - margin_right = strtol(endptr + 1, &endptr, 10); - assert(*endptr == ','); - margin_bottom = strtol(endptr + 1, &endptr, 10); - assert(*endptr == ','); - margin_left = strtol(endptr + 1, &endptr, 10); - assert(!*endptr); - break; - } - case 'n': - animate = true; - break; - case 'k': { - const struct { - const char *name; - enum zwlr_layer_surface_v1_keyboard_interactivity value; - } kb_int[] = { - { "none", ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE }, - { "exclusive", ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE }, - { "on_demand", ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND } - }; - found = false; - for (size_t i = 0; i < sizeof(kb_int) / sizeof(kb_int[0]); ++i) { - if (strcmp(optarg, kb_int[i].name) == 0) { - keyboard_interactive = kb_int[i].value; - found = true; - break; - } - } - if (!found) { - fprintf(stderr, "invalid keyboard interactivity setting %s\n", optarg); - return 1; - } - break; - } - default: - break; - } - } - - display = wl_display_connect(NULL); - if (display == NULL) { - fprintf(stderr, "Failed to create display\n"); - return 1; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (compositor == NULL) { - fprintf(stderr, "wl_compositor not available\n"); - return 1; - } - if (shm == NULL) { - fprintf(stderr, "wl_shm not available\n"); - return 1; - } - if (layer_shell == NULL) { - fprintf(stderr, "layer_shell not available\n"); - return 1; - } - - struct wl_cursor_theme *cursor_theme = - wl_cursor_theme_load(NULL, 16, shm); - assert(cursor_theme); - struct wl_cursor *cursor = - wl_cursor_theme_get_cursor(cursor_theme, "crosshair"); - if (cursor == NULL) { - cursor = wl_cursor_theme_get_cursor(cursor_theme, "default"); - } - assert(cursor); - cursor_image = cursor->images[0]; - - cursor = wl_cursor_theme_get_cursor(cursor_theme, "tcross"); - if (cursor == NULL) { - cursor = wl_cursor_theme_get_cursor(cursor_theme, "default"); - } - assert(cursor); - popup_cursor_image = cursor->images[0]; - - cursor_surface = wl_compositor_create_surface(compositor); - assert(cursor_surface); - - egl_init(display); - - wl_surface = wl_compositor_create_surface(compositor); - assert(wl_surface); - - layer_surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, - wl_surface, wl_output, layer, namespace); - assert(layer_surface); - zwlr_layer_surface_v1_set_size(layer_surface, width, height); - zwlr_layer_surface_v1_set_anchor(layer_surface, anchor); - zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, exclusive_zone); - zwlr_layer_surface_v1_set_margin(layer_surface, - margin_top, margin_right, margin_bottom, margin_left); - zwlr_layer_surface_v1_set_keyboard_interactivity( - layer_surface, keyboard_interactive); - zwlr_layer_surface_v1_add_listener(layer_surface, - &layer_surface_listener, layer_surface); - wl_surface_commit(wl_surface); - wl_display_roundtrip(display); - - egl_window = wl_egl_window_create(wl_surface, width, height); - assert(egl_window); - egl_surface = eglCreatePlatformWindowSurfaceEXT( - egl_display, egl_config, egl_window, NULL); - assert(egl_surface != EGL_NO_SURFACE); - - wl_display_roundtrip(display); - draw(); - - while (wl_display_dispatch(display) != -1 && run_display) { - // This space intentionally left blank - } - - wl_cursor_theme_destroy(cursor_theme); - return 0; -} diff --git a/examples/meson.build b/examples/meson.build index e0e5720b..3fe07df8 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -1,29 +1,10 @@ -threads = dependency('threads') -wayland_egl = dependency('wayland-egl') -wayland_cursor = dependency('wayland-cursor') -wayland_client = dependency('wayland-client') -libpng = dependency('libpng', required: false, disabler: true) -egl = dependency('egl', required: false, disabler: true) -glesv2 = dependency('glesv2', required: false, disabler: true) -gbm = dependency('gbm', required: false, disabler: true) cairo = dependency('cairo', required: false, disabler: true) -# These versions correspond to ffmpeg 4.0 -libavutil = dependency('libavutil', version: '>=56.14.100', required: false, disabler: true) -libavcodec = dependency('libavcodec', version: '>=58.18.100', required: false, disabler: true) -libavformat = dependency('libavformat', version: '>=58.12.100', required: false, disabler: true) # Only needed for drm_fourcc.h libdrm_header = dependency('libdrm').partial_dependency(compile_args: true, includes: true) - -# epoll is a separate library in FreeBSD -if host_machine.system() == 'freebsd' - libepoll = dependency('epoll-shim') -else - libepoll = dependency('', required: false) -endif - -if not cc.has_header('libavutil/hwcontext_drm.h', dependencies: libavutil) - libavutil = disabler() -endif +wayland_client = dependency('wayland-client', required: false, disabler: true) +wayland_egl = dependency('wayland-egl', required: false, disabler: true) +egl = dependency('egl', version: '>= 1.5', required: false, disabler: true) +glesv2 = dependency('glesv2', required: false, disabler: true) compositors = { 'simple': { @@ -62,131 +43,13 @@ compositors = { 'src': 'cairo-buffer.c', 'dep': cairo, }, -} - -clients = { - 'idle-inhibit': { - 'src': ['idle-inhibit.c', 'egl_common.c'], - 'dep': [wayland_egl, egl, glesv2], - 'proto': [ - 'idle-inhibit-unstable-v1', - 'xdg-shell', - ], - }, - 'keyboard-shortcuts-inhibit': { - 'src': ['keyboard-shortcuts-inhibit.c', 'egl_common.c'], - 'dep': [wayland_egl, wayland_cursor, egl, glesv2], - 'proto': [ - 'keyboard-shortcuts-inhibit-unstable-v1', - 'xdg-shell', - ], - }, - 'layer-shell': { - 'src': ['layer-shell.c', 'egl_common.c'], - 'dep': [wayland_egl, wayland_cursor, egl, glesv2], - 'proto': [ - 'wlr-layer-shell-unstable-v1', - 'xdg-shell', - ], - }, - 'input-inhibitor': { - 'src': ['input-inhibitor.c', 'egl_common.c'], - 'dep': [wayland_egl, wayland_cursor, egl, glesv2], - 'proto': [ - 'wlr-input-inhibitor-unstable-v1', - 'xdg-shell', - ], - }, - 'gamma-control': { - 'src': 'gamma-control.c', - 'dep': [wayland_cursor, math], - 'proto': ['wlr-gamma-control-unstable-v1'], - }, - 'output-power-management': { - 'src': 'output-power-management.c', - 'dep': [wayland_client], - 'proto': ['wlr-output-power-management-unstable-v1'], - }, - 'pointer-constraints': { - 'src': ['pointer-constraints.c', 'egl_common.c'], - 'dep': [wayland_egl, egl, glesv2], - 'proto': [ - 'pointer-constraints-unstable-v1', - 'xdg-shell', - ], - }, - 'relative-pointer': { - 'src': ['relative-pointer-unstable-v1.c', 'egl_common.c'], - 'dep': [wayland_egl, egl, glesv2], - 'proto': [ - 'pointer-constraints-unstable-v1', - 'relative-pointer-unstable-v1', - 'xdg-shell', - ], - }, - 'dmabuf-capture': { - 'src': 'dmabuf-capture.c', - 'dep': [ - libavcodec, - libavformat, - libavutil, - drm, - threads, - ], - 'proto': ['wlr-export-dmabuf-unstable-v1'], - }, - 'screencopy': { - 'src': 'screencopy.c', - 'dep': [libpng, rt], - 'proto': ['wlr-screencopy-unstable-v1'], - }, - 'screencopy-dmabuf': { - 'src': 'screencopy-dmabuf.c', - 'dep': [libpng, rt, gbm, drm], - 'proto': [ - 'wlr-screencopy-unstable-v1', - 'linux-dmabuf-unstable-v1', - ], - }, - 'toplevel-decoration': { - 'src': ['toplevel-decoration.c', 'egl_common.c'], - 'dep': [wayland_egl, egl, glesv2], - 'proto': [ - 'xdg-decoration-unstable-v1', - 'xdg-shell', - ], - }, - 'input-method': { - 'src': 'input-method.c', - 'dep': [wayland_egl, libepoll], - 'proto': [ - 'input-method-unstable-v2', - 'text-input-unstable-v3', - 'xdg-shell', - ], - }, - 'text-input': { - 'src': ['text-input.c', 'egl_common.c'], - 'dep': [wayland_egl, wayland_cursor, egl, glesv2], - 'proto': [ - 'text-input-unstable-v3', - 'xdg-shell', - ], - }, - 'foreign-toplevel': { - 'src': 'foreign-toplevel.c', - 'proto': ['wlr-foreign-toplevel-management-unstable-v1'], - }, - 'virtual-pointer': { - 'src': 'virtual-pointer.c', - 'proto': ['wlr-virtual-pointer-unstable-v1'], - }, - 'input-method-keyboard-grab': { - 'src': 'input-method-keyboard-grab.c', - 'dep': xkbcommon, - 'proto': [ - 'input-method-unstable-v2', + 'embedded': { + 'src': [ + 'embedded.c', + protocols_code['xdg-shell'], + protocols_client_header['xdg-shell'], ], + 'dep': [wayland_client, wayland_egl, egl, glesv2], }, } @@ -203,29 +66,3 @@ foreach name, info : compositors build_by_default: get_option('examples'), ) endforeach - -foreach name, info : clients - extra_src = [] - foreach p : info.get('proto') - extra_src += protocols_code[p] - extra_src += protocols_client_header[p] - endforeach - - executable( - name, - [info.get('src'), extra_src], - dependencies: [wayland_client, info.get('dep', [])], - build_by_default: get_option('examples'), - ) -endforeach - -executable( - 'embedded', - [ - 'embedded.c', - 'egl_common.c', - protocols_code['xdg-shell'], - protocols_client_header['xdg-shell'], - ], - dependencies: [wlroots, wayland_client, wayland_egl, egl, glesv2], -) diff --git a/examples/output-power-management.c b/examples/output-power-management.c deleted file mode 100644 index c06eae61..00000000 --- a/examples/output-power-management.c +++ /dev/null @@ -1,144 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <unistd.h> -#include <wayland-client-protocol.h> -#include <wayland-client.h> -#include "wlr-output-power-management-unstable-v1-client-protocol.h" - -struct output { - struct wl_output *wl_output; - struct zwlr_output_power_v1 *output_power; - struct wl_list link; -}; - -static struct wl_list outputs; -static struct zwlr_output_power_manager_v1 *output_power_manager = NULL; - -static void output_power_handle_mode(void *data, - struct zwlr_output_power_v1 *output_power, - enum zwlr_output_power_v1_mode mode) { - struct output *output = data; - - switch (mode) { - case ZWLR_OUTPUT_POWER_V1_MODE_OFF: - printf("Output %p disabled\n", output); - break; - case ZWLR_OUTPUT_POWER_V1_MODE_ON: - printf("Output %p enabled\n", output); - break; - } -} - -static void output_power_handle_failed(void *data, - struct zwlr_output_power_v1 *output_power) { - fprintf(stderr, "failed to set output power mode\n"); - exit(EXIT_FAILURE); -} - -static const struct zwlr_output_power_v1_listener output_power_listener = { - .mode = output_power_handle_mode, - .failed = output_power_handle_failed, -}; - -static void registry_handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, wl_output_interface.name) == 0) { - struct output *output = calloc(1, sizeof(*output)); - output->wl_output = wl_registry_bind(registry, name, - &wl_output_interface, 1); - wl_list_insert(&outputs, &output->link); - } else if (strcmp(interface, - zwlr_output_power_manager_v1_interface.name) == 0) { - output_power_manager = wl_registry_bind(registry, name, - &zwlr_output_power_manager_v1_interface, 1); - } -} - -static void registry_handle_global_remove(void *data, - struct wl_registry *registry, uint32_t name) { - // Who cares? -} - -static const struct wl_registry_listener registry_listener = { - .global = registry_handle_global, - .global_remove = registry_handle_global_remove, -}; - -static const char usage[] = "usage: output-power-management [options...]\n" - " -h: show this help message\n" - " -e: turn outputs on\n" - " -d: turn outputs off\n" - " -w: continuously watch for power mode changes\n"; - -int main(int argc, char *argv[]) { - wl_list_init(&outputs); - - int opt; - enum zwlr_output_power_v1_mode mode = - ZWLR_OUTPUT_POWER_V1_MODE_ON; - bool watch_mode = false; - while ((opt = getopt(argc, argv, "edhw")) != -1) { - switch (opt) { - case 'e': - mode = ZWLR_OUTPUT_POWER_V1_MODE_ON; - break; - case 'd': - mode = ZWLR_OUTPUT_POWER_V1_MODE_OFF; - break; - case 'w': - watch_mode = true; - break; - case 'h': - default: - fprintf(stderr, usage); - return opt == 'h' ? EXIT_SUCCESS : EXIT_FAILURE; - } - } - - struct wl_display *display = wl_display_connect(NULL); - if (display == NULL) { - fprintf(stderr, "failed to create display\n"); - return -1; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (output_power_manager == NULL) { - fprintf(stderr, - "compositor doesn't support wlr-output-power-management-unstable-v1\n"); - return EXIT_FAILURE; - } - - struct output *output; - wl_list_for_each(output, &outputs, link) { - output->output_power = zwlr_output_power_manager_v1_get_output_power( - output_power_manager, output->wl_output); - zwlr_output_power_v1_add_listener(output->output_power, - &output_power_listener, output); - } - wl_display_roundtrip(display); - - wl_list_for_each(output, &outputs, link) { - zwlr_output_power_v1_set_mode(output->output_power, - mode); - } - - if (!watch_mode) { - wl_display_roundtrip(display); - return EXIT_SUCCESS; - } - - while (wl_display_dispatch(display) != -1) { - // nothing to see here, please move along - } - - return EXIT_SUCCESS; -} diff --git a/examples/pointer-constraints.c b/examples/pointer-constraints.c deleted file mode 100644 index a75a2f6e..00000000 --- a/examples/pointer-constraints.c +++ /dev/null @@ -1,258 +0,0 @@ -#include <GLES2/gl2.h> -#include <linux/input-event-codes.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <wayland-client.h> -#include <wayland-egl.h> -#include "egl_common.h" -#include "xdg-shell-client-protocol.h" -#include "pointer-constraints-unstable-v1-client-protocol.h" - -static int width = 512, height = 512; - -static struct wl_compositor *compositor = NULL; -static struct wl_seat *seat = NULL; -static struct xdg_wm_base *wm_base = NULL; -static struct zwp_pointer_constraints_v1 *pointer_constraints = NULL; - -struct wl_egl_window *egl_window; -struct wlr_egl_surface *egl_surface; -struct zwp_locked_pointer_v1* locked_pointer; -struct zwp_confined_pointer_v1* confined_pointer; - -enum { - REGION_TYPE_NONE, - REGION_TYPE_DISJOINT, - REGION_TYPE_JOINT, - REGION_TYPE_MAX -} region_type = REGION_TYPE_NONE; - -struct wl_region *regions[3]; - -static void draw(void) { - eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context); - - float color[] = {1.0, 1.0, 0.0, 1.0}; - - glViewport(0, 0, width, height); - glClearColor(color[0], color[1], color[2], 1.0); - glClear(GL_COLOR_BUFFER_BIT); - - eglSwapBuffers(egl_display, egl_surface); -} - -static void pointer_handle_button(void *data, struct wl_pointer *pointer, - uint32_t serial, uint32_t time, uint32_t button, uint32_t state_w) { - struct wl_surface *surface = data; - - if (button == BTN_LEFT && state_w == WL_POINTER_BUTTON_STATE_PRESSED) { - region_type = (region_type + 1) % REGION_TYPE_MAX; - - if (locked_pointer) { - zwp_locked_pointer_v1_set_region(locked_pointer, - regions[region_type]); - } else if (confined_pointer) { - zwp_confined_pointer_v1_set_region(confined_pointer, - regions[region_type]); - } - - wl_surface_commit(surface); - } -} - -static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface, - wl_fixed_t surface_x, wl_fixed_t surface_y) { - // This space intentionally left blank -} - -static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface) { - // This space intentionally left blank -} - -static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, - uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { - // This space intentionally left blank -} - -static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, - uint32_t time, uint32_t axis, wl_fixed_t value) { - // This space intentionally left blank -} - -static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) { - // This space intentionally left blank -} - -static void pointer_handle_axis_source(void *data, - struct wl_pointer *wl_pointer, uint32_t axis_source) { - // This space intentionally left blank -} - -static void pointer_handle_axis_stop(void *data, - struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis) { - // This space intentionally left blank -} - -static void pointer_handle_axis_discrete(void *data, - struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete) { - // This space intentionally left blank -} - -static const struct wl_pointer_listener pointer_listener = { - .enter = pointer_handle_enter, - .leave = pointer_handle_leave, - .motion = pointer_handle_motion, - .button = pointer_handle_button, - .axis = pointer_handle_axis, - .frame = pointer_handle_frame, - .axis_source = pointer_handle_axis_source, - .axis_stop = pointer_handle_axis_stop, - .axis_discrete = pointer_handle_axis_discrete, -}; - -static void xdg_surface_handle_configure(void *data, - struct xdg_surface *xdg_surface, uint32_t serial) { - xdg_surface_ack_configure(xdg_surface, serial); - wl_egl_window_resize(egl_window, width, height, 0, 0); - draw(); -} - -static const struct xdg_surface_listener xdg_surface_listener = { - .configure = xdg_surface_handle_configure, -}; - -static void xdg_toplevel_handle_configure(void *data, - struct xdg_toplevel *xdg_toplevel, int32_t w, int32_t h, - struct wl_array *states) { - width = w; - height = h; -} - -static void xdg_toplevel_handle_close(void *data, - struct xdg_toplevel *xdg_toplevel) { - exit(EXIT_SUCCESS); -} - -static const struct xdg_toplevel_listener xdg_toplevel_listener = { - .configure = xdg_toplevel_handle_configure, - .close = xdg_toplevel_handle_close, -}; - -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, wl_compositor_interface.name) == 0) { - compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 1); - } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { - wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); - } else if (strcmp(interface, wl_seat_interface.name) == 0) { - seat = wl_registry_bind(registry, name, &wl_seat_interface, version); - } else if (strcmp(interface, - zwp_pointer_constraints_v1_interface.name) == 0) { - pointer_constraints = wl_registry_bind(registry, name, - &zwp_pointer_constraints_v1_interface, version); - } -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = NULL, -}; - -int main(int argc, char **argv) { - if (argc != 4) { - goto invalid_args; - } - - bool lock; - if (strcmp(argv[1], "lock") == 0) { - lock = true; - } else if (strcmp(argv[1], "confine") == 0) { - lock = false; - } else { - goto invalid_args; - } - - enum zwp_pointer_constraints_v1_lifetime lifetime; - if (strcmp(argv[2], "oneshot") == 0) { - lifetime = ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT; - } else if (strcmp(argv[2], "persistent") == 0) { - lifetime = ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT; - } else { - goto invalid_args; - } - - if (strcmp(argv[3], "no-region") == 0) { - region_type = REGION_TYPE_NONE; - } else if (strcmp(argv[3], "disjoint-region") == 0) { - region_type = REGION_TYPE_DISJOINT; - } else if (strcmp(argv[3], "joint-region") == 0) { - region_type = REGION_TYPE_JOINT; - } - - struct wl_display *display = wl_display_connect(NULL); - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - struct wl_region *disjoint_region = wl_compositor_create_region(compositor); - wl_region_add(disjoint_region, 0, 0, 255, 256); - wl_region_add(disjoint_region, 257, 0, 255, 256); - regions[REGION_TYPE_DISJOINT] = disjoint_region; - - struct wl_region *joint_region = wl_compositor_create_region(compositor); - wl_region_add(joint_region, 0, 0, 256, 256); - wl_region_add(joint_region, 256, 0, 256, 256); - wl_region_add(joint_region, 256, 256, 256, 256); - regions[REGION_TYPE_JOINT] = joint_region; - - egl_init(display); - - struct wl_surface *surface = wl_compositor_create_surface(compositor); - struct xdg_surface *xdg_surface = - xdg_wm_base_get_xdg_surface(wm_base, surface); - struct xdg_toplevel *xdg_toplevel = xdg_surface_get_toplevel(xdg_surface); - - xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL); - xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL); - - struct wl_pointer *pointer = wl_seat_get_pointer(seat); - wl_pointer_add_listener(pointer, &pointer_listener, surface); - - if (lock) { - locked_pointer = zwp_pointer_constraints_v1_lock_pointer( - pointer_constraints, surface, pointer, - regions[region_type], lifetime); - - zwp_locked_pointer_v1_set_cursor_position_hint(locked_pointer, - wl_fixed_from_int(128), wl_fixed_from_int(128)); - } else { - confined_pointer = zwp_pointer_constraints_v1_confine_pointer( - pointer_constraints, surface, pointer, - regions[region_type], lifetime); - } - - wl_surface_commit(surface); - - egl_window = wl_egl_window_create(surface, width, height); - egl_surface = eglCreatePlatformWindowSurfaceEXT( - egl_display, egl_config, egl_window, NULL); - - wl_display_roundtrip(display); - - draw(); - - while (wl_display_dispatch(display) != -1) {} - - return EXIT_SUCCESS; - -invalid_args: - fprintf(stderr, "pointer-constraints <lock | confine> " - "<oneshot | persistent> " - "<no-region | disjoint-rejoin | joint-region>\n"); - return EXIT_FAILURE; -} diff --git a/examples/screencopy-dmabuf.c b/examples/screencopy-dmabuf.c deleted file mode 100644 index f16c29da..00000000 --- a/examples/screencopy-dmabuf.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright © 2008 Kristian Høgsberg - * Copyright © 2020 Andri Yngvason - * - * 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 (including the next - * paragraph) 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. - */ - -#define _POSIX_C_SOURCE 200112L -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <png.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <unistd.h> -#include <assert.h> -#include <gbm.h> -#include <xf86drm.h> -#include <drm_fourcc.h> -#include <wayland-client-protocol.h> -#include "wlr-screencopy-unstable-v1-client-protocol.h" -#include "linux-dmabuf-unstable-v1-client-protocol.h" - -struct format { - uint32_t format; - bool is_bgr; -}; - -static int drm_fd = -1; -static struct gbm_device *gbm_device = NULL; - -static struct zwp_linux_dmabuf_v1 *dmabuf = NULL; -static struct zwlr_screencopy_manager_v1 *screencopy_manager = NULL; -static struct wl_output *output = NULL; - -static struct { - struct gbm_bo *bo; - struct wl_buffer *wl_buffer; - int width, height; - uint32_t format; - bool y_invert; -} buffer; - -bool buffer_copy_done = false; -static bool have_linux_dmabuf = false; - -// wl_shm_format describes little-endian formats, libpng uses big-endian -// formats (so Wayland's ABGR is libpng's RGBA). -static const struct format formats[] = { - {DRM_FORMAT_XRGB8888, true}, - {DRM_FORMAT_ARGB8888, true}, - {DRM_FORMAT_XBGR8888, false}, - {DRM_FORMAT_ABGR8888, false}, -}; - -static bool find_render_node(char *node, size_t node_size) { - bool r = false; - drmDevice *devices[64]; - - int n = drmGetDevices2(0, devices, sizeof(devices) / sizeof(devices[0])); - for (int i = 0; i < n; ++i) { - drmDevice *dev = devices[i]; - if (!(dev->available_nodes & (1 << DRM_NODE_RENDER))) { - continue; - } - - snprintf(node, node_size, "%s", dev->nodes[DRM_NODE_RENDER]); - r = true; - break; - } - - drmFreeDevices(devices, n); - return r; -} - -static void dmabuf_created(void *data, - struct zwp_linux_buffer_params_v1 *params, - struct wl_buffer *wl_buffer) { - buffer.wl_buffer = wl_buffer; - - zwlr_screencopy_frame_v1_copy(data, buffer.wl_buffer); -} - -static void dmabuf_failed(void *data, - struct zwp_linux_buffer_params_v1 *params) { - fprintf(stderr, "Failed to create dmabuf\n"); - exit(EXIT_FAILURE); -} - -static const struct zwp_linux_buffer_params_v1_listener params_listener = { - .created = dmabuf_created, - .failed = dmabuf_failed, -}; - -static void frame_handle_buffer(void *data, - struct zwlr_screencopy_frame_v1 *frame, uint32_t wl_format, - uint32_t width, uint32_t height, uint32_t stride) { - // Not implemented -} - -static void frame_handle_linux_dmabuf(void *data, - struct zwlr_screencopy_frame_v1 *frame, uint32_t fourcc, - uint32_t width, uint32_t height) { - buffer.width = width; - buffer.height = height; - buffer.format = fourcc; - have_linux_dmabuf = true; -} - -static void frame_handle_buffer_done(void *data, - struct zwlr_screencopy_frame_v1 *frame) { - assert(!buffer.bo); - - if (!have_linux_dmabuf) { - fprintf(stderr, "linux-dmabuf is not supported\n"); - exit(EXIT_FAILURE); - } - - buffer.bo = gbm_bo_create(gbm_device, buffer.width, buffer.height, - buffer.format, - GBM_BO_USE_LINEAR | GBM_BO_USE_RENDERING); - if (buffer.bo == NULL) { - fprintf(stderr, "failed to create GBM buffer object\n"); - exit(EXIT_FAILURE); - } - - struct zwp_linux_buffer_params_v1 *params; - params = zwp_linux_dmabuf_v1_create_params(dmabuf); - assert(params); - - int fd = gbm_bo_get_fd(buffer.bo); - uint32_t off = gbm_bo_get_offset(buffer.bo, 0); - uint32_t bo_stride = gbm_bo_get_stride(buffer.bo); - uint64_t mod = gbm_bo_get_modifier(buffer.bo); - zwp_linux_buffer_params_v1_add(params, fd, 0, off, bo_stride, mod >> 32, - mod & 0xffffffff); - - zwp_linux_buffer_params_v1_add_listener(params, ¶ms_listener, frame); - - zwp_linux_buffer_params_v1_create(params, buffer.width, buffer.height, - buffer.format, /* flags */ 0); -} - -static void frame_handle_flags(void *data, - struct zwlr_screencopy_frame_v1 *frame, uint32_t flags) { - buffer.y_invert = flags & ZWLR_SCREENCOPY_FRAME_V1_FLAGS_Y_INVERT; -} - -static void frame_handle_ready(void *data, - struct zwlr_screencopy_frame_v1 *frame, uint32_t tv_sec_hi, - uint32_t tv_sec_lo, uint32_t tv_nsec) { - buffer_copy_done = true; -} - -static void frame_handle_failed(void *data, - struct zwlr_screencopy_frame_v1 *frame) { - fprintf(stderr, "failed to copy frame\n"); - exit(EXIT_FAILURE); -} - -static const struct zwlr_screencopy_frame_v1_listener frame_listener = { - .buffer = frame_handle_buffer, - .linux_dmabuf = frame_handle_linux_dmabuf, - .buffer_done = frame_handle_buffer_done, - .flags = frame_handle_flags, - .ready = frame_handle_ready, - .failed = frame_handle_failed, -}; - -static void dmabuf_format(void *data, - struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format) { - // deprecated -} - -static void dmabuf_modifier(void *data, - struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format, - uint32_t modifier_hi, uint32_t modifier_lo) { - // TODO? -} - -static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = { - .format = dmabuf_format, - .modifier = dmabuf_modifier, -}; - -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, wl_output_interface.name) == 0 && output == NULL) { - output = wl_registry_bind(registry, name, &wl_output_interface, 1); - } else if (strcmp(interface, zwp_linux_dmabuf_v1_interface.name) == 0) { - dmabuf = wl_registry_bind(registry, name, - &zwp_linux_dmabuf_v1_interface, 3); - zwp_linux_dmabuf_v1_add_listener(dmabuf, &dmabuf_listener, data); - } else if (strcmp(interface, - zwlr_screencopy_manager_v1_interface.name) == 0) { - screencopy_manager = wl_registry_bind(registry, name, - &zwlr_screencopy_manager_v1_interface, 3); - } -} - -static void handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) { - // Who cares? -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = handle_global_remove, -}; - -static void write_image(char *filename, uint32_t format, int width, - int height, int stride, bool y_invert, png_bytep data) { - const struct format *fmt = NULL; - for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); ++i) { - if (formats[i].format == format) { - fmt = &formats[i]; - break; - } - } - - if (fmt == NULL) { - fprintf(stderr, "unsupported format %"PRIu32"\n", format); - exit(EXIT_FAILURE); - } - - FILE *f = fopen(filename, "wb"); - if (f == NULL) { - fprintf(stderr, "failed to open output file\n"); - exit(EXIT_FAILURE); - } - - png_structp png = - png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - png_infop info = png_create_info_struct(png); - - png_init_io(png, f); - - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGBA, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - - if (fmt->is_bgr) { - png_set_bgr(png); - } - - png_write_info(png, info); - - for (size_t i = 0; i < (size_t)height; ++i) { - png_bytep row; - if (y_invert) { - row = data + (height - i - 1) * stride; - } else { - row = data + i * stride; - } - png_write_row(png, row); - } - - png_write_end(png, NULL); - - png_destroy_write_struct(&png, &info); - - fclose(f); -} - -int main(int argc, char *argv[]) { - char render_node[256]; - if (!find_render_node(render_node, sizeof(render_node))) { - fprintf(stderr, "Failed to find a DRM render node\n"); - return EXIT_FAILURE; - } - - printf("Using render node: %s\n", render_node); - - drm_fd = open(render_node, O_RDWR); - if (drm_fd < 0) { - perror("Failed to open drm render node"); - return EXIT_FAILURE; - } - - gbm_device = gbm_create_device(drm_fd); - if (!gbm_device) { - fprintf(stderr, "Failed to create gbm device\n"); - return EXIT_FAILURE; - } - - struct wl_display *display = wl_display_connect(NULL); - if (display == NULL) { - perror("failed to create display"); - return EXIT_FAILURE; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (dmabuf == NULL) { - fprintf(stderr, "compositor is missing linux-dmabuf-unstable-v1\n"); - return EXIT_FAILURE; - } - if (screencopy_manager == NULL) { - fprintf(stderr, "compositor doesn't support wlr-screencopy-unstable-v1\n"); - return EXIT_FAILURE; - } - if (output == NULL) { - fprintf(stderr, "no output available\n"); - return EXIT_FAILURE; - } - - struct zwlr_screencopy_frame_v1 *frame = - zwlr_screencopy_manager_v1_capture_output(screencopy_manager, 0, output); - zwlr_screencopy_frame_v1_add_listener(frame, &frame_listener, NULL); - - while (!buffer_copy_done && wl_display_dispatch(display) != -1) { - // This space is intentionally left blank - } - - uint32_t stride = 0; - void *map_data = NULL; - void *data = gbm_bo_map(buffer.bo, 0, 0, buffer.width, buffer.height, - GBM_BO_TRANSFER_READ, &stride, &map_data); - if (!data) { - perror("Failed to map gbm bo"); - return EXIT_FAILURE; - } - - write_image("wayland-screenshot.png", buffer.format, buffer.width, - buffer.height, stride, buffer.y_invert, data); - - gbm_bo_unmap(buffer.bo, map_data); - gbm_bo_destroy(buffer.bo); - wl_buffer_destroy(buffer.wl_buffer); - - gbm_device_destroy(gbm_device); - close(drm_fd); - - return EXIT_SUCCESS; -} diff --git a/examples/screencopy.c b/examples/screencopy.c deleted file mode 100644 index 42123e55..00000000 --- a/examples/screencopy.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright © 2008 Kristian Høgsberg - * - * 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 (including the next - * paragraph) 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. - */ - -#define _POSIX_C_SOURCE 200112L -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <png.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <unistd.h> -#include <assert.h> -#include <wayland-client-protocol.h> -#include "wlr-screencopy-unstable-v1-client-protocol.h" - -struct format { - enum wl_shm_format wl_format; - bool is_bgr; -}; - -static struct wl_shm *shm = NULL; -static struct zwlr_screencopy_manager_v1 *screencopy_manager = NULL; -static struct wl_output *output = NULL; - -static struct { - struct wl_buffer *wl_buffer; - void *data; - enum wl_shm_format format; - int width, height, stride; - bool y_invert; -} buffer; -bool buffer_copy_done = false; - -// wl_shm_format describes little-endian formats, libpng uses big-endian -// formats (so Wayland's ABGR is libpng's RGBA). -static const struct format formats[] = { - {WL_SHM_FORMAT_XRGB8888, true}, - {WL_SHM_FORMAT_ARGB8888, true}, - {WL_SHM_FORMAT_XBGR8888, false}, - {WL_SHM_FORMAT_ABGR8888, false}, -}; - -static struct wl_buffer *create_shm_buffer(enum wl_shm_format fmt, - int width, int height, int stride, void **data_out) { - int size = stride * height; - - const char shm_name[] = "/wlroots-screencopy"; - int fd = shm_open(shm_name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - if (fd < 0) { - fprintf(stderr, "shm_open failed\n"); - return NULL; - } - shm_unlink(shm_name); - - int ret; - while ((ret = ftruncate(fd, size)) == EINTR) { - // No-op - } - if (ret < 0) { - close(fd); - fprintf(stderr, "ftruncate failed\n"); - return NULL; - } - - void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (data == MAP_FAILED) { - perror("mmap failed"); - close(fd); - return NULL; - } - - struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size); - close(fd); - struct wl_buffer *buffer = wl_shm_pool_create_buffer(pool, 0, width, height, - stride, fmt); - wl_shm_pool_destroy(pool); - - *data_out = data; - return buffer; -} - -static void frame_handle_buffer(void *data, - struct zwlr_screencopy_frame_v1 *frame, uint32_t format, - uint32_t width, uint32_t height, uint32_t stride) { - buffer.format = format; - buffer.width = width; - buffer.height = height; - buffer.stride = stride; - - // Make sure the buffer is not allocated - assert(!buffer.wl_buffer); - buffer.wl_buffer = - create_shm_buffer(format, width, height, stride, &buffer.data); - if (buffer.wl_buffer == NULL) { - fprintf(stderr, "failed to create buffer\n"); - exit(EXIT_FAILURE); - } - - zwlr_screencopy_frame_v1_copy(frame, buffer.wl_buffer); -} - -static void frame_handle_flags(void *data, - struct zwlr_screencopy_frame_v1 *frame, uint32_t flags) { - buffer.y_invert = flags & ZWLR_SCREENCOPY_FRAME_V1_FLAGS_Y_INVERT; -} - -static void frame_handle_ready(void *data, - struct zwlr_screencopy_frame_v1 *frame, uint32_t tv_sec_hi, - uint32_t tv_sec_lo, uint32_t tv_nsec) { - buffer_copy_done = true; -} - -static void frame_handle_failed(void *data, - struct zwlr_screencopy_frame_v1 *frame) { - fprintf(stderr, "failed to copy frame\n"); - exit(EXIT_FAILURE); -} - -static const struct zwlr_screencopy_frame_v1_listener frame_listener = { - .buffer = frame_handle_buffer, - .flags = frame_handle_flags, - .ready = frame_handle_ready, - .failed = frame_handle_failed, -}; - -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, wl_output_interface.name) == 0 && output == NULL) { - output = wl_registry_bind(registry, name, &wl_output_interface, 1); - } else if (strcmp(interface, wl_shm_interface.name) == 0) { - shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); - } else if (strcmp(interface, - zwlr_screencopy_manager_v1_interface.name) == 0) { - screencopy_manager = wl_registry_bind(registry, name, - &zwlr_screencopy_manager_v1_interface, 1); - } -} - -static void handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) { - // Who cares? -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = handle_global_remove, -}; - -static void write_image(char *filename, enum wl_shm_format wl_fmt, int width, - int height, int stride, bool y_invert, png_bytep data) { - const struct format *fmt = NULL; - for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); ++i) { - if (formats[i].wl_format == wl_fmt) { - fmt = &formats[i]; - break; - } - } - if (fmt == NULL) { - fprintf(stderr, "unsupported format %"PRIu32"\n", wl_fmt); - exit(EXIT_FAILURE); - } - - FILE *f = fopen(filename, "wb"); - if (f == NULL) { - fprintf(stderr, "failed to open output file\n"); - exit(EXIT_FAILURE); - } - - png_structp png = - png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - png_infop info = png_create_info_struct(png); - - png_init_io(png, f); - - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGBA, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - - if (fmt->is_bgr) { - png_set_bgr(png); - } - - png_write_info(png, info); - - for (size_t i = 0; i < (size_t)height; ++i) { - png_bytep row; - if (y_invert) { - row = data + (height - i - 1) * stride; - } else { - row = data + i * stride; - } - png_write_row(png, row); - } - - png_write_end(png, NULL); - - png_destroy_write_struct(&png, &info); - - fclose(f); -} - -int main(int argc, char *argv[]) { - struct wl_display * display = wl_display_connect(NULL); - if (display == NULL) { - perror("failed to create display"); - return EXIT_FAILURE; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (shm == NULL) { - fprintf(stderr, "compositor is missing wl_shm\n"); - return EXIT_FAILURE; - } - if (screencopy_manager == NULL) { - fprintf(stderr, "compositor doesn't support wlr-screencopy-unstable-v1\n"); - return EXIT_FAILURE; - } - if (output == NULL) { - fprintf(stderr, "no output available\n"); - return EXIT_FAILURE; - } - - struct zwlr_screencopy_frame_v1 *frame = - zwlr_screencopy_manager_v1_capture_output(screencopy_manager, 0, output); - zwlr_screencopy_frame_v1_add_listener(frame, &frame_listener, NULL); - - while (!buffer_copy_done && wl_display_dispatch(display) != -1) { - // This space is intentionally left blank - } - - write_image("wayland-screenshot.png", buffer.format, buffer.width, - buffer.height, buffer.stride, buffer.y_invert, buffer.data); - wl_buffer_destroy(buffer.wl_buffer); - munmap(buffer.data, buffer.stride * buffer.height); - - return EXIT_SUCCESS; -} diff --git a/examples/text-input.c b/examples/text-input.c deleted file mode 100644 index dba4ce18..00000000 --- a/examples/text-input.c +++ /dev/null @@ -1,390 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#include <GLES2/gl2.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <wayland-client.h> -#include <wayland-egl.h> -#include "egl_common.h" -#include "text-input-unstable-v3-client-protocol.h" -#include "xdg-shell-client-protocol.h" - -const char usage[] = "Usage: text-input [seconds [width height]]\n\ -\n\ -Creates a xdg-toplevel using the text-input protocol.\n\ -It will be solid black when it has no text input focus, yellow when it\n\ -has focus, and red when it was notified that the focus moved away\n\ -but still didn't give up the text input ability.\n\ -\n\ -The \"seconds\" argument is optional and defines the delay between getting\n\ -notified of lost focus and releasing text input.\n\ -\n\ -The \"width\" and \"height\" arguments define the window shape.\n\ -\n\ -The console will print the internal state of the text field:\n\ -- the text in the 1st line\n\ -- \".\" under each preedit character\n\ -- \"_\" under each selected preedit character\n\ -- \"|\" at the cursor position if there are no selected characters in the\n\ -preedit.\n\ -\n\ -The cursor positions may be inaccurate, especially in presence of zero-width\n\ -characters or non-monospaced fonts.\n"; - -struct text_input_state { - char *commit; - struct { - char *text; - int32_t cursor_begin; - int32_t cursor_end; - } preedit; - struct { - uint32_t after_length; - uint32_t before_length; - } delete_surrounding; -}; - -static struct text_input_state pending = {0}; -static struct text_input_state current = {0}; -static bool entered = false; -static uint32_t serial; -static char *buffer; // text buffer -// cursor is not present, there's no way to move it outside of preedit - -static int sleeptime = 0; -static int width = 100, height = 200; -static int enabled = 0; - -static struct wl_display *display = NULL; -static struct wl_compositor *compositor = NULL; -static struct wl_seat *seat = NULL; -static struct xdg_wm_base *wm_base = NULL; -static struct zwp_text_input_manager_v3 *text_input_manager = NULL; -static struct zwp_text_input_v3 *text_input = NULL; - -struct wl_egl_window *egl_window; -struct wlr_egl_surface *egl_surface; - -static void draw(void) { - eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context); - - float color[] = {1.0, 1.0, 0.0, 1.0}; - color[0] = enabled * 1.0; - color[1] = entered * 1.0; - - glViewport(0, 0, width, height); - glClearColor(color[0], color[1], color[2], 1.0); - glClear(GL_COLOR_BUFFER_BIT); - - eglSwapBuffers(egl_display, egl_surface); -} - -static size_t utf8_strlen(char *str) { - size_t cp_count = 0; - for (; *str != '\0'; str++) { - if ((*str & 0xc0) != 0x80) { - cp_count++; - } - } - return cp_count; -} - -static size_t utf8_offset(char *utf8_str, size_t byte_offset) { - size_t cp_count = 0; - for (char *c = utf8_str; c < utf8_str + byte_offset; c++) { - if ((*c & 0xc0) != 0x80) { - cp_count++; - } - } - return cp_count; -} - -// TODO: would be nicer to have this text display inside the window -static void show_status(void) { - printf("State %d:", serial); - if (!enabled) { - printf(" disabled"); - } - - char *preedit_text = current.preedit.text; - if (!preedit_text) { - preedit_text = ""; - } - - printf("\n"); - printf("%s", buffer); - printf("%s\n", preedit_text); - - // Positioning of the cursor requires UTF8 offsets to match monospaced - // glyphs - for (unsigned i = 0; i < utf8_strlen(buffer); i++) { - printf(" "); - } - char *cursor_mark = calloc(utf8_strlen(preedit_text) + 2, sizeof(*cursor_mark)); - for (unsigned i = 0; i < utf8_strlen(preedit_text); i++) { - cursor_mark[i] = '.'; - } - if (current.preedit.cursor_begin == -1 - && current.preedit.cursor_end == -1) { - goto end; - } - if (current.preedit.cursor_begin == -1 - || current.preedit.cursor_end == -1) { - printf("Only one cursor side is defined: %d to %d\n", - current.preedit.cursor_begin, current.preedit.cursor_end); - goto end; - } - - if ((unsigned)current.preedit.cursor_begin > strlen(preedit_text)) { - printf("Cursor out of bounds\n"); - goto end; - } - - if (current.preedit.cursor_begin == current.preedit.cursor_end) { - cursor_mark[utf8_offset(preedit_text, current.preedit.cursor_begin)] - = '|'; - goto print; - } - - if (current.preedit.cursor_begin > current.preedit.cursor_end) { - printf("End cursor is before start cursor\n"); - goto end; - } - - // negative offsets already checked before - for (unsigned i = utf8_offset(preedit_text, current.preedit.cursor_begin); - i < utf8_offset(preedit_text, current.preedit.cursor_end); i++) { - cursor_mark[i] = '_'; - } -print: - printf("%s\n", cursor_mark); -end: - free(cursor_mark); -} - -static void commit(struct zwp_text_input_v3 *text_input) { - zwp_text_input_v3_commit(text_input); - serial++; -} - -static void send_status_update(struct zwp_text_input_v3 *text_input) { - zwp_text_input_v3_set_surrounding_text(text_input, buffer, strlen(buffer), strlen(buffer)); - zwp_text_input_v3_set_text_change_cause(text_input, ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD); - commit(text_input); -} - -static void text_input_handle_enter(void *data, - struct zwp_text_input_v3 *zwp_text_input_v3, - struct wl_surface *surface) { - entered = true; - zwp_text_input_v3_enable(zwp_text_input_v3); - commit(zwp_text_input_v3); - enabled = true; - draw(); - show_status(); -} - -static void text_input_handle_leave(void *data, - struct zwp_text_input_v3 *zwp_text_input_v3, - struct wl_surface *surface) { - entered = false; - draw(); - wl_display_roundtrip(display); - sleep(sleeptime); - zwp_text_input_v3_disable(zwp_text_input_v3); - commit(zwp_text_input_v3); - enabled = false; - draw(); - show_status(); -} - -static void text_input_commit_string(void *data, - struct zwp_text_input_v3 *zwp_text_input_v3, - const char *text) { - free(pending.commit); - pending.commit = strdup(text); -} - -static void text_input_delete_surrounding_text(void *data, - struct zwp_text_input_v3 *zwp_text_input_v3, - uint32_t before_length, uint32_t after_length) { - pending.delete_surrounding.before_length = before_length; - pending.delete_surrounding.after_length = after_length; -} - -static void text_input_preedit_string(void *data, - struct zwp_text_input_v3 *zwp_text_input_v3, - const char *text, int32_t cursor_begin, int32_t cursor_end) { - free(pending.preedit.text); - pending.preedit.text = strdup(text); - pending.preedit.cursor_begin = cursor_begin; - pending.preedit.cursor_end = cursor_end; -} - -static void text_input_handle_done(void *data, - struct zwp_text_input_v3 *zwp_text_input_v3, - uint32_t incoming_serial) { - if (serial != incoming_serial) { - fprintf(stderr, "Received serial %d while expecting %d\n", incoming_serial, serial); - return; - } - free(current.preedit.text); - free(current.commit); - current = pending; - struct text_input_state empty = {0}; - pending = empty; - - if (current.delete_surrounding.after_length + current.delete_surrounding.before_length > 0) { - // cursor is always after committed text, after_length != 0 will never happen - unsigned delete_before = current.delete_surrounding.before_length; - if (delete_before > strlen(buffer)) { - delete_before = strlen(buffer); - } - buffer[strlen(buffer) - delete_before] = '\0'; - } - - const char *commit_string = current.commit; - if (!commit_string) { - commit_string = ""; - } - size_t new_size = strlen(buffer) + strlen(commit_string) + 1; - char *new_buffer = calloc(new_size, sizeof(*new_buffer)); // realloc may fail anyway - snprintf(new_buffer, new_size, "%s%s", buffer, commit_string); - free(buffer); - buffer = new_buffer; - - send_status_update(zwp_text_input_v3); - show_status(); -} - -static const struct zwp_text_input_v3_listener text_input_listener = { - .enter = text_input_handle_enter, - .leave = text_input_handle_leave, - .commit_string = text_input_commit_string, - .delete_surrounding_text = text_input_delete_surrounding_text, - .preedit_string = text_input_preedit_string, - .done = text_input_handle_done, -}; - -static void xdg_surface_handle_configure(void *data, - struct xdg_surface *xdg_surface, uint32_t serial) { - xdg_surface_ack_configure(xdg_surface, serial); - wl_egl_window_resize(egl_window, width, height, 0, 0); - draw(); -} - -static const struct xdg_surface_listener xdg_surface_listener = { - .configure = xdg_surface_handle_configure, -}; - -static void xdg_toplevel_handle_configure(void *data, - struct xdg_toplevel *xdg_toplevel, int32_t w, int32_t h, - struct wl_array *states) { - width = w; - height = h; -} - -static void xdg_toplevel_handle_close(void *data, - struct xdg_toplevel *xdg_toplevel) { - exit(EXIT_SUCCESS); -} - -static const struct xdg_toplevel_listener xdg_toplevel_listener = { - .configure = xdg_toplevel_handle_configure, - .close = xdg_toplevel_handle_close, -}; - -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, "wl_compositor") == 0) { - compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 1); - } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { - wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); - } else if (strcmp(interface, zwp_text_input_manager_v3_interface.name) == 0) { - text_input_manager = wl_registry_bind(registry, name, - &zwp_text_input_manager_v3_interface, 1); - } else if (strcmp(interface, wl_seat_interface.name) == 0) { - seat = wl_registry_bind(registry, name, &wl_seat_interface, version); - } -} - -static void handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) { - // who cares -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = handle_global_remove, -}; - -int main(int argc, char **argv) { - if (argc > 1) { - if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) { - printf(usage); - return 0; - } - sleeptime = atoi(argv[1]); - if (argc > 3) { - width = atoi(argv[2]); - height = atoi(argv[3]); - } - } - - buffer = calloc(1, sizeof(*buffer)); - - display = wl_display_connect(NULL); - if (display == NULL) { - fprintf(stderr, "Failed to create display\n"); - return EXIT_FAILURE; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (compositor == NULL) { - fprintf(stderr, "wl-compositor not available\n"); - return EXIT_FAILURE; - } - if (wm_base == NULL) { - fprintf(stderr, "xdg-shell not available\n"); - return EXIT_FAILURE; - } - if (text_input_manager == NULL) { - fprintf(stderr, "text-input not available\n"); - return EXIT_FAILURE; - } - - text_input = zwp_text_input_manager_v3_get_text_input(text_input_manager, seat); - - zwp_text_input_v3_add_listener(text_input, &text_input_listener, NULL); - - egl_init(display); - - struct wl_surface *surface = wl_compositor_create_surface(compositor); - struct xdg_surface *xdg_surface = - xdg_wm_base_get_xdg_surface(wm_base, surface); - struct xdg_toplevel *xdg_toplevel = xdg_surface_get_toplevel(xdg_surface); - - xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL); - xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL); - - wl_surface_commit(surface); - - egl_window = wl_egl_window_create(surface, width, height); - egl_surface = eglCreatePlatformWindowSurfaceEXT( - egl_display, egl_config, egl_window, NULL); - - wl_display_roundtrip(display); - - draw(); - - while (wl_display_dispatch(display) != -1) { - // This space intentionally left blank - } - - return EXIT_SUCCESS; -} diff --git a/examples/toplevel-decoration.c b/examples/toplevel-decoration.c deleted file mode 100644 index c5faf63d..00000000 --- a/examples/toplevel-decoration.c +++ /dev/null @@ -1,251 +0,0 @@ -#include <GLES2/gl2.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <wayland-client.h> -#include <wayland-egl.h> -#include "egl_common.h" -#include "xdg-shell-client-protocol.h" -#include "xdg-decoration-unstable-v1-client-protocol.h" - -/** - * Usage: toplevel-decoration [mode] - * Creates an xdg-toplevel supporting decoration negotiation. If `mode` is - * specified, the client will prefer this decoration mode. - */ - -static int width = 500, height = 300; - -static struct wl_compositor *compositor = NULL; -static struct xdg_wm_base *wm_base = NULL; -static struct zxdg_decoration_manager_v1 *decoration_manager = NULL; - -struct wl_egl_window *egl_window; -struct wlr_egl_surface *egl_surface; - -struct zxdg_toplevel_decoration_v1 *decoration; -enum zxdg_toplevel_decoration_v1_mode client_preferred_mode, current_mode; - -static const char *get_mode_name(enum zxdg_toplevel_decoration_v1_mode mode) { - switch (mode) { - case ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE: - return "client-side decorations"; - case ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE: - return "server-side decorations"; - } - abort(); -} - -static void request_preferred_mode(void) { - enum zxdg_toplevel_decoration_v1_mode mode = client_preferred_mode; - if (mode == 0) { - printf("Requesting compositor preferred mode\n"); - zxdg_toplevel_decoration_v1_unset_mode(decoration); - return; - } - if (mode == current_mode) { - return; - } - - printf("Requesting %s\n", get_mode_name(mode)); - zxdg_toplevel_decoration_v1_set_mode(decoration, mode); -} - -static void draw(void) { - eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context); - - float color[] = {1.0, 1.0, 0.0, 1.0}; - if (current_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE) { - color[0] = 0.0; - } - - glViewport(0, 0, width, height); - glClearColor(color[0], color[1], color[2], 1.0); - glClear(GL_COLOR_BUFFER_BIT); - - eglSwapBuffers(egl_display, egl_surface); -} - -static void xdg_surface_handle_configure(void *data, - struct xdg_surface *xdg_surface, uint32_t serial) { - xdg_surface_ack_configure(xdg_surface, serial); - wl_egl_window_resize(egl_window, width, height, 0, 0); - draw(); -} - -static const struct xdg_surface_listener xdg_surface_listener = { - .configure = xdg_surface_handle_configure, -}; - -static void xdg_toplevel_handle_configure(void *data, - struct xdg_toplevel *xdg_toplevel, int32_t w, int32_t h, - struct wl_array *states) { - width = w; - height = h; -} - -static const struct xdg_toplevel_listener xdg_toplevel_listener = { - .configure = xdg_toplevel_handle_configure, -}; - -static void decoration_handle_configure(void *data, - struct zxdg_toplevel_decoration_v1 *decoration, - enum zxdg_toplevel_decoration_v1_mode mode) { - printf("Using %s\n", get_mode_name(mode)); - current_mode = mode; -} - -static const struct zxdg_toplevel_decoration_v1_listener decoration_listener = { - .configure = decoration_handle_configure, -}; - -static void pointer_handle_enter(void *data, struct wl_pointer *pointer, - uint32_t serial, struct wl_surface *surface, - wl_fixed_t sx, wl_fixed_t sy) { - // No-op -} - -static void pointer_handle_leave(void *data, struct wl_pointer *pointer, - uint32_t serial, struct wl_surface *surface) { - // No-op -} - -static void pointer_handle_motion(void *data, struct wl_pointer *pointer, - uint32_t time, wl_fixed_t sx, wl_fixed_t sy) { - // No-op -} - -static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, uint32_t time, uint32_t button, - enum wl_pointer_button_state state) { - if (state == WL_POINTER_BUTTON_STATE_PRESSED) { - // Toggle mode - if (client_preferred_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) { - client_preferred_mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; - } else { - client_preferred_mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; - } - request_preferred_mode(); - } -} - -static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, - uint32_t time, enum wl_pointer_axis axis, wl_fixed_t value) { - // No-op -} - -static const struct wl_pointer_listener pointer_listener = { - .enter = pointer_handle_enter, - .leave = pointer_handle_leave, - .motion = pointer_handle_motion, - .button = pointer_handle_button, - .axis = pointer_handle_axis, -}; - -static void seat_handle_capabilities(void *data, struct wl_seat *seat, - enum wl_seat_capability caps) { - if (caps & WL_SEAT_CAPABILITY_POINTER) { - struct wl_pointer *pointer = wl_seat_get_pointer(seat); - wl_pointer_add_listener(pointer, &pointer_listener, NULL); - } -} - -static const struct wl_seat_listener seat_listener = { - .capabilities = seat_handle_capabilities, -}; - -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, wl_compositor_interface.name) == 0) { - compositor = wl_registry_bind(registry, name, &wl_compositor_interface, - 1); - } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { - wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); - } else if (strcmp(interface, zxdg_decoration_manager_v1_interface.name) == 0) { - decoration_manager = wl_registry_bind(registry, name, - &zxdg_decoration_manager_v1_interface, 1); - } else if (strcmp(interface, wl_seat_interface.name) == 0) { - struct wl_seat *seat = - wl_registry_bind(registry, name, &wl_seat_interface, 1); - wl_seat_add_listener(seat, &seat_listener, NULL); - } -} - -static void handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) { - // Who cares? -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = handle_global_remove, -}; - -int main(int argc, char **argv) { - if (argc == 2) { - char *mode = argv[1]; - if (strcmp(mode, "client") == 0) { - client_preferred_mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; - } else if (strcmp(mode, "server") == 0) { - client_preferred_mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; - } else { - fprintf(stderr, "Invalid decoration mode\n"); - return EXIT_FAILURE; - } - } - - struct wl_display *display = wl_display_connect(NULL); - if (display == NULL) { - fprintf(stderr, "Failed to create display\n"); - return EXIT_FAILURE; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (compositor == NULL) { - fprintf(stderr, "wl-compositor not available\n"); - return EXIT_FAILURE; - } - if (wm_base == NULL) { - fprintf(stderr, "xdg-shell not available\n"); - return EXIT_FAILURE; - } - if (decoration_manager == NULL) { - fprintf(stderr, "xdg-decoration not available\n"); - return EXIT_FAILURE; - } - - egl_init(display); - - struct wl_surface *surface = wl_compositor_create_surface(compositor); - struct xdg_surface *xdg_surface = - xdg_wm_base_get_xdg_surface(wm_base, surface); - struct xdg_toplevel *xdg_toplevel = xdg_surface_get_toplevel(xdg_surface); - decoration = zxdg_decoration_manager_v1_get_toplevel_decoration( - decoration_manager, xdg_toplevel); - - wl_display_roundtrip(display); - request_preferred_mode(); - - xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL); - xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL); - zxdg_toplevel_decoration_v1_add_listener(decoration, &decoration_listener, - NULL); - wl_surface_commit(surface); - - egl_window = wl_egl_window_create(surface, width, height); - egl_surface = eglCreatePlatformWindowSurfaceEXT( - egl_display, egl_config, egl_window, NULL); - - wl_display_roundtrip(display); - - draw(); - - while (wl_display_dispatch(display) != -1) { - // This space is intentionally left blank - } - - return EXIT_SUCCESS; -} diff --git a/examples/virtual-pointer.c b/examples/virtual-pointer.c deleted file mode 100644 index 27f4ed30..00000000 --- a/examples/virtual-pointer.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright © 2019 Josef Gajdusek - * - * 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 (including the next - * paragraph) 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. - */ - -#define _POSIX_C_SOURCE 200112L -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <wayland-client-protocol.h> -#include "wlr-virtual-pointer-unstable-v1-client-protocol.h" - -static struct wl_seat *seat = NULL; -static struct zwlr_virtual_pointer_manager_v1 *pointer_manager = NULL; - -static void handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, wl_seat_interface.name) == 0) { - seat = wl_registry_bind(registry, name, - &wl_seat_interface, version); - } else if (strcmp(interface, - zwlr_virtual_pointer_manager_v1_interface.name) == 0) { - pointer_manager = wl_registry_bind(registry, name, - &zwlr_virtual_pointer_manager_v1_interface, 1); - } -} - -static void handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) { - // Who cares? -} - -static const struct wl_registry_listener registry_listener = { - .global = handle_global, - .global_remove = handle_global_remove, -}; - -int main(int argc, char *argv[]) { - if (argc < 2) { - fprintf(stderr, "Usage: ./virtual-pointer <subcommand>\n"); - return EXIT_FAILURE; - } - struct wl_display * display = wl_display_connect(NULL); - if (display == NULL) { - perror("failed to create display"); - return EXIT_FAILURE; - } - - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_roundtrip(display); - - if (pointer_manager == NULL) { - fprintf(stderr, "compositor does not support wlr-virtual-pointer-unstable-v1\n"); - return EXIT_FAILURE; - } - - struct zwlr_virtual_pointer_v1 *pointer = - zwlr_virtual_pointer_manager_v1_create_virtual_pointer( - pointer_manager, seat); - - const char *cmd = argv[1]; - if (strcmp(cmd, "motion") == 0) { - if (argc < 4) { - fprintf(stderr, "Usage: ./virtual-pointer motion <dx> <dy>\n"); - return EXIT_FAILURE; - } - wl_fixed_t dx = wl_fixed_from_double(atof(argv[2])); - wl_fixed_t dy = wl_fixed_from_double(atof(argv[3])); - zwlr_virtual_pointer_v1_motion(pointer, 0, dx, dy); - } else if (strcmp(cmd, "absolute") == 0) { - if (argc < 6) { - fprintf(stderr, "Usage: ./virtual-pointer absolute <x> <y> <x_extent> <y_extent>\n"); - return EXIT_FAILURE; - } - uint32_t x = atoi(argv[2]); - uint32_t y = atoi(argv[3]); - uint32_t x_extent = atoi(argv[4]); - uint32_t y_extent = atoi(argv[5]); - zwlr_virtual_pointer_v1_motion_absolute(pointer, 0, x, y, x_extent, y_extent); - } else if (strcmp(cmd, "button") == 0) { - if (argc < 4) { - fprintf(stderr, "Usage: ./virtual-pointer button <button> press|release\n"); - return EXIT_FAILURE; - } - uint32_t button = atoi(argv[2]); - bool press = !!strcmp(argv[3], "release"); - zwlr_virtual_pointer_v1_button(pointer, 0, button, press); - } else if (strcmp(cmd, "axis") == 0) { - if (argc < 4) { - fprintf(stderr, "Usage: ./virtual-pointer axis <axis> <value>\n"); - return EXIT_FAILURE; - } - uint32_t axis = atoi(argv[2]); - wl_fixed_t value = wl_fixed_from_double(atof(argv[3])); - zwlr_virtual_pointer_v1_axis(pointer, 0, axis, value); - zwlr_virtual_pointer_v1_axis_stop(pointer, 0, axis); - } else if (strcmp(cmd, "axis_discrete") == 0) { - if (argc < 5) { - fprintf(stderr, "Usage: ./virtual-pointer axis <axis> <value> <value_discrete>\n"); - return EXIT_FAILURE; - } - uint32_t axis = atoi(argv[2]); - wl_fixed_t value = wl_fixed_from_double(atof(argv[3])); - uint32_t discrete = atoi(argv[4]); - zwlr_virtual_pointer_v1_axis_discrete(pointer, 0, axis, value, discrete); - zwlr_virtual_pointer_v1_axis_stop(pointer, 0, axis); - } else { - fprintf(stderr, "Invalid subcommand\n"); - return EXIT_FAILURE; - } - - zwlr_virtual_pointer_v1_frame(pointer); - zwlr_virtual_pointer_v1_destroy(pointer); - - wl_display_flush(display); - - return EXIT_SUCCESS; -} |