Copyright (c) 2022 Samsung Electronics co., Ltd. All Rights Reserved.
-Copyright (c) 2017, 2018 Drew DeVault
-Copyright (c) 2014 Jari Vetoniemi
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
-[] Implement a xdg shell
-[] Implement a KMS/DRM backend
-[] Implement a libinput backend
-[] Implement an input
-[] Implement a viewporter
-[] Make up a ds output interface
[] Make up tests
[] Document APIs
+++ /dev/null
-#ifndef LIBDS_ALLOCATOR_H
-#define LIBDS_ALLOCATOR_H
-
-#include <libds/buffer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_allocator;
-
-void
-ds_allocator_destroy(struct ds_allocator *alloc);
-
-struct ds_buffer *
-ds_allocator_create_buffer(struct ds_allocator *alloc, int width, int height,
- uint32_t format);
-
-void
-ds_allocator_add_destroy_listener(struct ds_allocator *alloc,
- struct wl_listener *listener);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_ALLOCATOR_SHM_H
-#define LIBDS_ALLOCATOR_SHM_H
-
-#include <libds/allocator.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_allocator *
-ds_shm_allocator_create(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_BACKEND_H
-#define LIBDS_BACKEND_H
-
-#include <stdbool.h>
-#include <wayland-server.h>
-#include <libds/buffer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_backend;
-
-bool
-ds_backend_start(struct ds_backend *backend);
-
-void
-ds_backend_destroy(struct ds_backend *backend);
-
-int
-ds_backend_get_drm_fd(struct ds_backend *backend);
-
-enum ds_buffer_caps
-ds_backend_get_buffer_caps(struct ds_backend *backend);
-
-void
-ds_backend_add_destroy_listener(struct ds_backend *backend,
- struct wl_listener *listener);
-
-void
-ds_backend_add_new_output_listener(struct ds_backend *backend,
- struct wl_listener *listener);
-
-void
-ds_backend_add_new_input_listener(struct ds_backend *backend,
- struct wl_listener *listener);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_BACKEND_LIBINPUT_H
-#define LIBDS_BACKEND_LIBINPUT_H
-
-#include <libds/backend.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_backend *
-ds_libinput_backend_create(struct wl_display *display);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_BACKEND_WAYLAND_H
-#define LIBDS_BACKEND_WAYLAND_H
-
-#include <libds/backend.h>
-#include <libds/output.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_backend *
-ds_wl_backend_create(struct wl_display *display, const char *server_name);
-
-struct ds_output *
-ds_wl_backend_create_output(struct ds_backend *backend);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_BUFFER_H
-#define LIBDS_BUFFER_H
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <wayland-server.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_buffer;
-
-enum ds_buffer_caps
-{
- DS_BUFFER_CAP_DATA_PTR = 1 << 0,
- DS_BUFFER_CAP_DMABUF = 1 << 1,
- DS_BUFFER_CAP_SHM = 1 << 2,
-};
-
-enum ds_buffer_data_ptr_access_flag
-{
- DS_BUFFER_DATA_PTR_ACCESS_READ = 1 << 0,
- DS_BUFFER_DATA_PTR_ACCESS_WRITE = 1 << 1,
-};
-
-struct ds_shm_attributes
-{
- int fd;
- uint32_t format;
- int width, height, stride;
- off_t offset;
-};
-
-struct ds_buffer_resource_interface
-{
- const char *name;
- bool (*is_instance)(struct wl_resource *resource);
- struct ds_buffer *(*from_resource)(struct wl_resource *resource);
-};
-
-struct ds_buffer *
-ds_buffer_from_resource(struct wl_resource *resource);
-
-void
-ds_buffer_drop(struct ds_buffer *buffer);
-
-struct ds_buffer *
-ds_buffer_lock(struct ds_buffer *buffer);
-
-void
-ds_buffer_unlock(struct ds_buffer *buffer);
-
-bool
-ds_buffer_get_shm(struct ds_buffer *buffer, struct ds_shm_attributes *attribs);
-
-void
-ds_buffer_get_size(struct ds_buffer *buffer, int *out_width, int *out_height);
-
-void
-ds_buffer_add_destroy_listener(struct ds_buffer *buffer,
- struct wl_listener *listener);
-
-void
-ds_buffer_add_release_listener(struct ds_buffer *buffer,
- struct wl_listener *listener);
-
-bool
-ds_buffer_begin_data_ptr_access(struct ds_buffer *buffer,
- enum ds_buffer_data_ptr_access_flag flags, void **data,
- uint32_t *format, size_t *stride);
-
-void
-ds_buffer_end_data_ptr_access(struct ds_buffer *buffer);
-
-void
-ds_buffer_register_resource_interface(
- const struct ds_buffer_resource_interface *iface);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_COMPOSITOR_H
-#define LIBDS_COMPOSITOR_H
-
-#include <wayland-server.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_compositor;
-
-struct ds_compositor *
-ds_compositor_create(struct wl_display *display);
-
-void
-ds_compositor_add_new_surface_listener(struct ds_compositor *compositor,
- struct wl_listener *listener);
-
-void
-ds_compositor_add_destroy_listener(struct ds_compositor *compositor,
- struct wl_listener *listener);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_INPUT_DEVICE_H
-#define LIBDS_INPUT_DEVICE_H
-
-struct ds_input_device;
-
-struct ds_pointer;
-
-struct ds_keyboard;
-
-struct ds_touch;
-
-enum ds_button_state
-{
- DS_BUTTON_RELEASED,
- DS_BUTTON_PRESSED,
-};
-
-enum ds_input_device_type
-{
- DS_INPUT_DEVICE_POINTER,
- DS_INPUT_DEVICE_KEYBOARD,
- DS_INPUT_DEVICE_TOUCH,
-};
-
-enum ds_input_device_type
-ds_input_device_get_type(struct ds_input_device *dev);
-
-const char *
-ds_input_device_get_name(struct ds_input_device *dev);
-
-struct ds_pointer *
-ds_input_device_get_pointer(struct ds_input_device *dev);
-
-struct ds_keyboard *
-ds_input_device_get_keyboard(struct ds_input_device *dev);
-
-struct ds_touch *
-ds_input_device_get_touch(struct ds_input_device *dev);
-
-void
-ds_input_device_add_destroy_listener(struct ds_input_device *dev,
- struct wl_listener *listener);
-
-#endif
+++ /dev/null
-#ifndef LIBDS_INTERFACES_ALLOCATOR_H
-#define LIBDS_INTERFACES_ALLOCATOR_H
-
-#include <wayland-server.h>
-#include <libds/buffer.h>
-
-struct ds_allocator;
-
-struct ds_allocator_interface {
- struct ds_buffer *(*create_buffer)(struct ds_allocator *alloc,
- int width, int height, uint32_t format);
- void (*destroy)(struct ds_allocator *alloc);
-};
-
-struct ds_allocator
-{
- const struct ds_allocator_interface *iface;
-
- uint32_t buffer_caps;
-
- struct {
- struct wl_signal destroy;
- } events;
-};
-
-void
-ds_allocator_init(struct ds_allocator *alloc,
- const struct ds_allocator_interface *iface, uint32_t buffer_caps);
-
-void
-ds_allocator_destroy(struct ds_allocator *alloc);
-
-#endif
+++ /dev/null
-#ifndef LIBDS_INTERFACES_BACKEND_H
-#define LIBDS_INTERFACES_BACKEND_H
-
-#include <wayland-server.h>
-
-struct ds_backend;
-
-struct ds_backend_interface
-{
- bool (*start)(struct ds_backend *backend);
- void (*destroy)(struct ds_backend *backend);
- int (*get_drm_fd)(struct ds_backend *backend);
-};
-
-struct ds_backend
-{
- const struct ds_backend_interface *iface;
-
- struct wl_display *display;
-
- struct
- {
- struct wl_signal destroy;
- struct wl_signal new_output;
- struct wl_signal new_input;
- } events;
-
- bool started;
-};
-
-void
-ds_backend_init(struct ds_backend *backend, struct wl_display *display,
- const struct ds_backend_interface *iface);
-
-void
-ds_backend_finish(struct ds_backend *backend);
-
-#endif
+++ /dev/null
-#ifndef LIBDS_INTERFACES_BUFFER_H
-#define LIBDS_INTERFACES_BUFFER_H
-
-#include <wayland-server.h>
-#include <libds/buffer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_buffer;
-
-struct ds_buffer_interface
-{
- void (*destroy)(struct ds_buffer *buffer);
- bool (*get_shm)(struct ds_buffer *buffer,
- struct ds_shm_attributes *attribs);
- bool (*begin_data_ptr_access)(struct ds_buffer *buffer, uint32_t flags,
- void **data, uint32_t *format, size_t *stride);
- void (*end_data_ptr_access)(struct ds_buffer *buffer);
-};
-
-struct ds_buffer
-{
- const struct ds_buffer_interface *iface;
- void *iface_data;
-
- int width, height;
- size_t n_locks;
-
- bool dropped;
- bool accessing_data_ptr;
-
- struct {
- struct wl_signal destroy;
- struct wl_signal release;
- } events;
-};
-
-void
-ds_buffer_init(struct ds_buffer *buffer,
- const struct ds_buffer_interface *iface, int width, int height);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_INTERFACES_INPUT_DEVICE_H
-#define LIBDS_INTERFACES_INPUT_DEVICE_H
-
-#include <wayland-server.h>
-#include <libds/input_device.h>
-#include <libds/pointer.h>
-#include <libds/keyboard.h>
-#include <libds/touch.h>
-
-struct ds_input_device_interface
-{
- void (*destroy)(struct ds_input_device *dev);
-};
-
-struct ds_input_device
-{
- const struct ds_input_device_interface *iface;
-
- char *name;
- double width_mm, height_mm;
- char *output_name;
-
- enum ds_input_device_type type;
- union {
- void *_device;
- struct ds_pointer *pointer;
- struct ds_keyboard *keyboard;
- struct ds_touch *touch;
- };
-
- struct {
- struct wl_signal destroy;
- } events;
-
- struct wl_list link;
-};
-
-void ds_input_device_init(struct ds_input_device *dev,
- enum ds_input_device_type type,
- const struct ds_input_device_interface *iface,
- const char *name, int vendor, int product);
-void ds_input_device_destroy(struct ds_input_device *dev);
-
-#endif
+++ /dev/null
-#ifndef LIBDS_INTERFACES_KEYBOARD_H
-#define LIBDS_INTERFACES_KEYBOARD_H
-
-#include <wayland-server.h>
-#include <xkbcommon/xkbcommon.h>
-
-#include <libds/keyboard.h>
-
-#define DS_LED_COUNT 3
-
-enum ds_keyboard_led {
- DS_LED_NUM_LOCK = 1 << 0,
- DS_LED_CAPS_LOCK = 1 << 1,
- DS_LED_SCROLL_LOCK = 1 << 2,
-};
-
-#define DS_KEYBOARD_KEYS_CAP 32
-
-struct ds_keyboard;
-
-struct ds_keyboard_interface
-{
- void (*destroy)(struct ds_keyboard *keyboard);
-};
-
-struct ds_keyboard
-{
- const struct ds_keyboard_interface *iface;
-
- char *keymap_string;
- size_t keymap_size;
- int keymap_fd;
- struct xkb_keymap *keymap;
- struct xkb_state *xkb_state;
- xkb_led_index_t led_indexes[DS_LED_COUNT];
- xkb_mod_index_t mod_indexes[DS_MODIFIER_COUNT];
-
- uint32_t keycodes[DS_KEYBOARD_KEYS_CAP];
- size_t num_keycodes;
- struct ds_keyboard_modifiers modifiers;
-
- struct {
- int32_t rate;
- int32_t delay;
- } repeat_info;
-
- struct {
- struct wl_signal destroy;
- struct wl_signal key;
- struct wl_signal modifiers;
- struct wl_signal keymap;
- struct wl_signal repeat_info;
- } events;
-};
-
-void ds_keyboard_init(struct ds_keyboard *keyboard,
- const struct ds_keyboard_interface *iface);
-
-void ds_keyboard_destroy(struct ds_keyboard *keyboard);
-
-void ds_keyboard_notify_key(struct ds_keyboard *keyboard,
- struct ds_event_keyboard_key *event);
-
-void ds_keyboard_notify_modifiers(struct ds_keyboard *keyboard,
- uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked,
- uint32_t group);
-
-#endif
+++ /dev/null
-#ifndef LIBDS_INTERFACES_OUTPUT_H
-#define LIBDS_INTERFACES_OUTPUT_H
-
-#include <stdint.h>
-#include <wayland-server.h>
-#include <libds/output.h>
-#include <libds/backend.h>
-#include <libds/buffer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_output;
-
-enum ds_output_state_field
-{
- DS_OUTPUT_STATE_BUFFER = 1 << 0,
- DS_OUTPUT_STATE_DAMAGE = 1 << 1,
- DS_OUTPUT_STATE_MODE = 1 << 2,
- DS_OUTPUT_STATE_ENABLED = 1 << 3,
- DS_OUTPUT_STATE_SCALE = 1 << 4,
- DS_OUTPUT_STATE_TRANSFORM = 1 << 5,
-};
-
-enum ds_output_state_mode_type
-{
- DS_OUTPUT_STATE_MODE_FIXED,
- DS_OUTPUT_STATE_MODE_CUSTOM,
-};
-
-struct ds_output_interface
-{
- void (*destroy)(struct ds_output *output);
- bool (*commit)(struct ds_output *output);
-};
-
-struct ds_output_state
-{
- enum ds_output_state_field committed;
- struct ds_buffer *buffer;
-
- enum ds_output_state_mode_type mode_type;
- const struct ds_output_mode *mode;
- struct {
- int32_t width, height;
- int32_t refresh; // mHz, may be zero
- } custom_mode;
-
- bool enabled;
-};
-
-struct ds_output
-{
- const struct ds_output_interface *iface;
-
- struct ds_backend *backend;
-
- struct wl_display *display;
- struct wl_global *global;
-
- struct ds_buffer *back_buffer, *front_buffer;
- const struct ds_output_mode *current_mode;
- int32_t width, height;
- int32_t refresh; // mHz, may be zero
- struct ds_output_state pending;
-
- struct wl_list modes;
-
- struct wl_listener display_destroy;
-
- struct {
- struct wl_signal destroy;
- struct wl_signal frame;
- struct wl_signal commit;
- } events;
-
- bool enabled;
-};
-
-void
-ds_output_init(struct ds_output *output, struct ds_backend *backend,
- const struct ds_output_interface *iface, struct wl_display *display);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_INTERFACES_POINTER_H
-#define LIBDS_INTERFACES_POINTER_H
-
-#include <wayland-server.h>
-
-struct ds_pointer;
-
-struct ds_pointer_interface
-{
- void (*destroy)(struct ds_pointer *pointer);
-};
-
-struct ds_pointer
-{
- const struct ds_pointer_interface *iface;
-
- struct {
- struct wl_signal motion;
- struct wl_signal motion_absolute;
- struct wl_signal button;
- struct wl_signal frame;
- } events;
-};
-
-void ds_pointer_init(struct ds_pointer *pointer,
- const struct ds_pointer_interface *iface);
-
-void ds_pointer_destroy(struct ds_pointer *pointer);
-
-#endif
+++ /dev/null
-#ifndef LIBDS_INTERFACES_TOUCH_H
-#define LIBDS_INTERFACES_TOUCH_H
-
-#include <wayland-server.h>
-
-struct ds_touch;
-
-struct ds_touch_interface
-{
- void (*destroy)(struct ds_touch *touch);
-};
-
-struct ds_touch
-{
- const struct ds_touch_interface *iface;
-
- struct {
- struct wl_signal down;
- struct wl_signal up;
- struct wl_signal motion;
- struct wl_signal frame;
- } events;
-};
-
-void ds_touch_init(struct ds_touch *touch,
- const struct ds_touch_interface *iface);
-
-void ds_touch_destroy(struct ds_touch *touch);
-
-#endif
+++ /dev/null
-#ifndef LIBDS_KEYBOARD_H
-#define LIBDS_KEYBOARD_H
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#include <wayland-server.h>
-#include <xkbcommon/xkbcommon.h>
-
-struct ds_keyboard;
-
-#define DS_MODIFIER_COUNT 8
-
-enum ds_keyboard_modifier {
- DS_MODIFIER_SHIFT = 1 << 0,
- DS_MODIFIER_CAPS = 1 << 1,
- DS_MODIFIER_CTRL = 1 << 2,
- DS_MODIFIER_ALT = 1 << 3,
- DS_MODIFIER_MOD2 = 1 << 4,
- DS_MODIFIER_MOD3 = 1 << 5,
- DS_MODIFIER_LOGO = 1 << 6,
- DS_MODIFIER_MOD5 = 1 << 7,
-};
-
-struct ds_keyboard_modifiers
-{
- xkb_mod_mask_t depressed;
- xkb_mod_mask_t latched;
- xkb_mod_mask_t locked;
- xkb_mod_mask_t group;
-};
-
-struct ds_event_keyboard_key
-{
- uint32_t time_msec;
- uint32_t keycode;
- bool update_state;
- enum wl_keyboard_key_state state;
-};
-
-bool ds_keyboard_set_keymap(struct ds_keyboard *keyboard,
- struct xkb_keymap *keymap);
-
-void ds_keyboard_set_repeat_info(struct ds_keyboard *keyboard,
- int32_t rate, int32_t delay);
-
-uint32_t ds_keyboard_get_modifiers(struct ds_keyboard *keyboard);
-
-struct xkb_state *ds_keyboard_get_xkb_state(struct ds_keyboard *keyboard);
-
-void ds_keyboard_add_destroy_listener(struct ds_keyboard *keyboard,
- struct wl_listener *listener);
-
-void ds_keyboard_add_key_listener(struct ds_keyboard *keyboard,
- struct wl_listener *listener);
-
-void ds_keyboard_add_modifiers_listener(struct ds_keyboard *keyboard,
- struct wl_listener *listener);
-
-void ds_keyboard_add_keymap_listener(struct ds_keyboard *keyboard,
- struct wl_listener *listener);
-
-void ds_keyboard_add_repeat_info_listener(struct ds_keyboard *keyboard,
- struct wl_listener *listener);
-
-#endif
+++ /dev/null
-#ifndef LIBDS_LOG_H
-#define LIBDS_LOG_H
-
-#include <stdbool.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum ds_log_level {
- DS_SILENT = 0,
- DS_ERR = 1,
- DS_INF = 2,
- DS_DBG = 3,
- DS_LOG_LEVEL_LAST,
-};
-
-typedef void (*ds_log_func_t)(enum ds_log_level level,
- const char *fmt, va_list args);
-
-void ds_log_init(enum ds_log_level level, ds_log_func_t callback);
-
-enum ds_log_level ds_log_get_level(void);
-
-#ifdef __GNUC__
-#define _DS_ATTRIB_PRINTF(start, end) __attribute__((format(printf, start, end)))
-#else
-#define _DS_ATTRIB_PRINTF(start, end)
-#endif
-
-void _ds_log(enum ds_log_level level, const char *format, ...) _DS_ATTRIB_PRINTF(2, 3);
-void _ds_vlog(enum ds_log_level level, const char *format, va_list args) _DS_ATTRIB_PRINTF(2, 0);
-
-#define ds_log(level, fmt, ...) \
- _ds_log(level, "[%s:%d] " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
-
-#define ds_vlog(level, fmt, args) \
- _ds_vlog(level, "[%s:%d] " fmt, __FILE__, __LINE__, args)
-
-#define ds_log_errno(level, fmt, ...) \
- ds_log(level, fmt ": %s", ##__VA_ARGS__, strerror(errno))
-
-#define ds_err(fmt, ...) \
- ds_log(DS_ERR, fmt, ##__VA_ARGS__)
-
-#define ds_inf(fmt, ...) \
- ds_log(DS_INF, fmt, ##__VA_ARGS__)
-
-#define ds_dbg(fmt, ...) \
- ds_log(DS_DBG, fmt, ##__VA_ARGS__)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_OUTPUT_H
-#define LIBDS_OUTPUT_H
-
-#include <time.h>
-#include <libds/buffer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_output;
-
-struct ds_output_mode {
- int32_t width, height;
- int32_t refresh; // mHz
- bool preferred;
- struct wl_list link;
-};
-
-void
-ds_output_destroy(struct ds_output *output);
-
-void
-ds_output_enable(struct ds_output *output);
-
-void
-ds_output_disable(struct ds_output *output);
-
-bool
-ds_output_commit(struct ds_output *output);
-
-void
-ds_output_attach_buffer(struct ds_output *output, struct ds_buffer *buffer);
-
-const struct ds_output_mode *
-ds_output_get_preferred_mode(struct ds_output *output);
-
-void
-ds_output_set_mode(struct ds_output *output,
- const struct ds_output_mode *mode);
-
-void
-ds_output_set_custom_mode(struct ds_output *output,
- int32_t width, int32_t height, int32_t refresh);
-
-void
-ds_output_add_destroy_listener(struct ds_output *output,
- struct wl_listener *listener);
-
-void
-ds_output_add_frame_listener(struct ds_output *output,
- struct wl_listener *listener);
-
-void
-ds_output_add_commit_listener(struct ds_output *output,
- struct wl_listener *listener);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_POINTER_H
-#define LIBDS_POINTER_H
-
-#include <stdint.h>
-#include <wayland-server.h>
-#include <libds/input_device.h>
-
-struct ds_pointer;
-
-struct ds_event_pointer_motion_absolute
-{
- struct ds_input_device *device;
- uint32_t time_msec;
- // From 0..1
- double x, y;
-};
-
-struct ds_event_pointer_motion
-{
- struct ds_input_device *device;
- uint32_t time_msec;
- double delta_x, delta_y;
-};
-
-struct ds_event_pointer_button
-{
- struct ds_input_device *device;
- uint32_t time_msec;
- uint32_t button;
- enum ds_button_state state;
-};
-
-void ds_pointer_add_motion_listener(struct ds_pointer *pointer,
- struct wl_listener *listener);
-
-void ds_pointer_add_motion_absolute_listener(struct ds_pointer *pointer,
- struct wl_listener *listener);
-
-void ds_pointer_add_button_listener(struct ds_pointer *pointer,
- struct wl_listener *listener);
-
-void ds_pointer_add_frame_listener(struct ds_pointer *pointer,
- struct wl_listener *listener);
-
-#endif
+++ /dev/null
-#ifndef LIBstruct ds_presentationIME_H
-#define LIBstruct ds_presentationIME_H
-
-#include <time.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_presentation;
-
-struct ds_presentation *
-ds_presentation_create(struct wl_display *display,
- clockid_t clk_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_SEAT_H
-#define LIBDS_SEAT_H
-
-#include <stdint.h>
-#include <wayland-server.h>
-
-#include <libds/input_device.h>
-#include <libds/keyboard.h>
-#include <libds/surface.h>
-
-struct ds_seat;
-
-enum ds_axis_orientation
-{
- DS_AXIS_ORIENTATION_VERTICAL,
- DS_AXIS_ORIENTATION_HORIZONTAL,
-};
-
-enum ds_axis_source
-{
- DS_AXIS_SOURCE_WHEEL,
- DS_AXIS_SOURCE_FINGER,
- DS_AXIS_SOURCE_CONTINUOUS,
- DS_AXIS_SOURCE_WHEEL_TILT,
-};
-
-struct ds_event_seat_pointer_focus_change
-{
- struct ds_seat *seat;
- struct ds_surface *old_surface, *new_surface;
- double sx, sy;
-};
-
-struct ds_event_seat_keyboard_focus_change
-{
- struct ds_seat *seat;
- struct ds_surface *old_surface, *new_surface;
-};
-
-struct ds_seat *ds_seat_create(struct wl_display *display, const char *name);
-
-void ds_seat_destroy(struct ds_seat *seat);
-
-void ds_seat_set_capabilities(struct ds_seat *seat,
- enum wl_seat_capability capabilities);
-
-void ds_seat_set_name(struct ds_seat *seat, const char *name);
-
-void ds_seat_add_destroy_listener(struct ds_seat *seat,
- struct wl_listener *listener);
-
-void ds_seat_pointer_notify_enter(struct ds_seat *seat,
- struct ds_surface *surface, double sx, double sy);
-
-void ds_seat_pointer_notify_clear_focus(struct ds_seat *seat);
-
-void ds_seat_pointer_notify_motion(struct ds_seat *seat, uint32_t time_msec,
- double sx, double sy);
-
-uint32_t ds_seat_pointer_notify_button(struct ds_seat *seat,
- uint32_t time_msec, uint32_t button, enum ds_button_state state);
-
-void ds_seat_pointer_notify_axis(struct ds_seat *seat, uint32_t time_msec,
- enum ds_axis_orientation orientation, double value,
- int32_t value_discrete, enum ds_axis_source source);
-
-void ds_seat_pointer_notify_frame(struct ds_seat *seat);
-
-void ds_seat_pointer_add_grab_begin_listener(struct ds_seat *seat,
- struct wl_listener *listener);
-
-void ds_seat_pointer_add_grab_end_listener(struct ds_seat *seat,
- struct wl_listener *listener);
-
-void ds_seat_pointer_add_focus_change_listener(struct ds_seat *seat,
- struct wl_listener *listener);
-
-void ds_seat_keyboard_notify_enter(struct ds_seat *seat,
- struct ds_surface *surface, uint32_t keycodes[], size_t num_keycodes,
- struct ds_keyboard_modifiers *modifiers);
-
-void ds_seat_keyboard_notify_clear_focus(struct ds_seat *seat);
-
-void ds_seat_keyboard_notify_modifiers(struct ds_seat *seat,
- struct ds_keyboard_modifiers *modifiers);
-
-void ds_seat_keyboard_notify_key(struct ds_seat *seat, uint32_t time_msec,
- uint32_t key, uint32_t state);
-
-void ds_seat_keyboard_add_grab_begin_listener(struct ds_seat *seat,
- struct wl_listener *listener);
-
-void ds_seat_keyboard_add_grab_end_listener(struct ds_seat *seat,
- struct wl_listener *listener);
-
-void ds_seat_keyboard_add_focus_change_listener(struct ds_seat *seat,
- struct wl_listener *listener);
-
-void ds_seat_touch_end_grab_start_listener(struct ds_seat *seat,
- struct wl_listener *listener);
-
-uint32_t ds_seat_touch_notify_down(struct ds_seat *seat,
- struct ds_surface *surface, uint32_t time_msec, int32_t touch_id,
- double sx, double sy);
-
-void ds_seat_touch_notify_up(struct ds_seat *seat, uint32_t time_msec,
- int32_t touch_id);
-
-void ds_seat_touch_notify_motion(struct ds_seat *seat, uint32_t time_msec,
- int32_t touch_id, double sx, double sy);
-
-void ds_seat_touch_notify_frame(struct ds_seat *seat);
-
-void ds_seat_touch_add_grab_start_listener(struct ds_seat *seat,
- struct wl_listener *listener);
-
-#endif
+++ /dev/null
-#ifndef LIBDS_SHELL_H
-#define LIBDS_SHELL_H
-
-#include <stdint.h>
-#include <wayland-server.h>
-
-#include "surface.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_shell;
-
-struct ds_shell_surface;
-
-struct ds_shell *
-ds_shell_create(struct wl_display *display);
-
-void
-ds_shell_add_destroy_listener(struct ds_shell *shell,
- struct wl_listener *listener);
-
-void
-ds_shell_add_new_surface_listener(struct ds_shell *shell,
- struct wl_listener *listener);
-
-void
-ds_shell_surface_add_destroy_listener(struct ds_shell_surface *surface,
- struct wl_listener *listener);
-
-void
-ds_shell_surface_add_map_listener(struct ds_shell_surface *surface,
- struct wl_listener *listener);
-
-void
-ds_shell_surface_add_unmap_listener(struct ds_shell_surface *surface,
- struct wl_listener *listener);
-
-void
-ds_shell_surface_ping(struct ds_shell_surface *surface);
-
-struct ds_surface *
-ds_shell_surface_get_surface(struct ds_shell_surface *surface);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_SUBSURFACE_H
-#define LIBDS_SUBSURFACE_H
-
-#include <libds/surface.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_subsurface;
-
-bool ds_surface_is_subsurface(struct ds_surface *surface);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_SURFACE_H
-#define LIBDS_SURFACE_H
-
-#include <time.h>
-#include <wayland-server.h>
-
-#include <libds/buffer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_surface;
-
-typedef bool (*ds_surface_for_each_func_t)(struct ds_surface *surface,
- int sx, int sy, void *data);
-
-void
-ds_surface_add_destroy_listener(struct ds_surface *surface,
- struct wl_listener *listener);
-
-void
-ds_surface_add_commit_listener(struct ds_surface *surface,
- struct wl_listener *listener);
-
-void
-ds_surface_add_new_subsurface_listener(struct ds_surface *surface,
- struct wl_listener *listener);
-
-struct ds_buffer *
-ds_surface_get_buffer(struct ds_surface *surface);
-
-void
-ds_surface_for_each(struct ds_surface *surface,
- ds_surface_for_each_func_t iterator, void *data);
-
-void
-ds_surface_send_frame_done(struct ds_surface *surface,
- const struct timespec *when);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_SWAPCHAIN_H
-#define LIBDS_SWAPCHAIN_H
-
-#include <libds/allocator.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_swapchain;
-
-struct ds_swapchain *
-ds_swapchain_create(struct ds_allocator *alloc, int width, int height,
- uint32_t format);
-
-void
-ds_swapchain_destroy(struct ds_swapchain *swapchain);
-
-struct ds_buffer *
-ds_swapchain_acquire(struct ds_swapchain *swapchain, int *age);
-
-void
-ds_swapchain_set_buffer_submitted(struct ds_swapchain *swapchain,
- struct ds_buffer *buffer);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_TOUCH_H
-#define LIBDS_TOUCH_H
-
-#include <stdint.h>
-#include <wayland-server.h>
-#include <libds/input_device.h>
-
-struct ds_touch;
-
-struct ds_event_touch_down
-{
- struct ds_input_device *device;
- uint32_t time_msec;
- //wl_surface surface;
- uint32_t id;
- double x, y;
-};
-
-struct ds_event_touch_up
-{
- struct ds_input_device *device;
- uint32_t time_msec;
- uint32_t id;
-};
-
-struct ds_event_touch_motion
-{
- struct ds_input_device *device;
- uint32_t time_msec;
- uint32_t id;
- double x, y;
-};
-
-void ds_touch_add_down_listener(struct ds_touch *touch,
- struct wl_listener *listener);
-
-void ds_touch_add_up_listener(struct ds_touch *touch,
- struct wl_listener *listener);
-
-void ds_touch_add_motion_listener(struct ds_touch *touch,
- struct wl_listener *listener);
-
-void ds_touch_add_frame_listener(struct ds_touch *touch,
- struct wl_listener *listener);
-
-#endif
+++ /dev/null
-#ifndef LIBDS_XDG_SHELL_H
-#define LIBDS_XDG_SHELL_H
-
-#include <stdint.h>
-#include <wayland-server.h>
-
-#include "surface.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_xdg_shell;
-
-struct ds_xdg_surface;
-
-struct ds_xdg_shell *
-ds_xdg_shell_create(struct wl_display *display);
-
-void
-ds_xdg_shell_add_destroy_listener(struct ds_xdg_shell *shell,
- struct wl_listener *listener);
-
-void
-ds_xdg_shell_add_new_surface_listener(struct ds_xdg_shell *shell,
- struct wl_listener *listener);
-
-void
-ds_xdg_surface_add_destroy_listener(struct ds_xdg_surface *surface,
- struct wl_listener *listener);
-
-void
-ds_xdg_surface_add_map_listener(struct ds_xdg_surface *surface,
- struct wl_listener *listener);
-
-void
-ds_xdg_surface_add_unmap_listener(struct ds_xdg_surface *surface,
- struct wl_listener *listener);
-
-void
-ds_xdg_surface_ping(struct ds_xdg_surface *surface);
-
-struct ds_surface *
-ds_xdg_surface_get_surface(struct ds_xdg_surface *surface);
-
-uint32_t
-ds_xdg_toplevel_set_size(struct ds_xdg_surface *surface,
- uint32_t width, uint32_t height);
-
-uint32_t
-ds_xdg_toplevel_set_activated(struct ds_xdg_surface *surface,
- bool activated);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-install_subdir('libds',
+install_subdir('libds-tizen',
install_dir: get_option('includedir'),
)
-
-if get_option('tizen')
- install_subdir('libds-tizen',
- install_dir: get_option('includedir'),
- )
-endif
-project('libds', 'c',
+project('libds_tizen', 'c',
license: 'MIT',
version: '0.1.2',
default_options: [
]
)
-libds_version = meson.project_version()
-version_arr = libds_version.split('.')
-libds_version_major = version_arr[0]
-libds_version_minor = version_arr[1]
-libds_version_patch = version_arr[2]
+libds_tizen_version = meson.project_version()
+version_arr = libds_tizen_version.split('.')
+libds_tizen_version_major = version_arr[0]
+libds_tizen_version_minor = version_arr[1]
+libds_tizen_version_patch = version_arr[2]
dir_prefix = get_option('prefix')
-libds_bindir = join_paths(dir_prefix, get_option('bindir'))
+libds_tizen_bindir = join_paths(dir_prefix, get_option('bindir'))
-libds_inc = include_directories('include')
-common_inc = [ include_directories('.'), libds_inc ]
+libds_tizen_inc = include_directories('include')
+common_inc = [ include_directories('.'), libds_tizen_inc ]
cdata = configuration_data()
-cdata.set('LIBDS_VERSION_MAJOR', libds_version_major)
-cdata.set('LIBDS_VERSION_MINOR', libds_version_minor)
-cdata.set('LIBDS_VERSION_PATCH', libds_version_patch)
+cdata.set('LIBDS_VERSION_MAJOR', libds_tizen_version_major)
+cdata.set('LIBDS_VERSION_MINOR', libds_tizen_version_minor)
+cdata.set('LIBDS_VERSION_PATCH', libds_tizen_version_patch)
subdir('src')
subdir('include')
-option('tizen', type: 'boolean', value: false, description: 'Build Tizen features')
option('keylayout_dir', type: 'string', value: '', description: 'Directory where tizen key layout file is')
\ No newline at end of file
-Name: libds
+Name: libds-tizen
Version: 0.1.2
Release: 0
-Summary: Wayland Compositor Library
+Summary: Wayland Compositor Library for Tizen
License: MIT
URL: http://www.tizen.org/
Source: %name-%version.tar.xz
Source1001: %name.manifest
BuildRequires: meson
+BuildRequires: pkgconfig(libds)
BuildRequires: pkgconfig(wayland-server)
BuildRequires: pkgconfig(wayland-client)
BuildRequires: pkgconfig(wayland-protocols)
BuildRequires: pkgconfig(pixman-1)
BuildRequires: pkgconfig(libdrm)
BuildRequires: pkgconfig(xkbcommon)
-BuildRequires: pkgconfig(libinput)
-BuildRequires: pkgconfig(libudev)
BuildRequires: pkgconfig(libtdm)
BuildRequires: pkgconfig(libtbm)
BuildRequires: pkgconfig(libsmack)
%description
-Wayland Compositor Library
+Wayland Compositor Library for Tizen
%package devel
-Summary: Wayland Compositor Library
+Summary: Wayland Compositor Library for Tizen
Group: Development/Libraries
Requires: %{name} = %{version}-%{release}
%description devel
-Development package of Wayland Compositor Library
+Development package of Wayland Compositor Library for Tizen
-%package tizen-devel
-Summary: Wayland Compositor development package on Tizen
-
-%description tizen-devel
-Wayland Compositor development library for Tizen platform
-
-%package tizen-keyrouter
+%package keyrouter
Summary: Wayland Compositor Library for keyrouter
Group: Development/Libraries
-%description tizen-keyrouter
+%description keyrouter
Wayland Compositor Library for tizen keyrouter
-%package tizen-keyrouter-devel
+%package keyrouter-devel
Summary: Keyrouter Development package for Wayland Compositor Library
Group: Development/Libraries
-%description tizen-keyrouter-devel
+%description keyrouter-devel
Keyrouter Development package for Wayland Compositor Library
%package tizen-input-devicemgr
--libdir %{_libdir} \
--bindir %{_bindir} \
builddir \
- -Dtizen=true \
-Dkeylayout_dir="%{TZ_SYS_RO_SHARE}/X11/xkb/tizen_key_layout.txt"
ninja -C builddir all
%manifest %{name}.manifest
%defattr(-,root,root,-)
%license LICENSE
-%{_libdir}/libds.so.*
%{_libdir}/libds-tizen.so.*
%files devel
%manifest %{name}.manifest
%defattr(-,root,root,-)
%license LICENSE
-%{_includedir}/libds/*
-%{_libdir}/pkgconfig/libds.pc
-%{_libdir}/libds.so
-%{_bindir}/wl-backend
-%{_bindir}/tinyds
-%{_bindir}/input-device-test
-%{_bindir}/libinput-backend
-
-%files tizen-devel
-%manifest %{name}.manifest
-%defattr(-,root,root,-)
-%license LICENSE
%{_includedir}/libds-tizen/*
%{_libdir}/pkgconfig/libds-tizen.pc
%{_libdir}/libds-tizen.so
%{_bindir}/tinyds-tdm
%{_bindir}/ds-simple-tbm
%{_bindir}/tinyds-tdm-libinput
-%{_bindir}/ds-simple-shm-shell
%{_bindir}/tinyds-tdm-dpms
-%{_bindir}/ds-simple-dpms
%{_bindir}/input-generator
-%files tizen-keyrouter
+%files keyrouter
%manifest %{name}.manifest
%defattr(-,root,root,-)
%license LICENSE
%{_libdir}/libds-tizen-keyrouter.so.*
-%files tizen-keyrouter-devel
+%files keyrouter-devel
%manifest %{name}.manifest
%defattr(-,root,root,-)
%license LICENSE
-simple_shm_shell_files = ['simple-shm-shell.c']
-simple_shm_shell_deps = [
- dependency('wayland-client', required: true),
-]
-
-executable('ds-simple-shm-shell',
- simple_shm_shell_files,
- dependencies: simple_shm_shell_deps,
- install_dir: libds_bindir,
- install: true,
-)
-
wayland_tbm_client = dependency('wayland-tbm-client', required: false)
libtbm = dependency('libtbm', required: false)
tizen_extension_client = dependency('tizen-extension-client', required: true)
executable('ds-simple-tbm',
simple_tbm_files,
dependencies: simple_tbm_deps,
- install_dir: libds_bindir,
+ install_dir: libds_tizen_bindir,
install: true,
)
+++ /dev/null
-/*
-Copyright (C) 2015 - 2016 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact:
- SooChan Lim <sc1.lim@samsung.com>
- Changyeon Lee <cyeon.lee@samsung.com>
- JunKyeong Kim <jk0430.kim@samsung.com>
- Boram Park <boram1288.park@samsung.com>
-
-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.
-*/
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <stdlib.h>
-
-#include <wayland-client.h>
-
-#define BUF_WIDTH 1920
-#define BUF_HEIGHT 1080
-
-#define RETURN_VAL_IF_FAIL(c,v) {\
- if(!((c))){\
- fprintf(stderr, "[%s(%d)] '%s' failed.", __func__, __LINE__, #c);\
- return (v);\
- }\
-}
-
-#define GOTO_IF_FAIL(c,l) {\
- if(!(c)) {\
- fprintf(stderr, "[%s(%d)] '%s' failed.", __func__, __LINE__, #c);\
- goto l;\
- }\
-}
-
-#define EXIT_IF_FAIL(c) {\
- if(!(c)) {\
- fprintf (stderr, "[%s(%d)] '%s' failed.\n",__func__,__LINE__,#c);\
- exit(0);\
- }\
-}
-
-struct wl_test_info {
- int width;
- int height;
- int stride;
- int format;
- int size;
-
- struct wl_display *display;
- struct wl_registry *registry;
-
- /* global objects */
- struct wl_compositor *compositor;
- struct wl_shm *shm;
- struct wl_shell *shell;
- struct wl_shm_pool *shm_pool;
-
- /* objects */
- struct wl_surface *surface;
- struct wl_shell_surface *shell_surface;
- struct wl_buffer *buffer;
-};
-
-static int
-_create_anonymous_file (off_t size)
-{
- static const char template[] =
- "/shooter-XXXXXX";
- const char *path;
- char *name = NULL;
- int fd = -1;
- int ret = -1;
-
- path = getenv("XDG_RUNTIME_DIR");
- if (!path) {
- errno = ENOENT;
- return -1;
- }
-
- name = malloc(strlen(path) + sizeof(template));
- GOTO_IF_FAIL(name != NULL, fail);
-
- strcpy(name, path);
- strcat(name, template);
-
- fd = mkstemp(name);
- if (fd >= 0)
- unlink(name);
-
- ret = ftruncate(fd, size);
- GOTO_IF_FAIL(ret >= 0, fail);
-
- free(name);
-
- return fd;
-fail:
- if (fd >= 0)
- close(fd);
-
- if (name)
- free(name);
-
- return -1;
-}
-
-static void
-_destroy_anonymous_file(int fd)
-{
- if (fd < 0) return;
-
- close(fd);
-}
-
-
-static struct wl_test_info *
-_create_wl_test_info (void)
-{
- struct wl_test_info *test_info = NULL;
-
- test_info = calloc(1, sizeof(struct wl_test_info));
- RETURN_VAL_IF_FAIL(test_info != NULL, NULL);
-
- return test_info;
-}
-
-static void
-_destroy_wl_test_info (struct wl_test_info *test_info)
-{
- if (!test_info) return;
-
- free(test_info);
-}
-
-static struct wl_shm_pool *
-_create_shm_pool(struct wl_shm *shm, int size)
-{
- struct wl_shm_pool *shm_pool = NULL;
- void *data = NULL;
- int fd = -1;
-
- fd = _create_anonymous_file(size);
- GOTO_IF_FAIL(fd >= 0, fail);
-
- data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- GOTO_IF_FAIL(data != NULL, fail);
-
- memset(data, 0xff, size);
- munmap(data, size);
-
- shm_pool = wl_shm_create_pool(shm, fd, size);
- GOTO_IF_FAIL(shm_pool != NULL, fail);
-
- _destroy_anonymous_file(fd);
-
- return shm_pool;
-
-fail:
- if (fd > 0)
- _destroy_anonymous_file(fd);
-
- return NULL;
-}
-
-void
-_destroy_shm_pool(struct wl_shm_pool *shm_pool)
-{
- if (!shm_pool) return;
-
- wl_shm_pool_destroy(shm_pool);
-}
-
-static void
-handle_global(void *data, struct wl_registry *registry, uint32_t name,
- const char *interface, uint32_t version)
-{
- struct wl_test_info *ti = (struct wl_test_info *)data;
-
- if (strcmp(interface, "wl_compositor") == 0) {
- ti->compositor = wl_registry_bind(registry, name,
- &wl_compositor_interface, 3);
- if (!ti->compositor)
- printf("%s(%d): Error. fail to bind %s.\n",
- __func__, __LINE__, interface);
- else
- printf("%s(%d): bind %s.\n", __func__, __LINE__, interface);
- } else if (strcmp(interface, "wl_shm") == 0) {
- ti->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
- if (!ti->shm)
- printf("%s(%d): Error. fail to bind %s.\n",
- __func__, __LINE__, interface);
- else
- printf("%s(%d): bind %s.\n", __func__, __LINE__, interface);
-
- ti->shm_pool = _create_shm_pool(ti->shm, ti->size);
- if (!ti->shm_pool)
- printf("%s(%d): Error. fail to create wl_shm_pool.\n",
- __func__, __LINE__);
- else
- printf("%s(%d): success to create wl_shm_pool.\n",
- __func__, __LINE__);
-
- } else if (strcmp(interface, "wl_shell") == 0) {
- ti->shell = wl_registry_bind(registry, name, &wl_shell_interface, 1);
- if (!ti->shell)
- printf("%s(%d): Error. fail to bind %s.\n",
- __func__, __LINE__, interface);
- else
- printf("%s(%d): bind %s.\n", __func__, __LINE__, interface);
- } else {
- printf("%s(%d): Not bind %s.\n", __func__, __LINE__, interface);
- }
-}
-
-static void
-handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
-{
-
-}
-
-static const struct wl_registry_listener registry_listener = {
- handle_global,
- handle_global_remove
-};
-
-int main (void)
-{
- struct wl_test_info *ti = NULL;
- int ret = 0;
-
- /* create test info */
- ti = _create_wl_test_info ();
- GOTO_IF_FAIL(ti != NULL, fail);
-
- /* init */
- ti->width = BUF_WIDTH;
- ti->height = BUF_HEIGHT;
- ti->stride = ti->width * 4;
- ti->format = WL_SHM_FORMAT_XRGB8888;
- ti->size = ti->stride * ti->height;
-
- /* connect display */
- ti->display = wl_display_connect(NULL);
- GOTO_IF_FAIL(ti->display != NULL, fail);
-
- /* get the registry */
- ti->registry = wl_display_get_registry(ti->display);
- GOTO_IF_FAIL(ti->registry != NULL, fail);
-
- /* get the global objects */
- wl_registry_add_listener(ti->registry, ®istry_listener, ti);
- wl_display_dispatch(ti->display);
- wl_display_roundtrip(ti->display);
-
- /* check the global objects */
- GOTO_IF_FAIL(ti->compositor != NULL, fail);
- GOTO_IF_FAIL(ti->shm != NULL, fail);
- GOTO_IF_FAIL(ti->shell != NULL, fail);
- GOTO_IF_FAIL(ti->shm_pool != NULL, fail);
-
- /* create objects */
- ti->surface = wl_compositor_create_surface(ti->compositor);
- GOTO_IF_FAIL(ti->surface != NULL, fail);
-
- ti->shell_surface = wl_shell_get_shell_surface(ti->shell, ti->surface);
- GOTO_IF_FAIL(ti->shell_surface != NULL, fail);
-
- wl_shell_surface_set_toplevel(ti->shell_surface);
-
- ti->buffer = wl_shm_pool_create_buffer(ti->shm_pool, 0,
- ti->width, ti->height, ti->stride, ti->format);
- GOTO_IF_FAIL(ti->buffer != NULL, fail);
-
- wl_surface_attach(ti->surface, ti->buffer, 0, 0);
- wl_surface_damage(ti->surface, 0, 0, ti->width, ti->height);
- wl_surface_commit(ti->surface);
-
- wl_display_roundtrip(ti->display);
-
- /* main loop */
- printf("%s(%d): loop start.\n", __func__, __LINE__);
- while (ret >= 0) {
- ret = wl_display_dispatch(ti->display);
- printf("%s(%d): loop running(ret=%d).\n", __func__, __LINE__, ret);
- }
- printf("%s(%d): loop end.\n", __func__, __LINE__);
-
-fail:
- /* destory objects */
- if (ti->shell_surface)
- wl_shell_surface_destroy(ti->shell_surface);
- if (ti->surface)
- wl_surface_destroy(ti->surface);
- if (ti->buffer)
- wl_buffer_destroy(ti->buffer);
-
- /* destroy global objects */
- if (ti->shell)
- wl_shell_destroy(ti->shell);
- if (ti->shm_pool)
- _destroy_shm_pool(ti->shm_pool);
- if (ti->shm)
- wl_shm_destroy(ti->shm);
- if (ti->compositor)
- wl_compositor_destroy(ti->compositor);
-
- /* destory registry and display */
- if (ti->registry)
- wl_registry_destroy(ti->registry);
- if (ti->display)
- wl_display_disconnect(ti->display);
-
- /* destroy test_info */
- if (ti)
- _destroy_wl_test_info(ti);
-
- return 0;
-}
+++ /dev/null
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <drm_fourcc.h>
-#include <libds/log.h>
-#include <libds/backend/wayland.h>
-#include <libds/input_device.h>
-#include <libds/pointer.h>
-#include <libds/keyboard.h>
-#include <libds/allocator/shm.h>
-#include <libds/swapchain.h>
-
-#include "pixman-helper.h"
-
-#define WIDTH 700
-#define HEIGHT 400
-
-struct pointer_device {
- struct ds_pointer *ds_pointer;
-
- struct wl_listener destroy;
- struct wl_listener motion_absolute;
- struct wl_listener button;
- struct wl_listener frame;
-};
-
-struct server;
-
-struct keyboard_device {
- struct server *server;
- struct ds_keyboard *ds_keyboard;
-
- struct wl_listener destroy;
- struct wl_listener modifiers;
- struct wl_listener key;
-};
-
-struct output
-{
- struct server *server;
-
- struct ds_output *ds_output;
- struct ds_allocator *allocator;
- struct ds_swapchain *swapchain;
-
- struct ds_buffer *front_buffer;
-
- struct wl_listener destroy;
-};
-
-struct server
-{
- struct wl_display *display;
-
- struct output output;
-
- struct ds_backend *backend;
-
- struct wl_listener backend_destroy;
- struct wl_listener new_input;
-};
-
-struct server _server;
-
-static struct ds_backend *create_backend_auto(struct wl_display *display);
-static void handle_backend_destroy(struct wl_listener *listener, void *data);
-static void handle_new_input(struct wl_listener *listener, void *data);
-static void output_init(struct output *output, struct server *sever);
-static void output_draw(struct output *output);
-
-int
-main(void)
-{
- struct server *server = &_server;
-
- ds_log_init(DS_DBG, NULL);
-
- server->display = wl_display_create();
- assert(server->display);
-
- server->backend = create_backend_auto(server->display);
- assert(server->backend);
-
- server->backend_destroy.notify = handle_backend_destroy;
- ds_backend_add_destroy_listener(server->backend, &server->backend_destroy);
-
- server->new_input.notify = handle_new_input;
- ds_backend_add_new_input_listener(server->backend, &server->new_input);
-
- output_init(&server->output, server);
-
- ds_backend_start(server->backend);
-
- output_draw(&server->output);
-
- wl_display_run(server->display);
-
- wl_display_destroy(server->display);
-
- return 0;
-}
-
-static struct ds_backend *
-create_backend_auto(struct wl_display *display)
-{
- struct ds_backend *backend = NULL;
- char name[512];
- int i;
-
- for (i = 0; i < 5; i++) {
- snprintf(name, sizeof name, "wayland-%d", i);
- backend = ds_wl_backend_create(display, name);
- if (backend)
- break;
- }
-
- return backend;
-}
-
-static void
-handle_backend_destroy(struct wl_listener *listener, void *data)
-{
- struct server *server;
-
- server = wl_container_of(listener, server, backend_destroy);
-
- wl_list_remove(&server->backend_destroy.link);
- wl_list_remove(&server->new_input.link);
-}
-
-static char *
-device_type_to_string(enum ds_input_device_type type)
-{
- switch (type) {
- case DS_INPUT_DEVICE_POINTER:
- return "pointer";
- break;
- case DS_INPUT_DEVICE_KEYBOARD:
- return "keyboard";
- break;
- case DS_INPUT_DEVICE_TOUCH:
- return "touch";
- break;
- default:
- return "Unknown";
- }
-}
-
-static void
-pointer_handle_device_destroy(struct wl_listener *listener, void *data)
-{
- struct pointer_device *pointer;
-
- pointer = wl_container_of(listener, pointer, destroy);
-
- wl_list_remove(&pointer->destroy.link);
- wl_list_remove(&pointer->motion_absolute.link);
- wl_list_remove(&pointer->button.link);
- wl_list_remove(&pointer->frame.link);
-
- free(pointer);
-}
-
-static void
-pointer_handle_motion_absolute(struct wl_listener *listener, void *data)
-{
- struct ds_event_pointer_motion_absolute *event = data;
-
- ds_inf("Pointer device(%p): motion absolute (%f, %f) time(%d ms)",
- event->device, event->x, event->y, event->time_msec);
-}
-
-static void
-pointer_handle_button(struct wl_listener *listener, void *data)
-{
- struct ds_event_pointer_button *event = data;
-
- ds_inf("Pointer Device(%p): button(%d) state(%d) time(%d ms)",
- event->device, event->button, event->state, event->time_msec);
-}
-
-static void
-pointer_handle_frame(struct wl_listener *listener, void *data)
-{
- ds_inf("Pointer device(%p): frame", data);
-}
-
-static void
-add_pointer(struct ds_input_device *dev)
-{
- struct pointer_device *pointer;
-
- pointer = calloc(1, sizeof *pointer);
- if (!pointer)
- return;
-
- pointer->ds_pointer = ds_input_device_get_pointer(dev);
-
- pointer->destroy.notify = pointer_handle_device_destroy;
- ds_input_device_add_destroy_listener(dev, &pointer->destroy);
-
- pointer->motion_absolute.notify = pointer_handle_motion_absolute;
- ds_pointer_add_motion_absolute_listener(pointer->ds_pointer,
- &pointer->motion_absolute);
-
- pointer->button.notify = pointer_handle_button;
- ds_pointer_add_button_listener(pointer->ds_pointer,
- &pointer->button);
-
- pointer->frame.notify = pointer_handle_frame;
- ds_pointer_add_frame_listener(pointer->ds_pointer,
- &pointer->frame);
-}
-
-static void
-keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
-{
- struct keyboard_device *keyboard;
-
- keyboard = wl_container_of(listener, keyboard, destroy);
-
- wl_list_remove(&keyboard->destroy.link);
- wl_list_remove(&keyboard->modifiers.link);
- wl_list_remove(&keyboard->key.link);
-
- free(keyboard);
-}
-
-static void
-keyboard_handle_modifiers(struct wl_listener *listener, void *data)
-{
- struct ds_keyboard *ds_keyboard = data;
- uint32_t modifiers;
-
- modifiers = ds_keyboard_get_modifiers(ds_keyboard);
- if (modifiers & DS_MODIFIER_CTRL)
- ds_inf("Keyboard(%p) modifier: Ctrl", ds_keyboard);
- if (modifiers & DS_MODIFIER_SHIFT)
- ds_inf("Keyboard(%p) modifier: Shift", ds_keyboard);
- if (modifiers & DS_MODIFIER_CAPS)
- ds_inf("Keyboard(%p) modifier: Caps", ds_keyboard);
- if (modifiers & DS_MODIFIER_ALT)
- ds_inf("Keyboard(%p) modifier: Alt", ds_keyboard);
- if (modifiers & DS_MODIFIER_MOD2)
- ds_inf("Keyboard(%p) modifier: Mod2", ds_keyboard);
- if (modifiers & DS_MODIFIER_MOD3)
- ds_inf("Keyboard(%p) modifier: Mod3", ds_keyboard);
- if (modifiers & DS_MODIFIER_LOGO)
- ds_inf("Keyboard(%p) modifier: Logo", ds_keyboard);
- if (modifiers & DS_MODIFIER_MOD5)
- ds_inf("Keyboard(%p) modifier: Mod5", ds_keyboard);
-}
-
-static void
-keyboard_handle_key(struct wl_listener *listener, void *data)
-{
- struct ds_event_keyboard_key *event = data;
- struct keyboard_device *keyboard;
- struct xkb_state *xkb_state;
- const xkb_keysym_t *syms;
- uint32_t modifiers;
- int nsyms = 0;
-
- keyboard = wl_container_of(listener, keyboard, key);
-
- ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), "
- "update_state(%d)", keyboard->ds_keyboard,
- event->keycode, event->state, event->time_msec,
- event->update_state);
-
- xkb_state = ds_keyboard_get_xkb_state(keyboard->ds_keyboard);
- if (!xkb_state)
- return;
-
- nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, &syms);
-
- modifiers = ds_keyboard_get_modifiers(keyboard->ds_keyboard);
- if ((modifiers & DS_MODIFIER_CTRL) &&
- (modifiers & DS_MODIFIER_ALT) &&
- event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
- for (int i = 0; i < nsyms; i++) {
- if (syms[i] == XKB_KEY_BackSpace)
- wl_display_terminate(keyboard->server->display);
- }
- }
-}
-
-static void
-add_keyboard(struct server *server, struct ds_input_device *dev)
-{
- struct keyboard_device *keyboard;
-
- keyboard = calloc(1, sizeof *keyboard);
- if (!keyboard)
- return;
-
- keyboard->server = server;
- keyboard->ds_keyboard = ds_input_device_get_keyboard(dev);
-
- ds_inf("Keyboard(%p) added", keyboard->ds_keyboard);
-
- keyboard->destroy.notify = keyboard_handle_device_destroy;
- ds_input_device_add_destroy_listener(dev, &keyboard->destroy);
-
- keyboard->modifiers.notify = keyboard_handle_modifiers;
- ds_keyboard_add_modifiers_listener(keyboard->ds_keyboard,
- &keyboard->modifiers);
-
- keyboard->key.notify = keyboard_handle_key;
- ds_keyboard_add_key_listener(keyboard->ds_keyboard,
- &keyboard->key);
-}
-
-static void
-handle_new_input(struct wl_listener *listener, void *data)
-{
- struct server *server;
- struct ds_input_device *dev = data;
- enum ds_input_device_type type;
-
- type = ds_input_device_get_type(dev);
-
- ds_inf("New device(%p) type(%s)", dev, device_type_to_string(type));
-
- if (type == DS_INPUT_DEVICE_POINTER)
- add_pointer(dev);
- else if (type == DS_INPUT_DEVICE_KEYBOARD) {
- server = wl_container_of(listener, server, new_input);
- add_keyboard(server, dev);
- }
-}
-
-static void
-output_handle_destroy(struct wl_listener *listener, void *data)
-{
- struct output *output;
-
- output = wl_container_of(listener, output, destroy);
-
- wl_list_remove(&output->destroy.link);
-
- ds_swapchain_destroy(output->swapchain);
- ds_allocator_destroy(output->allocator);
-}
-
-static void
-output_init(struct output *output, struct server *server)
-{
- output->server = server;
-
- output->ds_output = ds_wl_backend_create_output(server->backend);
- assert(output->ds_output);
-
- output->destroy.notify = output_handle_destroy;
- ds_output_add_destroy_listener(output->ds_output, &output->destroy);
-
- output->allocator = ds_shm_allocator_create();
- assert(output->allocator);
-
- output->swapchain = ds_swapchain_create(output->allocator,
- WIDTH, HEIGHT, DRM_FORMAT_XRGB8888);
- assert(output->swapchain);
-}
-
-static void
-output_draw(struct output *output)
-{
- struct ds_buffer *buffer;
- pixman_image_t *img;
-
- ds_dbg("Redraw output");
-
- buffer = ds_swapchain_acquire(output->swapchain, NULL);
- assert(buffer);
-
- img = pixman_image_from_buffer(buffer, DS_BUFFER_DATA_PTR_ACCESS_WRITE);
- assert(img);
-
- pixman_image_fill_color(img, 80, 80, 80);
-
- pixman_image_unref(img);
-
- ds_output_attach_buffer(output->ds_output, buffer);
- ds_output_commit(output->ds_output);
-
- if (output->front_buffer)
- ds_buffer_unlock(output->front_buffer);
-
- output->front_buffer = buffer;
-}
+++ /dev/null
-#include <assert.h>
- #include <stdlib.h>
-
-#include <wayland-server.h>
-#include <libds/log.h>
-#include <libds/backend/libinput.h>
-#include <libds/input_device.h>
-#include <libds/pointer.h>
-#include <libds/keyboard.h>
-#include <libds/touch.h>
-
-#define UNUSED __attribute__((unused))
-
-struct keyboard_device
-{
- struct server *server;
- struct ds_keyboard *ds_keyboard;
-
- struct wl_listener destroy;
- struct wl_listener key;
-};
-
-struct pointer_device
-{
- struct ds_pointer *ds_pointer;
-
- struct wl_listener destroy;
- struct wl_listener motion;
- struct wl_listener button;
-};
-
-struct touch_device
-{
- struct ds_touch *ds_touch;
-
- struct wl_listener destroy;
- struct wl_listener down;
- struct wl_listener up;
- struct wl_listener motion;
-};
-
-struct server
-{
- struct wl_display *display;
-
- struct ds_backend *backend;
-
- struct wl_listener backend_destroy;
- struct wl_listener new_input;
-};
-
-struct server _server;
-
-static struct ds_backend *create_backend_auto(struct wl_display *display);
-static void handle_backend_destroy(struct wl_listener *listener, void *data);
-static void handle_new_input(struct wl_listener *listener, void *data);
-
-int
-main(void)
-{
- struct server *server = &_server;
-
- ds_log_init(DS_DBG, NULL);
-
- server->display = wl_display_create();
- assert(server->display);
-
- server->backend = create_backend_auto(server->display);
- assert(server->backend);
-
- server->backend_destroy.notify = handle_backend_destroy;
- ds_backend_add_destroy_listener(server->backend, &server->backend_destroy);
-
- server->new_input.notify = handle_new_input;
- ds_backend_add_new_input_listener(server->backend, &server->new_input);
-
- ds_backend_start(server->backend);
-
- wl_display_run(server->display);
-
- wl_display_destroy(server->display);
-
- return 0;
-}
-
-static struct ds_backend *
-create_backend_auto(struct wl_display *display)
-{
- struct ds_backend *backend = NULL;
- backend = ds_libinput_backend_create(display);
- if (!backend)
- ds_err("Failed to create libinput backend");
-
- return backend;
-}
-
-static void
-handle_backend_destroy(struct wl_listener *listener, void *data)
-{
- struct server *server;
-
- server = wl_container_of(listener, server, backend_destroy);
-
- wl_list_remove(&server->backend_destroy.link);
- wl_list_remove(&server->new_input.link);
-}
-
-static char *
-device_type_to_string(enum ds_input_device_type type)
-{
- switch (type) {
- case DS_INPUT_DEVICE_POINTER:
- return "pointer";
- break;
- case DS_INPUT_DEVICE_KEYBOARD:
- return "keyboard";
- break;
- case DS_INPUT_DEVICE_TOUCH:
- return "touch";
- break;
- default:
- return "Unknown";
- }
-}
-
-static void
-keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
-{
- struct keyboard_device *keyboard;
-
- keyboard = wl_container_of(listener, keyboard, destroy);
-
- wl_list_remove(&keyboard->destroy.link);
- wl_list_remove(&keyboard->key.link);
-
- free(keyboard);
-}
-
-static void
-keyboard_handle_key(struct wl_listener *listener, void *data)
-{
- struct ds_event_keyboard_key *event = data;
- struct keyboard_device *keyboard;
-
- keyboard = wl_container_of(listener, keyboard, key);
-
- ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), "
- "update_state(%d)", keyboard->ds_keyboard,
- event->keycode, event->state, event->time_msec,
- event->update_state);
-}
-
-static void
-add_keyboard(struct server *server, struct ds_input_device *dev)
-{
- struct keyboard_device *keyboard;
-
- keyboard = calloc(1, sizeof *keyboard);
- if (!keyboard)
- return;
-
- keyboard->server = server;
- keyboard->ds_keyboard = ds_input_device_get_keyboard(dev);
-
- ds_inf("Keyboard(%p) added", keyboard->ds_keyboard);
-
- keyboard->destroy.notify = keyboard_handle_device_destroy;
- ds_input_device_add_destroy_listener(dev, &keyboard->destroy);
-
- keyboard->key.notify = keyboard_handle_key;
- ds_keyboard_add_key_listener(keyboard->ds_keyboard,
- &keyboard->key);
-}
-
-static void
-pointer_handle_device_destroy(struct wl_listener *listener, void *data)
-{
- struct pointer_device *pointer;
-
- pointer = wl_container_of(listener, pointer, destroy);
-
- wl_list_remove(&pointer->destroy.link);
- wl_list_remove(&pointer->button.link);
- wl_list_remove(&pointer->motion.link);
-
- free(pointer);
-}
-
-static void
-pointer_handle_motion(struct wl_listener *listener, void *data)
-{
- struct ds_event_pointer_motion *event = data;
- struct pointer_device *pointer;
-
- pointer = wl_container_of(listener, pointer, motion);
-
- ds_inf("Pointer Device(%p): motion delta_x,y(%f, %f) time(%d ms)",
- pointer->ds_pointer, event->delta_x, event->delta_y,
- event->time_msec);
-}
-
-static void
-pointer_handle_button(struct wl_listener *listener, void *data)
-{
- struct ds_event_pointer_button *event = data;
- struct pointer_device *pointer;
-
- pointer = wl_container_of(listener, pointer, button);
- ds_inf("Pointer Device(%p): button(%d) state(%d) time(%d ms)",
- pointer->ds_pointer, event->button, event->state,
- event->time_msec);
-}
-
-static void
-add_pointer(struct ds_input_device *dev)
-{
- struct pointer_device *pointer;
-
- pointer = calloc(1, sizeof *pointer);
- if (!pointer)
- return;
-
- pointer->ds_pointer = ds_input_device_get_pointer(dev);
-
- ds_inf("Pointer(%p) added", pointer->ds_pointer);
-
- pointer->destroy.notify = pointer_handle_device_destroy;
- ds_input_device_add_destroy_listener(dev, &pointer->destroy);
-
- pointer->motion.notify = pointer_handle_motion;
- ds_pointer_add_motion_listener(pointer->ds_pointer,
- &pointer->motion);
-
- pointer->button.notify = pointer_handle_button;
- ds_pointer_add_button_listener(pointer->ds_pointer,
- &pointer->button);
-}
-
-static void
-touch_handle_device_destroy(struct wl_listener *listener, void *data)
-{
- struct touch_device *touch;
-
- touch = wl_container_of(listener, touch, destroy);
-
- wl_list_remove(&touch->destroy.link);
- wl_list_remove(&touch->down.link);
- wl_list_remove(&touch->up.link);
- wl_list_remove(&touch->motion.link);
-
- free(touch);
-}
-
-static void
-touch_handle_down(struct wl_listener *listener, void *data)
-{
- struct ds_event_touch_down *event = data;
- struct touch_device *touch;
-
- touch = wl_container_of(listener, touch, down);
-
- ds_inf("Touch(%p) event down: id(%d) x(%f) y(%f) time_msec(%d)",
- touch->ds_touch, event->id, event->x, event->y, event->time_msec);
-}
-
-static void
-touch_handle_up(struct wl_listener *listener, void *data)
-{
- struct ds_event_touch_up *event = data;
- struct touch_device *touch;
-
- touch = wl_container_of(listener, touch, up);
-
- ds_inf("Touch(%p) event up: id(%d) time_msec(%d)",
- touch->ds_touch, event->id, event->time_msec);
-}
-
-static void
-touch_handle_motion(struct wl_listener *listener, void *data)
-{
- struct ds_event_touch_motion *event = data;
- struct touch_device *touch;
-
- touch = wl_container_of(listener, touch, motion);
-
- ds_inf("Touch(%p) event motion: id(%d) x(%f) y(%f) time_msec(%d)",
- touch->ds_touch, event->id, event->x, event->y, event->time_msec);
-}
-
-static void
-add_touch(struct server *server, struct ds_input_device *dev)
-{
- struct touch_device *touch;
-
- touch = calloc(1, sizeof *touch);
- if (!touch)
- return;
-
- touch->ds_touch = ds_input_device_get_touch(dev);
-
- ds_inf("Touch(%p) added", touch->ds_touch);
-
- touch->destroy.notify = touch_handle_device_destroy;
- ds_input_device_add_destroy_listener(dev, &touch->destroy);
-
- touch->down.notify = touch_handle_down;
- ds_touch_add_down_listener(touch->ds_touch,
- &touch->down);
-
- touch->up.notify = touch_handle_up;
- ds_touch_add_up_listener(touch->ds_touch,
- &touch->up);
-
- touch->motion.notify = touch_handle_motion;
- ds_touch_add_motion_listener(touch->ds_touch,
- &touch->motion);
-}
-
-static void
-handle_new_input(struct wl_listener *listener, void *data)
-{
- struct server *server;
- struct ds_input_device *dev = data;
- enum ds_input_device_type type;
-
- type = ds_input_device_get_type(dev);
-
- ds_inf("New device(%p) type(%s)", dev, device_type_to_string(type));
-
- if (type == DS_INPUT_DEVICE_POINTER)
- add_pointer(dev);
- else if (type == DS_INPUT_DEVICE_KEYBOARD) {
- server = wl_container_of(listener, server, new_input);
- add_keyboard(server, dev);
- }
- else if (type == DS_INPUT_DEVICE_TOUCH) {
- server = wl_container_of(listener, server, new_input);
- add_touch(server, dev);
- }
-}
common_deps = [
- dep_libds,
+ dep_libds_tizen,
dependency('wayland-server', required: true),
]
-executable('wl-backend',
- 'wl-backend.c',
- dependencies: common_deps,
- install_dir: libds_bindir,
- install : true)
+executable('tdm-backend',
+ 'tdm-backend.c',
+ dependencies: common_deps,
+ install_dir: libds_tizen_bindir,
+ install : true
+)
-executable('tinyds',
- [
- 'tinyds.c',
- 'pixman-helper.c'
+tinyds_tdm_files = [
+ 'tinyds-tdm.c',
+ 'pixman-helper.c',
+ 'pixman-tbm-helper.c',
+ 'tinyds-tdm-renderer.c',
+]
+
+executable('tinyds-tdm',
+ tinyds_tdm_files,
+ dependencies: [
+ common_deps,
+ dependency('pixman-1', required: true),
+ dependency('threads', required: true),
],
+ install_dir: libds_tizen_bindir,
+ install : true
+)
+
+tinyds_tdm_libinput_files = [
+ 'tinyds-tdm-libinput.c',
+ 'pixman-helper.c',
+ 'pixman-tbm-helper.c',
+ 'tinyds-tdm-renderer.c',
+]
+
+executable('tinyds-tdm-libinput',
+ tinyds_tdm_libinput_files,
dependencies: [
common_deps,
dependency('pixman-1', required: true),
- dependency('libdrm', required: true),
+ dependency('threads', required: true),
],
- install_dir: libds_bindir,
+ install_dir: libds_tizen_bindir,
install : true
)
-executable('input-device-test',
- [
- 'input-device-test.c',
- 'pixman-helper.c',
+executable('tinyds-tdm-dpms',
+ 'tinyds-tdm-dpms.c',
+ 'pixman-helper.c',
+ 'pixman-tbm-helper.c',
+ 'tinyds-tdm-renderer.c',
+ dependencies: [
+ common_deps,
+ dependency('pixman-1', required: true),
+ dependency('threads', required: true),
],
- dependencies: common_deps,
install_dir: libds_bindir,
- install : true)
-
-if get_option('tizen')
- common_deps += dep_libds_tizen
-
- executable('tdm-backend',
- 'tdm-backend.c',
- dependencies: common_deps,
- install_dir: libds_bindir,
- install : true
- )
-
- tinyds_tdm_files = [
- 'tinyds-tdm.c',
- 'pixman-helper.c',
- 'pixman-tbm-helper.c',
- 'tinyds-tdm-renderer.c',
- ]
- executable('tinyds-tdm',
- tinyds_tdm_files,
- dependencies: [
- common_deps,
- dependency('pixman-1', required: true),
- dependency('threads', required: true),
- ],
- install_dir: libds_bindir,
- install : true
- )
-
- executable('libinput-backend',
- 'libinput-backend.c',
- dependencies: common_deps,
- install_dir: libds_bindir,
- install : true
- )
-
- tinyds_tdm_libinput_files = [
- 'tinyds-tdm-libinput.c',
- 'pixman-helper.c',
- 'pixman-tbm-helper.c',
- 'tinyds-tdm-renderer.c',
- ]
- executable('tinyds-tdm-libinput',
- tinyds_tdm_libinput_files,
- dependencies: [
- common_deps,
- dep_libds_tizen_input_devicemgr,
- dependency('pixman-1', required: true),
- dependency('threads', required: true),
- ],
- install_dir: libds_bindir,
- install : true
- )
- executable('tinyds-tdm-dpms',
- 'tinyds-tdm-dpms.c',
- 'pixman-helper.c',
- 'pixman-tbm-helper.c',
- 'tinyds-tdm-renderer.c',
- dependencies: [
- common_deps,
- dependency('pixman-1', required: true),
- dependency('threads', required: true),
- ],
- install_dir: libds_bindir,
- install : true
- )
-endif
+ install : true
+)
+++ /dev/null
-#include "pixman-helper.h"
-
-#include <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <time.h>
-
-#include <drm_fourcc.h>
-#include <pixman.h>
-#include <wayland-server.h>
-#include <libds/log.h>
-#include <libds/backend.h>
-#include <libds/allocator/shm.h>
-#include <libds/backend/wayland.h>
-#include <libds/swapchain.h>
-#include <libds/compositor.h>
-#include <libds/xdg_shell.h>
-#include <libds/input_device.h>
-#include <libds/keyboard.h>
-#include <libds/touch.h>
-#include <libds/pointer.h>
-#include <libds/seat.h>
-
-#define TINYDS_UNUSED __attribute__((unused))
-
-#define OUTPUT_WIDTH 1280
-#define OUTPUT_HEIGHT 720
-
-struct tinyds_server;
-
-struct tinyds_pointer
-{
- struct ds_input_device *dev;
- struct tinyds_server *server;
-
- struct tinyds_view *focused_view;
-
- struct wl_listener destroy;
- struct wl_listener motion;
- struct wl_listener motion_absolute;
- struct wl_listener button;
- struct wl_listener frame;
-};
-
-struct tinyds_keyboard
-{
- struct ds_input_device *dev;
- struct tinyds_server *server;
-
- struct wl_listener destroy;
- struct wl_listener key;
-};
-
-struct tinyds_touch
-{
- struct ds_input_device *dev;
- struct tinyds_server *server;
-
- struct wl_listener destroy;
- struct wl_listener down;
- struct wl_listener up;
- struct wl_listener motion;
-};
-
-struct tinyds_output
-{
- struct tinyds_server *server;
- struct ds_output *ds_output;
- struct ds_allocator *allocator;
- struct ds_swapchain *swapchain;
-
- struct wl_listener output_destroy;
- struct wl_listener output_frame;
-
- int width, height;
-
- bool drawable;
- bool damaged;
-};
-
-struct tinyds_server
-{
- struct wl_display *display;
-
- struct ds_backend *backend;
- struct ds_compositor *compositor;
- struct ds_xdg_shell *xdg_shell;
- struct ds_seat *seat;
-
- struct tinyds_output output;
-
- struct wl_list views;
-
- struct wl_listener new_output;
- struct wl_listener new_input;
- struct wl_listener new_xdg_surface;
-};
-
-struct tinyds_view
-{
- struct tinyds_server *server;
-
- struct ds_xdg_surface *xdg_surface;
-
- struct wl_listener xdg_surface_map;
- struct wl_listener xdg_surface_unmap;
- struct wl_listener xdg_surface_destroy;
- struct wl_listener surface_commit;
- struct wl_list link; // tinyds_server::views
-
- int x, y;
- bool mapped;
-};
-
-static bool server_init(struct tinyds_server *server,
- struct wl_display *display);
-static void server_fini(struct tinyds_server *server);
-static void server_add_view(struct tinyds_server *server,
- struct ds_xdg_surface *xdg_surface);
-static struct tinyds_view *server_view_at(struct tinyds_server *server,
- double lx, double ly, double *sx, double *sy);
-static bool output_init(struct tinyds_output *output,
- struct tinyds_server *server, struct ds_output *ds_output,
- int width, int height);
-static void output_fini(struct tinyds_output *output);
-static void output_damage(struct tinyds_output *output);
-static void output_redraw(struct tinyds_output *output);
-static void view_destroy(struct tinyds_view *view);
-static void view_composite(struct tinyds_view *view,
- pixman_image_t *dst_image);
-
-int
-main(void)
-{
- struct tinyds_server server;
- struct wl_display *display;
- const char *socket;
-
- ds_log_init(DS_DBG, NULL);
-
- display = wl_display_create();
- assert(display);
-
- assert(server_init(&server, display) == true);
-
- socket = wl_display_add_socket_auto(display);
- assert(socket);
-
- ds_backend_start(server.backend);
-
- output_damage(&server.output);
- output_redraw(&server.output);
-
- setenv("WAYLAND_DISPLAY", socket, true);
-
- ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
-
- wl_display_run(server.display);
-
- server_fini(&server);
- wl_display_destroy(display);
-
- return 0;
-}
-
-static struct ds_backend *
-create_wl_backend(struct wl_display *display)
-{
- if (!getenv("WAYLAND_DISPLAY") && !getenv("WAYLAND_SOCKET"))
- return NULL;
-
- return ds_wl_backend_create(display, NULL);
-}
-
-static void
-server_handle_new_output(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
- struct ds_output *ds_output = data;
-
- server = wl_container_of(listener, server, new_output);
-
- assert(output_init(&server->output, server, ds_output,
- OUTPUT_WIDTH, OUTPUT_HEIGHT) == true);
-}
-
-static void
-keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
-{
- struct tinyds_keyboard *kbd;
-
- kbd = wl_container_of(listener, kbd, destroy);
-
- ds_inf("Keyboard(%p) destroyed", kbd);
-
- wl_list_remove(&kbd->destroy.link);
- wl_list_remove(&kbd->key.link);
-
- free(kbd);
-}
-
-static bool
-server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym)
-{
- switch (sym) {
- case XKB_KEY_BackSpace:
- wl_display_terminate(server->display);
- break;
- default:
- return false;
- }
-
- return true;
-}
-
-static void
-keyboard_handle_key(struct wl_listener *listener, void *data)
-{
- struct tinyds_keyboard *kbd;
- struct ds_event_keyboard_key *event = data;
- struct ds_keyboard *ds_keyboard;
- struct xkb_state *xkb_state;
- const xkb_keysym_t *syms;
- uint32_t modifiers;
- int nsyms;
-
- kbd = wl_container_of(listener, kbd, key);
-
- ds_keyboard = ds_input_device_get_keyboard(kbd->dev);
-
- modifiers = ds_keyboard_get_modifiers(ds_keyboard);
- if ((modifiers & DS_MODIFIER_CTRL) &&
- (modifiers & DS_MODIFIER_ALT) &&
- (modifiers & DS_MODIFIER_SHIFT) &&
- event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
- xkb_state = ds_keyboard_get_xkb_state(ds_keyboard);
- if (xkb_state) {
- nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8,
- &syms);
- for (int i = 0; i < nsyms; i++) {
- server_handle_keybinding(kbd->server, syms[i]);
- }
- }
- }
-}
-
-static void
-server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev)
-{
- struct tinyds_keyboard *kbd;
-
- kbd = calloc(1, sizeof *kbd);
- assert(kbd);
-
- kbd->dev = dev;
- kbd->server = server;
-
- kbd->destroy.notify = keyboard_handle_device_destroy;
- ds_input_device_add_destroy_listener(dev, &kbd->destroy);
-
- kbd->key.notify = keyboard_handle_key;
- ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key);
-
- ds_inf("Keyboard(%p) added", kbd);
-}
-
-static void
-touch_handle_device_destroy(struct wl_listener *listener, void *data)
-{
- struct tinyds_touch *touch;
-
- touch = wl_container_of(listener, touch, destroy);
-
- ds_inf("Touch(%p) destroyed", touch);
-
- wl_list_remove(&touch->destroy.link);
- wl_list_remove(&touch->down.link);
- wl_list_remove(&touch->up.link);
- wl_list_remove(&touch->motion.link);
-
- free(touch);
-}
-
-static void
-touch_handle_down(struct wl_listener *listener, void *data)
-{
- ds_inf("Touch device(%p): down", data);
-}
-
-static void
-touch_handle_up(struct wl_listener *listener, void *data)
-{
- ds_inf("Touch device(%p): up", data);
-}
-
-static void
-touch_handle_motion(struct wl_listener *listener, void *data)
-{
- ds_inf("Touch device(%p): motion", data);
-}
-
-static void
-server_add_touch(struct tinyds_server *server, struct ds_input_device *dev)
-{
- struct tinyds_touch *touch;
-
- touch = calloc(1, sizeof *touch);
- assert(touch);
-
- touch->dev = dev;
- touch->server = server;
-
- touch->destroy.notify = touch_handle_device_destroy;
- ds_input_device_add_destroy_listener(dev, &touch->destroy);
-
- touch->down.notify = touch_handle_down;
- ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down);
-
- touch->up.notify = touch_handle_up;
- ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up);
-
- touch->motion.notify = touch_handle_motion;
- ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion);
-
- ds_inf("Touch(%p) added", touch);
-}
-
-static void
-pointer_handle_device_destroy(struct wl_listener *listener, void *data)
-{
- struct tinyds_pointer *pointer;
-
- pointer = wl_container_of(listener, pointer, destroy);
-
- ds_inf("Pointer(%p) destroyed", pointer);
-
- wl_list_remove(&pointer->destroy.link);
- wl_list_remove(&pointer->motion.link);
- wl_list_remove(&pointer->motion_absolute.link);
- wl_list_remove(&pointer->button.link);
- wl_list_remove(&pointer->frame.link);
-
- free(pointer);
-}
-
-static void
-pointer_handle_motion(struct wl_listener *listener, void *data)
-{
- struct tinyds_pointer *pointer;
-
- pointer = wl_container_of(listener, pointer, motion);
-
- ds_inf("Pointer(%p) motion", pointer);
-}
-
-static void
-pointer_handle_motion_absolute(struct wl_listener *listener, void *data)
-{
- struct tinyds_pointer *pointer;
- struct ds_event_pointer_motion_absolute *event = data;
- struct tinyds_view *view;
- double ox, oy, sx, sy;
-
- pointer = wl_container_of(listener, pointer, motion_absolute);
-
- ds_inf("Pointer(%p) motion absolute: (x %f y %f) time(%d)",
- pointer, event->x, event->y, event->time_msec);
-
- ox = event->x * OUTPUT_WIDTH;
- oy = event->y * OUTPUT_HEIGHT;
- view = server_view_at(pointer->server, ox, oy, &sx, &sy);
-
- if (pointer->focused_view != view) {
- if (pointer->focused_view) {
- ds_inf("Clear pointer focus from view(%p)", pointer->focused_view);
- ds_seat_pointer_notify_clear_focus(pointer->server->seat);
- pointer->focused_view = NULL;
- }
-
- if (view) {
- ds_inf("Set pointer focus to view(%p)", view);
- ds_seat_pointer_notify_enter(pointer->server->seat,
- ds_xdg_surface_get_surface(view->xdg_surface), sx, sy);
- pointer->focused_view = view;
- }
- }
-
- if (view) {
- ds_seat_pointer_notify_motion(pointer->server->seat,
- event->time_msec, sx, sy);
- }
-}
-
-static void
-pointer_handle_button(struct wl_listener *listener, void *data)
-{
- struct tinyds_pointer *pointer;
- struct ds_event_pointer_button *event = data;
-
- pointer = wl_container_of(listener, pointer, button);
-
- ds_inf("Pointer(%p) button(%d): state(%s) time(%d)",
- pointer, event->button,
- (event->state == DS_BUTTON_PRESSED) ? "Pressed" : "Released",
- event->time_msec);
-}
-
-static void
-pointer_handle_frame(struct wl_listener *listener, void *data)
-{
- struct tinyds_pointer *pointer;
-
- pointer = wl_container_of(listener, pointer, frame);
-
- ds_inf("Pointer(%p) frame", pointer);
- ds_seat_pointer_notify_frame(pointer->server->seat);
-}
-
-static void
-server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev)
-{
- struct tinyds_pointer *pointer;
-
- pointer = calloc(1, sizeof *pointer);
- assert(pointer);
-
- pointer->dev = dev;
- pointer->server = server;
-
- pointer->destroy.notify = pointer_handle_device_destroy;
- ds_input_device_add_destroy_listener(dev, &pointer->destroy);
-
- pointer->motion.notify = pointer_handle_motion;
- ds_pointer_add_motion_listener(ds_input_device_get_pointer(dev),
- &pointer->motion);
-
- pointer->motion_absolute.notify = pointer_handle_motion_absolute;
- ds_pointer_add_motion_absolute_listener(ds_input_device_get_pointer(dev),
- &pointer->motion_absolute);
-
- pointer->button.notify = pointer_handle_button;
- ds_pointer_add_button_listener(ds_input_device_get_pointer(dev),
- &pointer->button);
-
- pointer->frame.notify = pointer_handle_frame;
- ds_pointer_add_frame_listener(ds_input_device_get_pointer(dev),
- &pointer->frame);
-
- ds_inf("Pointer(%p) added", pointer);
-}
-
-static void
-server_handle_new_input(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
- struct ds_input_device *dev = data;
- enum ds_input_device_type dev_type;
-
- server = wl_container_of(listener, server, new_input);
-
- dev_type = ds_input_device_get_type(dev);
- switch (dev_type) {
- case DS_INPUT_DEVICE_KEYBOARD:
- server_add_keyboard(server, dev);
- break;
- case DS_INPUT_DEVICE_TOUCH:
- server_add_touch(server, dev);
- break;
- case DS_INPUT_DEVICE_POINTER:
- server_add_pointer(server, dev);
- ds_seat_set_capabilities(server->seat, WL_SEAT_CAPABILITY_POINTER);
- break;
- default:
- ds_err("Unknown type(%d) of ds_input_device", dev_type);
- break;
- }
-}
-
-static void
-view_handle_xdg_surface_map(struct wl_listener *listener,
- void *data TINYDS_UNUSED)
-{
- struct tinyds_view *view;
-
- view = wl_container_of(listener, view, xdg_surface_map);
- view->mapped = true;
-}
-
-static void
-view_handle_xdg_surface_unmap(struct wl_listener *listener,
- void *data TINYDS_UNUSED)
-{
- struct tinyds_view *view;
-
- view = wl_container_of(listener, view, xdg_surface_unmap);
- view->mapped = false;
-}
-
-static void
-view_handle_xdg_surface_destroy(struct wl_listener *listener,
- void *data TINYDS_UNUSED)
-{
- struct tinyds_view *view;
-
- view = wl_container_of(listener, view, xdg_surface_destroy);
-
- output_damage(&view->server->output);
- output_redraw(&view->server->output);
-
- view_destroy(view);
-}
-
-static void
-view_handle_surface_commit(struct wl_listener *listener,
- void *data TINYDS_UNUSED)
-{
- struct tinyds_view *view;
-
- view = wl_container_of(listener, view, surface_commit);
-
- output_damage(&view->server->output);
- output_redraw(&view->server->output);
-}
-
-static void
-server_new_xdg_surface(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
-
- server = wl_container_of(listener, server, new_xdg_surface);
-
- server_add_view(server, (struct ds_xdg_surface *)data);
-}
-
-static bool
-server_init(struct tinyds_server *server, struct wl_display *display)
-{
- server->display = display;
-
- wl_list_init(&server->views);
-
- if (wl_display_init_shm(display) != 0)
- return false;
-
- server->backend = create_wl_backend(display);
- if (!server->backend)
- return false;
-
- ds_wl_backend_create_output(server->backend);
-
- server->new_input.notify = server_handle_new_input;
- ds_backend_add_new_input_listener(server->backend, &server->new_input);
-
- server->new_output.notify = server_handle_new_output;
- ds_backend_add_new_output_listener(server->backend, &server->new_output);
-
- server->compositor = ds_compositor_create(display);
- if (!server->compositor)
- goto err;
-
- server->xdg_shell = ds_xdg_shell_create(display);
- if (!server->xdg_shell)
- goto err;
-
- server->new_xdg_surface.notify = server_new_xdg_surface;
- ds_xdg_shell_add_new_surface_listener(server->xdg_shell,
- &server->new_xdg_surface);
-
- server->seat = ds_seat_create(display, "seat0" /* arbitrary name */);
- if (!server->seat)
- goto err;
-
- return true;
-
-err:
- ds_backend_destroy(server->backend);
-
- return false;
-}
-
-static void
-server_fini(struct tinyds_server *server)
-{
- struct tinyds_view *view, *tmp;
-
- wl_list_for_each_safe(view, tmp, &server->views, link)
- view_destroy(view);
-
- output_fini(&server->output);
-
- wl_list_remove(&server->new_xdg_surface.link);
-}
-
-static void
-output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
-{
- struct tinyds_output *output =
- wl_container_of(listener, output, output_destroy);
-
- wl_list_remove(&output->output_destroy.link);
- wl_list_remove(&output->output_frame.link);
- output->ds_output = NULL;
-
- wl_display_terminate(output->server->display);
-}
-
-static void
-output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED)
-{
- struct tinyds_output *output =
- wl_container_of(listener, output, output_frame);
-
- output->drawable = true;
- output_redraw(output);
-}
-
-static bool
-output_init(struct tinyds_output *output, struct tinyds_server *server,
- struct ds_output *ds_output, int width, int height)
-{
- output->server = server;
- output->ds_output = ds_output;
- output->width = width;
- output->height = height;
- output->drawable = true;
-
- ds_output_set_custom_mode(ds_output, OUTPUT_WIDTH, OUTPUT_HEIGHT, 0);
-
- output->allocator = ds_shm_allocator_create();
- if (!output->allocator)
- return false;
-
- output->swapchain = ds_swapchain_create(output->allocator,
- width, height, DRM_FORMAT_XRGB8888);
- if (!output->swapchain)
- goto err_swapchain;
-
- output->output_destroy.notify = output_handle_destroy;
- ds_output_add_destroy_listener(output->ds_output, &output->output_destroy);
-
- output->output_frame.notify = output_handle_frame;
- ds_output_add_frame_listener(output->ds_output, &output->output_frame);
-
- return true;
-
-err_swapchain:
- ds_allocator_destroy(output->allocator);
-
- return false;
-}
-
-static void
-output_fini(struct tinyds_output *output)
-{
- ds_output_destroy(output->ds_output);
- ds_swapchain_destroy(output->swapchain);
- ds_allocator_destroy(output->allocator);
-}
-
-static void
-output_damage(struct tinyds_output *output)
-{
- output->damaged = true;
-}
-
-static void
-output_redraw(struct tinyds_output *output)
-{
- struct ds_buffer *output_buffer;
- pixman_image_t *output_image;
- struct tinyds_view *view;
-
- if (!output->drawable || !output->damaged)
- return;
-
- output_buffer = ds_swapchain_acquire(output->swapchain, NULL);
- if (!output_buffer)
- return;
-
- output_image = pixman_image_from_buffer(output_buffer,
- DS_BUFFER_DATA_PTR_ACCESS_WRITE);
- if (!output_image)
- goto out;
-
- pixman_image_fill_color(output_image, 80, 80, 80);
-
- wl_list_for_each(view, &output->server->views, link) {
- if (!view->mapped)
- continue;
- view_composite(view, output_image);
- }
- pixman_image_unref(output_image);
-
- ds_output_attach_buffer(output->ds_output, output_buffer);
- ds_output_commit(output->ds_output);
-
- output->drawable = false;
- output->damaged = false;
-
-out:
- ds_buffer_unlock(output_buffer);
-}
-
-static void
-server_add_view(struct tinyds_server *server, struct ds_xdg_surface *xdg_surface)
-{
- struct tinyds_view *view;
-
- view = calloc(1, sizeof *view);
- view->server = server;
- view->xdg_surface = xdg_surface;
-
- view->xdg_surface_map.notify = view_handle_xdg_surface_map;
- ds_xdg_surface_add_map_listener(xdg_surface,
- &view->xdg_surface_map);
-
- view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap;
- ds_xdg_surface_add_unmap_listener(xdg_surface,
- &view->xdg_surface_unmap);
-
- view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy;
- ds_xdg_surface_add_destroy_listener(xdg_surface,
- &view->xdg_surface_destroy);
-
- view->surface_commit.notify = view_handle_surface_commit;
- ds_surface_add_commit_listener(
- ds_xdg_surface_get_surface(xdg_surface),
- &view->surface_commit);
-
- wl_list_insert(server->views.prev, &view->link);
-
- ds_inf("View(%p) added", view);
-}
-
-static struct tinyds_view *
-server_view_at(struct tinyds_server *server, double lx, double ly,
- double *sx, double *sy)
-{
- struct tinyds_view *view;
- struct ds_surface *surface;
- struct ds_buffer *buffer;
- int x, y, w = 0, h = 0;
-
- wl_list_for_each(view, &server->views, link) {
- surface = ds_xdg_surface_get_surface(view->xdg_surface);
- buffer = ds_surface_get_buffer(surface);
- ds_buffer_get_size(buffer, &w, &h);
-
- x = view->x;
- y = view->y;
-
- if (lx >= x && lx <= w && ly >= y && ly <= h) {
- *sx = lx - x;
- *sy = ly - y;
-
- return view;
- }
- }
-
- return NULL;
-}
-
-static void
-view_destroy(struct tinyds_view *view)
-{
- ds_inf("View(%p) destroyed", view);
-
- wl_list_remove(&view->xdg_surface_destroy.link);
- wl_list_remove(&view->xdg_surface_map.link);
- wl_list_remove(&view->xdg_surface_unmap.link);
- wl_list_remove(&view->surface_commit.link);
- wl_list_remove(&view->link);
- free(view);
-}
-
-static void
-view_send_frame_done(struct tinyds_view *view)
-{
- struct timespec now;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
- ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface),
- &now);
-}
-
-static void
-view_composite(struct tinyds_view *view, pixman_image_t *dst_image)
-{
- struct ds_buffer *buffer;
- pixman_image_t *src_image;
-
- buffer = ds_surface_get_buffer(
- ds_xdg_surface_get_surface(view->xdg_surface));
- if (!buffer)
- return;
-
- src_image = pixman_image_from_buffer(buffer,
- DS_BUFFER_DATA_PTR_ACCESS_READ);
- pixman_image_composite32(PIXMAN_OP_OVER,
- src_image,
- NULL,
- dst_image,
- 0, 0, 0, 0, 0, 0,
- pixman_image_get_width(src_image),
- pixman_image_get_height(src_image));
- pixman_image_unref(src_image);
-
- view_send_frame_done(view);
-}
+++ /dev/null
-#include <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-
-#include <wayland-server.h>
-#include <libds/log.h>
-#include <libds/backend.h>
-#include <libds/allocator/shm.h>
-#include <libds/backend/wayland.h>
-#include <libds/swapchain.h>
-#include <libds/compositor.h>
-
-#define WIDTH 700
-#define HEIGHT 400
-
-struct server
-{
- struct ds_backend *backend;
- struct ds_output *output;
- struct ds_allocator *allocator;
- struct ds_swapchain *swapchain;
- struct ds_buffer *front_buffer;
-
- struct wl_display *display;
-
- struct {
- struct wl_listener output_destroy;
- struct wl_listener output_frame;
- } listener;
-
- int width, height;
-};
-
-struct server _server;
-
-static void init_server(struct server *server, struct wl_display *display);
-static void fini_server(struct server *server);
-static void output_handle_destroy(struct wl_listener *listener, void *data);
-static void output_handle_frame(struct wl_listener *listener, void *data);
-static void draw_output(struct server *server);
-
-int
-main(void)
-{
- struct server *server = &_server;
- struct wl_display *display;
-
- ds_log_init(DS_DBG, NULL);
-
- display = wl_display_create();
- assert(display);
-
- server->width = WIDTH;
- server->height = HEIGHT;
-
- init_server(server, display);
-
- server->listener.output_destroy.notify = output_handle_destroy;
- ds_output_add_destroy_listener(server->output,
- &server->listener.output_destroy);
-
- server->listener.output_frame.notify = output_handle_frame;
- ds_output_add_frame_listener(server->output,
- &server->listener.output_frame);
-
- ds_backend_start(server->backend);
-
- draw_output(server);
-
- wl_display_run(server->display);
-
- fini_server(server);
- wl_display_destroy(display);
- return 0;
-}
-
-static struct ds_backend *
-create_backend_auto(struct wl_display *display)
-{
- struct ds_backend *backend = NULL;
- char name[512];
- int i;
-
- for (i = 0; i < 5; i++) {
- snprintf(name, sizeof name, "wayland-%d", i);
- backend = ds_wl_backend_create(display, name);
- if (backend)
- break;
- }
-
- return backend;
-}
-
-static void
-init_server(struct server *server, struct wl_display *display)
-{
- server->display = display;
-
- server->backend = create_backend_auto(display);
- assert(server->backend);
-
- server->allocator = ds_shm_allocator_create();
- assert(server->allocator);
-
- server->swapchain = ds_swapchain_create(server->allocator,
- server->width, server->height, WL_SHM_FORMAT_XRGB8888);
- assert(server->swapchain);
-
- server->output =
- ds_wl_backend_create_output(server->backend);
- assert(server->output);
-}
-
-static void
-fini_server(struct server *server)
-{
- ds_buffer_unlock(server->front_buffer);
- ds_swapchain_destroy(server->swapchain);
- ds_allocator_destroy(server->allocator);
-}
-
-static void
-paint_pixels(void *image, int padding, int width, int height, uint32_t time)
-{
- const int halfh = padding + (height - padding * 2) / 2;
- const int halfw = padding + (width - padding * 2) / 2;
- int ir, or;
- uint32_t *pixel = image;
- int y;
-
- /* squared radii thresholds */
- or = (halfw < halfh ? halfw : halfh) - 8;
- ir = or - 32;
- or *= or;
- ir *= ir;
-
- pixel += padding * width;
- for (y = padding; y < height - padding; y++) {
- int x;
- int y2 = (y - halfh) * (y - halfh);
-
- pixel += padding;
- for (x = padding; x < width - padding; x++) {
- uint32_t v;
-
- /* squared distance from center */
- int r2 = (x - halfw) * (x - halfw) + y2;
-
- if (r2 < ir)
- v = (r2 / 32 + time / 64) * 0x0080401;
- else if (r2 < or)
- v = (y + time / 32) * 0x0080401;
- else
- v = (x + time / 16) * 0x0080401;
- v &= 0x00ffffff;
-
- /* cross if compositor uses X from XRGB as alpha */
- if (abs(x - y) > 6 && abs(x + y - height) > 6)
- v |= 0xff000000;
-
- *pixel++ = v;
- }
-
- pixel += padding;
- }
-}
-
-static inline int64_t
-timespec_to_msec(const struct timespec *a)
-{
- return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
-}
-
-static void
-output_handle_destroy(struct wl_listener *listener,
- void *data __attribute__((unused)))
-{
- struct server *server =
- wl_container_of(listener, server, listener.output_destroy);
- wl_display_terminate(server->display);
-}
-
-static void
-output_handle_frame(struct wl_listener *listener,
- void *data __attribute__((unused)))
-{
- struct server *server =
- wl_container_of(listener, server, listener.output_frame);
- draw_output(server);
-}
-
-static void
-draw_output(struct server *server)
-{
- struct ds_buffer *buffer;
- void *data;
- uint32_t format;
- size_t stride;
- struct timespec now;
- uint32_t frame_time_msec;
-
- ds_dbg("Redraw output");
-
- clock_gettime(CLOCK_MONOTONIC, &now);
- frame_time_msec = timespec_to_msec(&now);
-
- buffer = ds_swapchain_acquire(server->swapchain, NULL);
- assert(buffer);
-
- assert(ds_buffer_begin_data_ptr_access(buffer,
- 0, &data, &format, &stride) == true);
-
- paint_pixels(data, 20, server->width, server->height, frame_time_msec);
-
- ds_buffer_end_data_ptr_access(buffer);
-
- ds_output_attach_buffer(server->output, buffer);
- ds_output_commit(server->output);
-
- if (server->front_buffer)
- ds_buffer_unlock(server->front_buffer);
-
- server->front_buffer = buffer;
-}
#include <tbm_bufmgr.h>
#include <tbm_surface.h>
-#include "libds/interfaces/allocator.h"
-#include "libds/interfaces/buffer.h"
-#include "libds/log.h"
+#include <libds/interfaces/allocator.h>
+#include <libds/interfaces/buffer.h>
+#include <libds/log.h>
struct ds_tbm_allocator
{
#include <assert.h>
#include <stdlib.h>
-#include "libds/log.h"
+#include <libds/log.h>
#include "tdm.h"
#include <tbm_surface.h>
-#include "libds/log.h"
+#include <libds/log.h>
#include "libds-tizen/allocator/tbm.h"
#include "tdm.h"
#include <tdm.h>
-#include "libds/interfaces/backend.h"
-#include "libds/interfaces/output.h"
+#include <libds/interfaces/backend.h>
+#include <libds/interfaces/output.h>
enum ds_tdm_output_status {
DS_TDM_OUTPUT_DISCONNECTED,
#include <stdlib.h>
#include <sys/eventfd.h>
-#include "libds/log.h"
+#include <libds/log.h>
#include "libds/interfaces/buffer.h"
#include "tdm.h"
#include <stdint.h>
#include <stdlib.h>
#include <wayland-server.h>
-#include "libds/log.h"
-#include "libds/output.h"
+#include <libds/log.h>
+#include <libds/output.h>
+#include <tizen-dpms-server-protocol.h>
#include "libds-tizen/dpms.h"
-#include "tizen-dpms-server-protocol.h"
#include "util.h"
struct ds_tizen_dpms
#include <stdint.h>
#include <stdbool.h>
-#include "libds/log.h"
+#include <libds/log.h>
#include "libds-tizen/keyrouter.h"
#include "util.h"
#include <stdio.h>
#include <stdlib.h>
-#include "libds/log.h"
+#include <libds/log.h>
#include "keyrouter.h"
]
libds_tizen_keyrouter_deps = [
- dep_libds,
dep_libds_tizen,
dependency('tizen-extension-server', required: true),
]
'dpms.c',
]
+math = meson.get_compiler('c').find_library('m')
+wayland_server = dependency('wayland-server', required: true)
+pixman = dependency('pixman-1', required: true)
+libdrm = dependency('libdrm', required: true)
+xkbcommon = dependency('xkbcommon', required: true)
+rt = meson.get_compiler('c').find_library('rt')
+
+if wayland_server.version().version_compare('>= 1.19')
+ cdata.set('HAVE_WL_SEAT_ERROR_MISSING_CAPABILITY', '1')
+endif
+
+base_deps = [
+ math,
+ wayland_server,
+ pixman,
+ libdrm,
+ xkbcommon,
+ rt,
+]
+
libds_tizen_deps = [
- dep_libds,
+ base_deps,
+ dependency('libds', required: true),
dependency('libdrm', required: true),
dependency('libtbm', required: true),
dependency('wayland-tbm-server', required: true),
#include <drm_fourcc.h>
#include <tbm_type.h>
-#include "libds/log.h"
+#include <libds/log.h>
#include "pixel_format.h"
#ifdef ARRAY_LENGTH
#include <tbm_bufmgr.h>
-#include "libds/log.h"
+#include <libds/log.h>
#include "pixel_format.h"
#include "tbm_server.h"
#include <wayland-server.h>
#include <wayland-tbm-server.h>
#include <tbm_surface.h>
-#include "libds/interfaces/buffer.h"
+#include <libds/interfaces/buffer.h>
struct ds_tbm_server
{
#include <cynara-creds-socket.h>
#include <sys/smack.h>
-#include "libds/log.h"
+#include <libds/log.h>
#include "util.h"
#define CYNARA_BUFSIZE 128
+++ /dev/null
-#include <assert.h>
-
-#include "addon.h"
-
-void
-ds_addon_set_init(struct ds_addon_set *set)
-{
- wl_list_init(&set->addons);
-}
-
-void
-ds_addon_set_finish(struct ds_addon_set *set)
-{
- struct ds_addon *addon, *tmp;
-
- wl_list_for_each_safe(addon, tmp, &set->addons, link) {
- ds_addon_finish(addon);
- addon->impl->destroy(addon);
- }
-}
-
-void
-ds_addon_init(struct ds_addon *addon, struct ds_addon_set *set,
- const void *owner, const struct ds_addon_interface *impl)
-{
- struct ds_addon *iter;
-
- assert(owner && impl);
-
- wl_list_for_each(iter, &set->addons, link) {
- if (iter->owner == addon->owner && iter->impl == addon->impl)
- assert(0 && "Can't have two addons of the same type with the same owner");
- }
-
- wl_list_insert(&set->addons, &addon->link);
-
- addon->owner = owner;
- addon->impl = impl;
-}
-
-void
-ds_addon_finish(struct ds_addon *addon)
-{
- wl_list_remove(&addon->link);
- wl_list_init(&addon->link);
-}
-
-struct ds_addon *
-ds_addon_find(struct ds_addon_set *set, const void *owner,
- const struct ds_addon_interface *impl)
-{
- struct ds_addon *addon;
-
- wl_list_for_each(addon, &set->addons, link) {
- if (addon->owner == owner && addon->impl == impl)
- return addon;
- }
-
- return NULL;
-}
+++ /dev/null
-#ifndef DS_ADDON_H
-#define DS_ADDON_H
-
-#include <wayland-util.h>
-
-struct ds_addon_set {
- struct wl_list addons;
-};
-
-struct ds_addon {
- const struct ds_addon_interface *impl;
- const void *owner;
- struct wl_list link;
-};
-
-struct ds_addon_interface {
- const char *name;
- void (*destroy)(struct ds_addon *addon);
-};
-
-void
-ds_addon_set_init(struct ds_addon_set *set);
-
-void
-ds_addon_set_finish(struct ds_addon_set *set);
-
-void
-ds_addon_init(struct ds_addon *addon, struct ds_addon_set *set,
- const void *owner, const struct ds_addon_interface *impl);
-
-void
-ds_addon_finish(struct ds_addon *addon);
-
-struct ds_addon *
-ds_addon_find(struct ds_addon_set *set, const void *owner,
- const struct ds_addon_interface *impl);
-
-#endif
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#include <wayland-server.h>
-
-#include "libds/log.h"
-#include "libds/interfaces/allocator.h"
-
-WL_EXPORT void
-ds_allocator_init(struct ds_allocator *alloc,
- const struct ds_allocator_interface *iface, uint32_t buffer_caps)
-{
- alloc->iface = iface;
- alloc->buffer_caps = buffer_caps;
-
- wl_signal_init(&alloc->events.destroy);
-}
-
-WL_EXPORT void
-ds_allocator_destroy(struct ds_allocator *alloc)
-{
- wl_signal_emit(&alloc->events.destroy, NULL);
- alloc->iface->destroy(alloc);
-}
-
-WL_EXPORT struct ds_buffer *
-ds_allocator_create_buffer(struct ds_allocator *alloc, int width, int height,
- uint32_t format)
-{
- return alloc->iface->create_buffer(alloc, width, height, format);
-}
-
-WL_EXPORT void
-ds_allocator_add_destroy_listener(struct ds_allocator *alloc,
- struct wl_listener *listener)
-{
- wl_signal_add(&alloc->events.destroy, listener);
-}
+++ /dev/null
-libds_files += files('shm.c')
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#include <drm_fourcc.h>
-#include <wayland-server.h>
-
-#include "libds/allocator/shm.h"
-#include "libds/interfaces/allocator.h"
-#include "libds/interfaces/buffer.h"
-#include "libds/log.h"
-#include "util.h"
-
-struct ds_shm_allocator
-{
- struct ds_allocator base;
-};
-
-struct ds_shm_buffer
-{
- struct ds_buffer base;
- struct ds_shm_attributes shm;
- void *data;
- size_t size;
-};
-
-static const struct ds_allocator_interface shm_allocator_iface;
-
-WL_EXPORT struct ds_allocator *
-ds_shm_allocator_create(void)
-{
- struct ds_shm_allocator *alloc;
-
- alloc = calloc(1, sizeof *alloc);
- if (!alloc)
- return NULL;
-
- ds_allocator_init(&alloc->base, &shm_allocator_iface,
- DS_BUFFER_CAP_DATA_PTR | DS_BUFFER_CAP_SHM);
-
- ds_dbg("Shm allocator(%p) created", alloc);
-
- return &alloc->base;
-}
-
-static struct ds_shm_allocator *
-shm_allocator_from_allocator(struct ds_allocator *ds_allocator)
-{
- assert(ds_allocator->iface == &shm_allocator_iface);
- return (struct ds_shm_allocator *)ds_allocator;
-}
-
-static void
-shm_allocator_destroy(struct ds_allocator *ds_allocator)
-{
- struct ds_shm_allocator *alloc;
-
- alloc = shm_allocator_from_allocator(ds_allocator);
- ds_dbg("Destroy Shm allocator(%p)", alloc);
- free(alloc);
-}
-
-static const struct ds_buffer_interface shm_buffer_interface;
-
-static struct ds_shm_buffer *
-shm_buffer_from_buffer(struct ds_buffer *buffer)
-{
- assert(buffer->iface == &shm_buffer_interface);
- return (struct ds_shm_buffer *)buffer;
-}
-
-static void
-shm_buffer_destroy(struct ds_buffer *ds_buffer)
-{
- struct ds_shm_buffer *buffer;
-
- buffer = shm_buffer_from_buffer(ds_buffer);
-
- ds_dbg("Destroy shm buffer(%p)", buffer);
-
- munmap(buffer->data, buffer->size);
- close(buffer->shm.fd);
- free(buffer);
-}
-
-static bool
-shm_buffer_get_shm(struct ds_buffer *ds_buffer, struct ds_shm_attributes *shm)
-{
- struct ds_shm_buffer *buffer;
-
- buffer = shm_buffer_from_buffer(ds_buffer);
- memcpy(shm, &buffer->shm, sizeof *shm);
- return true;
-}
-
-static bool
-shm_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, uint32_t flags,
- void **data, uint32_t *format, size_t *stride)
-{
- struct ds_shm_buffer *buffer;
-
- buffer = shm_buffer_from_buffer(ds_buffer);
- *data = buffer->data;
- *format = buffer->shm.format;
- *stride = buffer->shm.stride;
- return true;
-}
-
-static void
-shm_buffer_end_data_ptr_access(struct ds_buffer *buffer)
-{
- (void) buffer;
-
- // This space is intentionally left blank
-}
-
-static const struct ds_buffer_interface shm_buffer_interface =
-{
- .destroy = shm_buffer_destroy,
- .get_shm = shm_buffer_get_shm,
- .begin_data_ptr_access = shm_buffer_begin_data_ptr_access,
- .end_data_ptr_access = shm_buffer_end_data_ptr_access,
-};
-
-static struct ds_buffer *
-shm_allocator_create_buffer(struct ds_allocator *ds_allocator,
- int width, int height, uint32_t format)
-{
- struct ds_shm_buffer *buffer;
- int bytes_per_pixel, stride;
-
- buffer = calloc(1, sizeof *buffer);
- if (!buffer)
- return NULL;
-
- ds_buffer_init(&buffer->base, &shm_buffer_interface, width, height);
-
- // FIXME
- bytes_per_pixel = 4;
- stride = width * bytes_per_pixel;
- buffer->size = stride * height;
- buffer->shm.fd = allocate_shm_file(buffer->size);
- if (buffer->shm.fd < 0) {
- free(buffer);
- return NULL;
- }
-
- buffer->shm.format = format;
- buffer->shm.width = width;
- buffer->shm.height = height;
- buffer->shm.stride = stride;
- buffer->shm.offset = 0;
-
- buffer->data = mmap(NULL, buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED,
- buffer->shm.fd, 0);
- if (buffer->data == MAP_FAILED) {
- ds_log_errno(DS_ERR, "mmap failed");
- close(buffer->shm.fd);
- free(buffer);
- return NULL;
- }
-
- ds_dbg("Shm buffer(%p) created: size(%dx%d)", buffer, width, height);
-
- return &buffer->base;
-}
-
-static const struct ds_allocator_interface shm_allocator_iface =
-{
- .destroy = shm_allocator_destroy,
- .create_buffer = shm_allocator_create_buffer,
-};
+++ /dev/null
-#include <stdlib.h>
-
-#include <wayland-server.h>
-
-#include "libds/interfaces/backend.h"
-
-WL_EXPORT bool
-ds_backend_start(struct ds_backend *backend)
-{
- if (backend->iface->start)
- return backend->iface->start(backend);
-
- backend->started = true;
-
- return true;
-}
-
-WL_EXPORT void
-ds_backend_destroy(struct ds_backend *backend)
-{
- if (!backend)
- return;
-
- if (backend->iface && backend->iface->destroy)
- backend->iface->destroy(backend);
- else
- free(backend);
-}
-
-WL_EXPORT void
-ds_backend_add_destroy_listener(struct ds_backend *backend,
- struct wl_listener *listener)
-{
- wl_signal_add(&backend->events.destroy, listener);
-}
-
-WL_EXPORT void
-ds_backend_add_new_output_listener(struct ds_backend *backend,
- struct wl_listener *listener)
-{
- wl_signal_add(&backend->events.new_output, listener);
-}
-
-WL_EXPORT void
-ds_backend_add_new_input_listener(struct ds_backend *backend,
- struct wl_listener *listener)
-{
- wl_signal_add(&backend->events.new_input, listener);
-}
-
-void
-ds_backend_init(struct ds_backend *backend,
- struct wl_display *display,
- const struct ds_backend_interface *iface)
-{
- backend->iface = iface;
- backend->display = display;
- wl_signal_init(&backend->events.destroy);
- wl_signal_init(&backend->events.new_output);
- wl_signal_init(&backend->events.new_input);
-}
-
-void
-ds_backend_finish(struct ds_backend *backend)
-{
- wl_signal_emit(&backend->events.destroy, backend);
-}
+++ /dev/null
-#include <assert.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "libds/log.h"
-
-#include "backend.h"
-
-static const struct ds_backend_interface libinput_backend_interface;
-static void libinput_backend_handle_display_destroy(
- struct wl_listener *listener, void *data);
-
-WL_EXPORT struct ds_backend *
-ds_libinput_backend_create(struct wl_display *display)
-{
- struct ds_libinput_backend *libinput_backend;
-
- libinput_backend = calloc(1, sizeof *libinput_backend);
- if (!libinput_backend) {
- ds_log_errno(DS_ERR, "Could not allocate memory");
- return NULL;
- }
-
- ds_backend_init(&libinput_backend->base, display, &libinput_backend_interface);
-
- libinput_backend->display = display;
- wl_list_init(&libinput_backend->devices);
-
- libinput_backend->display_destroy.notify =
- libinput_backend_handle_display_destroy;
- wl_display_add_destroy_listener(display,
- &libinput_backend->display_destroy);
-
- ds_inf("Libinput backend(%p) created",
- libinput_backend);
-
- return &libinput_backend->base;
-}
-
-WL_EXPORT struct ds_libinput_backend *
-libinput_backend_from_backend(struct ds_backend *backend)
-{
- assert(backend->iface == &libinput_backend_interface);
- return (struct ds_libinput_backend *)backend;
-}
-
-void
-destroy_libinput_input_device(struct ds_libinput_input_device *dev)
-{
- ds_input_device_destroy(&dev->base);
- wl_list_remove(&dev->link);
-}
-
-static void
-libinput_backend_destroy(struct ds_libinput_backend *backend)
-{
- struct ds_libinput_input_device *dev, *tmp_dev;
-
- wl_list_for_each_safe(dev, tmp_dev, &backend->devices, link)
- destroy_libinput_input_device(dev);
-
- ds_backend_finish(&backend->base);
- wl_list_remove(&backend->display_destroy.link);
- wl_event_source_remove(backend->server_event_source);
- udev_unref(backend->udev);
- libinput_unref(backend->libinput_context);
-
- free(backend);
-}
-
-static int
-libinput_open_restricted(const char *path, int flags, void *_backend)
-{
- int fd = -1;
- struct stat s;
-
- fd = open(path, flags | O_CLOEXEC);
-
- if (fd < 0 || (fstat(fd, &s) == -1)) {
- ds_log(DS_ERR, "Could not open device");
- close(fd);
- return -1;
- }
- return fd;
-}
-
-static void
-libinput_close_restricted(int fd, void *_backend)
-{
- if (fd >= 0) close(fd);
-}
-
-static const struct libinput_interface libinput_impl = {
- .open_restricted = libinput_open_restricted,
- .close_restricted = libinput_close_restricted
-};
-
-static int
-handle_libinput_readable(int fd, uint32_t mask, void *_backend)
-{
- struct ds_libinput_backend *backend = _backend;
- struct libinput_event *event;
- int ret;
-
- ret = libinput_dispatch(backend->libinput_context);
- if (ret != 0) {
- ds_log(DS_ERR, "Failed to dispatch libinput: %s", strerror(-ret));
- wl_display_terminate(backend->display);
- return 0;
- }
-
- while ((event = libinput_get_event(backend->libinput_context))) {
- handle_libinput_event(backend, event);
- libinput_event_destroy(event);
- }
- return 0;
-}
-
-static void
-log_libinput(struct libinput *libinput_context,
- enum libinput_log_priority priority, const char *fmt, va_list args)
-{
- char buf[1024] = {0,};
-
- vsnprintf(buf, 1024, fmt, args);
- switch (priority) {
- case LIBINPUT_LOG_PRIORITY_DEBUG:
- ds_log(DS_DBG,"%s", buf);
- break;
- case LIBINPUT_LOG_PRIORITY_INFO:
- ds_log(DS_INF, "%s", buf);
- break;
- case LIBINPUT_LOG_PRIORITY_ERROR:
- ds_log(DS_ERR, "%s", buf);
- break;
- default:
- break;
- }
-}
-
-static bool
-libinput_backend_iface_start(struct ds_backend *ds_backend)
-{
- struct ds_libinput_backend *backend;
- struct wl_event_loop *event_loop;
- int libinput_fd;
-
- backend = libinput_backend_from_backend(ds_backend);
- ds_log(DS_DBG, "Starting libinput backend");
-
- backend->udev = udev_new();
- backend->libinput_context = libinput_udev_create_context(&libinput_impl,
- backend, backend->udev);
- if (!backend->libinput_context) {
- ds_log(DS_ERR, "Failed to create libinput context");
- return false;
- }
-
- if (libinput_udev_assign_seat(backend->libinput_context, "seat0") != 0) {
- ds_log(DS_ERR, "Failed to assign libinput seat");
- return false;
- }
-
- libinput_log_set_handler(backend->libinput_context, log_libinput);
- libinput_log_set_priority(backend->libinput_context,
- LIBINPUT_LOG_PRIORITY_DEBUG);
-
- libinput_fd = libinput_get_fd(backend->libinput_context);
- if (wl_list_empty(&backend->devices)) {
- handle_libinput_readable(libinput_fd, WL_EVENT_READABLE, backend);
- if (wl_list_empty(&backend->devices)) {
- ds_log(DS_ERR, "libinput initialization failed, no input devices");
- return false;
- }
- }
-
- event_loop = wl_display_get_event_loop(backend->display);
- if (backend->server_event_source) {
- wl_event_source_remove(backend->server_event_source);
- }
- backend->server_event_source =
- wl_event_loop_add_fd(event_loop, libinput_fd, WL_EVENT_READABLE,
- handle_libinput_readable, backend);
- if (!backend->server_event_source) {
- ds_log(DS_ERR, "Failed to create input event on event loop");
- return false;
- }
- ds_log(DS_DBG, "libinput successfully initialized");
-
- return true;
-}
-
-static void
-libinput_backend_iface_destroy(struct ds_backend *backend)
-{
- struct ds_libinput_backend *libinput_backend;
-
- if (!backend)
- return;
-
- libinput_backend = libinput_backend_from_backend(backend);
- libinput_backend_destroy(libinput_backend);
-}
-
-static const struct ds_backend_interface libinput_backend_interface =
-{
- .start = libinput_backend_iface_start,
- .destroy = libinput_backend_iface_destroy,
- .get_drm_fd = NULL,
-};
-
-static void
-libinput_backend_handle_display_destroy(struct wl_listener *listener,
- void *data)
-{
- struct ds_libinput_backend *libinput_backend;
-
- libinput_backend =
- wl_container_of(listener, libinput_backend, display_destroy);
- libinput_backend_destroy(libinput_backend);
-}
-
-uint32_t usec_to_msec(uint64_t usec) {
- return (uint32_t)(usec / 1000);
-}
\ No newline at end of file
+++ /dev/null
-#ifndef DS_BACKEND_LIBINPUT_H
-#define DS_BACKEND_LIBINPUT_H
-
-#include <libinput.h>
-#include <libudev.h>
-
-#include "libds/interfaces/backend.h"
-#include "libds/interfaces/input_device.h"
-#include "libds/interfaces/pointer.h"
-#include "libds/interfaces/keyboard.h"
-#include "libds/interfaces/touch.h"
-
-struct ds_libinput_backend
-{
- struct ds_backend base;
-
- struct wl_display *display;
- struct wl_listener display_destroy;
-
- struct udev *udev;
- struct libinput *libinput_context;
- struct wl_list devices; // ds_libinput_input_device::link
-
- struct wl_event_source *server_event_source;
-};
-
-struct ds_libinput_input_device
-{
- struct ds_input_device base;
-
- struct ds_libinput_backend *backend;
- struct libinput_device *handle;
-
- struct wl_list link; //ds_libinput_backend.devices
-};
-
-uint32_t usec_to_msec(uint64_t usec);
-
-struct ds_libinput_backend *
- libinput_backend_from_backend(struct ds_backend *backend);
-
-void handle_libinput_event(struct ds_libinput_backend *state,
- struct libinput_event *event);
-
-void destroy_libinput_input_device(struct ds_libinput_input_device *dev);
-
-//keyboard
-void handle_keyboard_key(struct libinput_event *event,
- struct ds_keyboard *kbd);
-
-//pointer
-void handle_pointer_motion(struct libinput_event *event,
- struct ds_pointer *pointer);
-void handle_pointer_motion_abs(struct libinput_event *event,
- struct ds_pointer *pointer);
-void handle_pointer_button(struct libinput_event *event,
- struct ds_pointer *pointer);
-void handle_pointer_axis(struct libinput_event *event,
- struct ds_pointer *pointer);
-
-//touch
-void handle_touch_down(struct libinput_event *event,
- struct ds_touch *touch);
-void handle_touch_up(struct libinput_event *event,
- struct ds_touch *touch);
-void handle_touch_motion(struct libinput_event *event,
- struct ds_touch *touch);
-void handle_touch_cancel(struct libinput_event *event,
- struct ds_touch *touch);
-void handle_touch_frame(struct libinput_event *event,
- struct ds_touch *touch);
-
-#endif
+++ /dev/null
-#include <assert.h>
-
-#include "libds/log.h"
-#include "backend.h"
-
-static const struct ds_input_device_interface input_device_iface;
-
-static bool
-ds_input_device_is_libinput(struct ds_input_device *ds_dev)
-{
- return ds_dev->iface == &input_device_iface;
-}
-
-static struct ds_libinput_input_device *
-get_libinput_input_device_from_input_device(struct ds_input_device *ds_dev)
-{
- assert(ds_input_device_is_libinput(ds_dev));
- return (struct ds_libinput_input_device *)ds_dev;
-}
-
-static void
-input_device_iface_destroy(struct ds_input_device *ds_dev)
-{
- struct ds_libinput_input_device *dev;
-
- dev = get_libinput_input_device_from_input_device(ds_dev);
-
- libinput_device_unref(dev->handle);
-
- free(dev);
-}
-
-static const struct ds_input_device_interface input_device_iface =
-{
- .destroy = input_device_iface_destroy,
-};
-
-static struct ds_keyboard *
-create_ds_keyboard()
-{
- struct ds_keyboard *kbd;
- kbd = calloc(1, sizeof *kbd);
- if (!kbd) {
- ds_err("Could not allocate memory");
- return NULL;
- }
- ds_keyboard_init(kbd, NULL);
-
- return kbd;
-}
-
-static struct ds_pointer *
-create_ds_pointer()
-{
- struct ds_pointer *pointer;
- pointer = calloc(1, sizeof *pointer);
- if (!pointer) {
- ds_err("Could not allocate memory");
- return NULL;
- }
- ds_pointer_init(pointer, NULL);
-
- return pointer;
-}
-
-static struct ds_touch *
-create_ds_touch()
-{
- struct ds_touch *touch;
- touch = calloc(1, sizeof *touch);
- if (!touch) {
- ds_err("Could not allocate memory");
- return NULL;
- }
- ds_touch_init(touch, NULL);
-
- return touch;
-}
-
-static void
-handle_device_added(struct ds_libinput_backend *backend,
- struct libinput_device *libinput_dev)
-{
- int vendor, product;
- const char *name;
- struct ds_libinput_input_device *dev;
-
- vendor = libinput_device_get_id_vendor(libinput_dev);
- product = libinput_device_get_id_product(libinput_dev);
- name = libinput_device_get_name(libinput_dev);
- ds_log(DS_DBG, "Adding %s [%d:%d]", name, vendor, product);
-
- dev = calloc(1, sizeof(struct ds_libinput_input_device));
- if (dev == NULL) {
- ds_log(DS_ERR, "failed to allocate ds_libinput_input_device");
- return;
- }
-
- dev->handle = libinput_dev;
- dev->backend = backend;
- libinput_device_ref(libinput_dev);
- libinput_device_set_user_data(libinput_dev, dev);
-
- wl_list_insert(&backend->devices, &dev->link);
-
- if (libinput_device_has_capability(
- libinput_dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) {
- ds_input_device_init(&dev->base, DS_INPUT_DEVICE_KEYBOARD,
- &input_device_iface, name, vendor, product);
- dev->base.keyboard = create_ds_keyboard();
-
- wl_signal_emit(&backend->base.events.new_input,
- &dev->base);
- }
-
- if (libinput_device_has_capability(
- libinput_dev, LIBINPUT_DEVICE_CAP_POINTER)) {
- ds_input_device_init(&dev->base, DS_INPUT_DEVICE_POINTER,
- &input_device_iface, name, vendor, product);
- dev->base.pointer = create_ds_pointer();
-
- wl_signal_emit(&backend->base.events.new_input,
- &dev->base);
- }
-
- if (libinput_device_has_capability(
- libinput_dev, LIBINPUT_DEVICE_CAP_TOUCH)) {
- ds_input_device_init(&dev->base, DS_INPUT_DEVICE_TOUCH,
- &input_device_iface, name, vendor, product);
- dev->base.touch = create_ds_touch();
-
- wl_signal_emit(&backend->base.events.new_input,
- &dev->base);
- }
-}
-
-static void
-handle_device_removed(struct ds_libinput_backend *backend,
- struct libinput_device *libinput_dev)
-{
- int vendor, product;
- const char *name;
- struct ds_libinput_input_device *dev;
-
- vendor = libinput_device_get_id_vendor(libinput_dev);
- product = libinput_device_get_id_product(libinput_dev);
- name = libinput_device_get_name(libinput_dev);
- ds_log(DS_DBG, "Removing %s [%d:%d]", name, vendor, product);
-
- dev = libinput_device_get_user_data(libinput_dev);
- if (dev == NULL) {
- ds_log(DS_ERR, "libinput_device has no ds_libinput_input_device");
- return;
- }
-
- destroy_libinput_input_device(dev);
-}
-
-void
-handle_libinput_event(struct ds_libinput_backend *backend,
- struct libinput_event *event)
-{
- struct libinput_device *libinput_dev;
- struct ds_libinput_input_device *dev;
- enum libinput_event_type event_type;
-
- libinput_dev = libinput_event_get_device(event);
- event_type = libinput_event_get_type(event);
- dev = libinput_device_get_user_data(libinput_dev);
-
- switch (event_type) {
- case LIBINPUT_EVENT_DEVICE_ADDED:
- handle_device_added(backend, libinput_dev);
- break;
- case LIBINPUT_EVENT_DEVICE_REMOVED:
- handle_device_removed(backend, libinput_dev);
- break;
- case LIBINPUT_EVENT_KEYBOARD_KEY:
- handle_keyboard_key(event, dev->base.keyboard);
- break;
- case LIBINPUT_EVENT_POINTER_MOTION:
- handle_pointer_motion(event, dev->base.pointer);
- break;
- case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
- handle_pointer_motion_abs(event, dev->base.pointer);
- break;
- case LIBINPUT_EVENT_POINTER_BUTTON:
- handle_pointer_button(event, dev->base.pointer);
- break;
- case LIBINPUT_EVENT_POINTER_AXIS:
- handle_pointer_axis(event, dev->base.pointer);
- break;
- case LIBINPUT_EVENT_TOUCH_DOWN:
- handle_touch_down(event, dev->base.touch);
- break;
- case LIBINPUT_EVENT_TOUCH_UP:
- handle_touch_up(event, dev->base.touch);
- break;
- case LIBINPUT_EVENT_TOUCH_MOTION:
- handle_touch_motion(event, dev->base.touch);
- break;
- case LIBINPUT_EVENT_TOUCH_CANCEL:
- handle_touch_cancel(event, dev->base.touch);
- break;
- case LIBINPUT_EVENT_TOUCH_FRAME:
- handle_touch_frame(event, dev->base.touch);
- break;
- default:
- ds_log(DS_DBG, "Unknown libinput event %d", event_type);
- break;
- }
-}
+++ /dev/null
-#include "libds/log.h"
-#include "backend.h"
-
-void
-handle_keyboard_key(struct libinput_event *event,
- struct ds_keyboard *kbd)
-{
- struct libinput_event_keyboard *kbevent;
- uint32_t key;
- enum libinput_key_state li_state;
- enum wl_keyboard_key_state state = WL_KEYBOARD_KEY_STATE_PRESSED;
- struct ds_event_keyboard_key ds_event = {0};
-
- kbevent = libinput_event_get_keyboard_event(event);
-
- key = libinput_event_keyboard_get_key(kbevent);
- li_state = libinput_event_keyboard_get_key_state(kbevent);
- if (li_state == LIBINPUT_KEY_STATE_PRESSED) {
- state = WL_KEYBOARD_KEY_STATE_PRESSED;
- }
- else {
- state = WL_KEYBOARD_KEY_STATE_RELEASED;
- }
-
- ds_log(DS_DBG, "Keyboard(%p) key event key:%d, state:%s", kbd, key,
- (state == WL_KEYBOARD_KEY_STATE_PRESSED) ? "PRESSED":"RELEASED");
-
- ds_event.keycode = key;
- ds_event.state = state;
- ds_event.time_msec = usec_to_msec(
- libinput_event_keyboard_get_time_usec(kbevent));
- ds_event.update_state = false;
-
- ds_keyboard_notify_key(kbd, &ds_event);
-}
+++ /dev/null
-libds_files += files(
- 'backend.c',
- 'input.c',
- 'keyboard.c',
- 'pointer.c',
- 'touch.c',
-)
-
-libinput = dependency('libinput', required: true)
-libudev = dependency('libudev', required: true)
-
-libds_deps += [
- libinput,
- libudev,
-]
+++ /dev/null
-#include "libds/log.h"
-#include "backend.h"
-
-void
-handle_pointer_motion(struct libinput_event *event,
- struct ds_pointer *pointer)
-{
- struct libinput_event_pointer *pevent;
- double delta_x, delta_y;
- struct ds_event_pointer_motion ds_event = { 0 };
-
- pevent = libinput_event_get_pointer_event(event);
-
- delta_x = libinput_event_pointer_get_dx(pevent);
- delta_y = libinput_event_pointer_get_dy(pevent);
-
- ds_log(DS_DBG, "pointer motion event delta_x:%f, delta_y:%f", delta_x, delta_y);
-
- ds_event.device = NULL;
- ds_event.time_msec = usec_to_msec(
- libinput_event_pointer_get_time_usec(pevent));
- ds_event.delta_x = delta_x;
- ds_event.delta_y = delta_y;
-
- wl_signal_emit(&pointer->events.motion, &ds_event);
-}
-
-void
-handle_pointer_motion_abs(struct libinput_event *event,
- struct ds_pointer *pointer)
-{
- struct libinput_event_pointer *pevent;
- double x, y;
- struct ds_event_pointer_motion_absolute ds_event = { 0 };
-
- pevent = libinput_event_get_pointer_event(event);
-
- x = libinput_event_pointer_get_absolute_x_transformed(pevent, 1);
- y = libinput_event_pointer_get_absolute_y_transformed(pevent, 1);
-
- ds_log(DS_DBG, "Pointer(%p) motion abs event x:%f, y:%f", pointer, x, y);
-
- ds_event.device = NULL;
- ds_event.time_msec = usec_to_msec(
- libinput_event_pointer_get_time_usec(pevent));
- ds_event.x = x;
- ds_event.y = y;
-
- wl_signal_emit(&pointer->events.motion_absolute, &ds_event);
-}
-void
-handle_pointer_button(struct libinput_event *event,
- struct ds_pointer *pointer)
-{
- struct libinput_event_pointer *pevent;
- uint32_t button;
- enum libinput_button_state li_state = LIBINPUT_BUTTON_STATE_PRESSED;
- enum ds_button_state state = DS_BUTTON_PRESSED;
- struct ds_event_pointer_button ds_event = { 0 };
-
- pevent = libinput_event_get_pointer_event(event);
-
- button = libinput_event_pointer_get_button(pevent);
- button = ((button & 0x00F) + 1);
- if (button == 3) button = 2;
- else if (button == 2) button = 3;
-
- li_state = libinput_event_pointer_get_button_state(pevent);
- if (li_state == LIBINPUT_BUTTON_STATE_PRESSED) {
- state = DS_BUTTON_PRESSED;
- }
- else {
- state = DS_BUTTON_RELEASED;
- }
- ds_log(DS_DBG, "Pointer(%p) button event button:%d state:%s",
- pointer, button,
- (state == DS_BUTTON_PRESSED) ? "PRESSED" : "RELEASED");
-
- ds_event.device = NULL;
- ds_event.time_msec = usec_to_msec(
- libinput_event_pointer_get_time_usec(pevent));
- ds_event.button = button;
- ds_event.state = state;
-
- wl_signal_emit(&pointer->events.button, &ds_event);
-}
-
-void
-handle_pointer_axis(struct libinput_event *event,
- struct ds_pointer *pointer)
-{
- ds_log(DS_DBG, "pointer(%p) axis event", pointer);
- /* TODO: wl_signal_emit() */
-}
+++ /dev/null
-#include "libds/log.h"
-#include "backend.h"
-
-void
-handle_touch_down(struct libinput_event *event,
- struct ds_touch *touch)
-{
- struct libinput_event_touch *tevent;
- uint32_t touch_id;
- double x, y;
- struct ds_event_touch_down ds_event = { 0 };
-
- tevent = libinput_event_get_touch_event(event);
-
- touch_id = libinput_event_touch_get_seat_slot(tevent);
- x = libinput_event_touch_get_x_transformed(tevent, 1);
- y = libinput_event_touch_get_y_transformed(tevent, 1);
-
- ds_log(DS_DBG, "touch down event id:%d, x:%f, y:%f", touch_id, x, y);
-
- ds_event.device = NULL;
- ds_event.time_msec = usec_to_msec(
- libinput_event_touch_get_time_usec(tevent));
- ds_event.id = touch_id;
- ds_event.x = x;
- ds_event.y = y;
-
- wl_signal_emit(&touch->events.down, &ds_event);
-}
-
-void
-handle_touch_up(struct libinput_event *event,
- struct ds_touch *touch)
-{
- struct libinput_event_touch *tevent;
- uint32_t touch_id;
- struct ds_event_touch_up ds_event = { 0 };
-
- tevent = libinput_event_get_touch_event(event);
-
- touch_id = libinput_event_touch_get_seat_slot(tevent);
-
- ds_log(DS_DBG, "touch up event id:%d", touch_id);
-
- ds_event.device = NULL;
- ds_event.time_msec = usec_to_msec(
- libinput_event_touch_get_time_usec(tevent));
- ds_event.id = touch_id;
-
- wl_signal_emit(&touch->events.up, &ds_event);
-}
-
-void
-handle_touch_motion(struct libinput_event *event,
- struct ds_touch *touch)
-{
- struct libinput_event_touch *tevent;
- uint32_t touch_id;
- double x, y;
- struct ds_event_touch_motion ds_event = { 0 };
-
- tevent = libinput_event_get_touch_event(event);
-
- touch_id = libinput_event_touch_get_seat_slot(tevent);
- x = libinput_event_touch_get_x_transformed(tevent, 1);
- y = libinput_event_touch_get_y_transformed(tevent, 1);
-
- ds_log(DS_DBG, "touch motion event id:%d, x:%f, y:%f", touch_id, x, y);
-
- ds_event.device = NULL;
- ds_event.time_msec = usec_to_msec(
- libinput_event_touch_get_time_usec(tevent));
- ds_event.id = touch_id;
- ds_event.x = x;
- ds_event.y = y;
-
- wl_signal_emit(&touch->events.motion, &ds_event);
-}
-
-void
-handle_touch_cancel(struct libinput_event *event,
- struct ds_touch *touch)
-{
- struct libinput_event_touch *tevent;
- uint32_t touch_id;
-
- tevent = libinput_event_get_touch_event(event);
-
- touch_id = libinput_event_touch_get_seat_slot(tevent);
-
- ds_log(DS_DBG, "touch cancel event id:%d", touch_id);
- /* TODO: wl_signal_emit() */
-}
-
-void
-handle_touch_frame(struct libinput_event *event,
- struct ds_touch *touch)
-{
- ds_log(DS_DBG, "touch frame event");
- /* TODO: wl_signal_emit() */
-}
+++ /dev/null
-subdir('wayland')
-subdir('libinput')
+++ /dev/null
-#include <assert.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#include <wayland-server.h>
-#include <wayland-client.h>
-
-#include "libds/log.h"
-#include "libds/output.h"
-#include "xdg-shell-client-protocol.h"
-
-#include "backend.h"
-
-static const struct ds_backend_interface wl_backend_interface;
-static void wl_backend_handle_display_destroy(struct wl_listener *listener,
- void *data);
-static bool wl_backend_server_init(struct ds_wl_backend *wl_backend,
- struct ds_wl_backend_server *server, const char *name);
-static void wl_backend_server_finish(struct ds_wl_backend_server *server);
-static int wl_backend_handle_dispatch_events(int fd, uint32_t mask,
- void *data);
-
-WL_EXPORT struct ds_backend *
-ds_wl_backend_create(struct wl_display *display, const char *server_name)
-{
- struct ds_wl_backend *wl_backend;
- struct wl_event_loop *loop;
- int fd;
-
- wl_backend = calloc(1, sizeof *wl_backend);
- if (!wl_backend) {
- ds_log_errno(DS_ERR, "Could not allocate memory");
- return NULL;
- }
-
- ds_backend_init(&wl_backend->base, display, &wl_backend_interface);
-
- wl_backend->display = display;
- wl_list_init(&wl_backend->buffers);
- wl_list_init(&wl_backend->outputs);
- wl_list_init(&wl_backend->seats);
-
- if (!wl_backend_server_init(wl_backend, &wl_backend->server, server_name)) {
- ds_err("Failed to initialize Wayland Server");
- goto err_server;
- }
-
- loop = wl_display_get_event_loop(wl_backend->display);
- fd = wl_display_get_fd(wl_backend->server.display);
-
- wl_backend->server_event_source =
- wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
- wl_backend_handle_dispatch_events, wl_backend);
- if (!wl_backend->server_event_source) {
- ds_err("Failed to create event source");
- goto err_src;
- }
- wl_event_source_check(wl_backend->server_event_source);
-
- wl_backend->display_destroy.notify = wl_backend_handle_display_destroy;
- wl_display_add_destroy_listener(display, &wl_backend->display_destroy);
-
- ds_inf("Wayland backend(%p) created: server name \"%s\"",
- wl_backend, server_name);
-
- return &wl_backend->base;
-
-err_src:
- wl_backend_server_finish(&wl_backend->server);
-err_server:
- ds_backend_finish(&wl_backend->base);
- free(wl_backend);
-
- return NULL;
-}
-
-struct ds_wl_backend *
-wl_backend_from_backend(struct ds_backend *backend)
-{
- assert(backend->iface == &wl_backend_interface);
- return (struct ds_wl_backend *)backend;
-}
-
-static bool
-wl_backend_iface_start(struct ds_backend *ds_backend)
-{
- struct ds_wl_backend *backend;
-
- backend = wl_backend_from_backend(ds_backend);
-
- ds_inf("Starting wayland backend");
-
- for (size_t i = 0; i < backend->requested_outputs; i++)
- create_wl_output(backend);
-
- return true;
-}
-
-static void
-wl_backend_destroy(struct ds_wl_backend *backend)
-{
- struct ds_wl_output *output, *tmp_output;
- struct ds_wl_buffer *buffer, *tmp_buffer;
- struct ds_wl_seat *seat, *tmp_seat;
-
- ds_dbg("Destroy wayland backend(%p)", backend);
-
- wl_list_for_each_safe(output, tmp_output, &backend->outputs, link)
- ds_output_destroy(&output->base);
-
- wl_list_for_each_safe(buffer, tmp_buffer, &backend->buffers, link)
- destroy_wl_buffer(buffer);
-
- wl_list_for_each_safe(seat, tmp_seat, &backend->seats, link)
- destroy_wl_seat(seat);
-
- ds_backend_finish(&backend->base);
-
- wl_list_remove(&backend->display_destroy.link);
-
- wl_event_source_remove(backend->server_event_source);
-
- wl_backend_server_finish(&backend->server);
-
- free(backend);
-}
-
-static void
-wl_backend_iface_destroy(struct ds_backend *backend)
-{
- struct ds_wl_backend *wl_backend;
-
- if (!backend)
- return;
-
- wl_backend = wl_backend_from_backend(backend);
-
- wl_backend_destroy(wl_backend);
-}
-
-static const struct ds_backend_interface wl_backend_interface =
-{
- .start = wl_backend_iface_start,
- .destroy = wl_backend_iface_destroy,
- .get_drm_fd = NULL,
-};
-
-static void
-wl_backend_handle_display_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_wl_backend *wl_backend;
-
- wl_backend = wl_container_of(listener, wl_backend, display_destroy);
- wl_backend_destroy(wl_backend);
-}
-
-static void
-shm_handle_format(void *data, struct wl_shm *shm, uint32_t shm_format)
-{
-}
-
-static const struct wl_shm_listener shm_listener =
-{
- .format = shm_handle_format,
-};
-
-static void
-xdg_wm_base_handle_ping(void *data, struct xdg_wm_base *base, uint32_t serial)
-{
- xdg_wm_base_pong(base, serial);
-}
-
-static const struct xdg_wm_base_listener xdg_wm_base_listener =
-{
- .ping = xdg_wm_base_handle_ping,
-};
-
-static void
-registry_handle_global(void *data, struct wl_registry *registry,
- uint32_t name, const char *iface, uint32_t version)
-{
- struct ds_wl_backend_server *server = data;
- struct ds_wl_seat *seat;
-
- ds_log(DS_DBG, "Wayland global: %s v%d", iface, version);
-
- if (strcmp(iface, wl_compositor_interface.name) == 0) {
- server->compositor = wl_registry_bind(registry, name,
- &wl_compositor_interface, 4);
- }
- else if (strcmp(iface, xdg_wm_base_interface.name) == 0) {
- server->xdg_wm_base = wl_registry_bind(registry, name,
- &xdg_wm_base_interface, 1);
- xdg_wm_base_add_listener(server->xdg_wm_base,
- &xdg_wm_base_listener, NULL);
- }
- else if (strcmp(iface, wl_shm_interface.name) == 0) {
- server->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
- wl_shm_add_listener(server->shm, &shm_listener, server);
- }
- else if (strcmp(iface, wl_seat_interface.name) == 0) {
- seat = create_wl_seat(server->backend, name, version);
- if (!seat) {
- ds_err("Could not create ds_wl_seat");
- return;
- }
-
- wl_list_insert(&server->backend->seats, &seat->link);
- }
-}
-
-static void
-registry_handle_global_remove(void *data, struct wl_registry *registry,
- uint32_t name)
-{
- // TODO
-}
-
-static const struct wl_registry_listener registry_listener =
-{
- .global = registry_handle_global,
- .global_remove = registry_handle_global_remove,
-};
-
-static bool
-wl_backend_server_init(struct ds_wl_backend *wl_backend, struct ds_wl_backend_server *server, const char *name)
-{
- server->backend = wl_backend;
-
- server->display = wl_display_connect(name);
- if (!server->display) {
- ds_log_errno(DS_ERR, "Could not connect to display: name \"%s\"", name);
- return false;
- }
-
- server->registry = wl_display_get_registry(server->display);
- if (!server->registry) {
- ds_log_errno(DS_ERR, "Could not get wl_registry");
- goto err_reg;
- }
-
- wl_registry_add_listener(server->registry, ®istry_listener, server);
-
- wl_display_roundtrip(server->display);
-
- if (!server->compositor) {
- ds_err("Wayland Server does not support wl_compositor");
- goto err_bind;
- }
-
- if (!server->xdg_wm_base) {
- ds_err("Wayland Server does not support xdg_wm_base");
- goto err_bind;
- }
-
- return true;
-
-err_bind:
- if (server->compositor)
- wl_compositor_destroy(server->compositor);
-
- if (server->xdg_wm_base)
- xdg_wm_base_destroy(server->xdg_wm_base);
-
- wl_registry_destroy(server->registry);
-err_reg:
- wl_display_disconnect(server->display);
-
- return false;
-}
-
-static void
-wl_backend_server_finish(struct ds_wl_backend_server *server)
-{
- xdg_wm_base_destroy(server->xdg_wm_base);
- wl_compositor_destroy(server->compositor);
- wl_registry_destroy(server->registry);
- wl_display_disconnect(server->display);
-}
-
-static int
-wl_backend_handle_dispatch_events(int fd, uint32_t mask, void *data)
-{
- struct ds_wl_backend *wl_backend = data;
- struct ds_wl_backend_server *server = &wl_backend->server;
- int count = 0;
-
- if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
- if (mask & WL_EVENT_ERROR) {
- ds_err("Failed to read from Wayland Server");
- }
- wl_display_terminate(wl_backend->display);
- return 0;
- }
-
- count = 0;
- if (mask & WL_EVENT_READABLE)
- count = wl_display_dispatch(server->display);
-
- if (mask & WL_EVENT_WRITABLE)
- wl_display_flush(server->display);
-
- if (mask == 0) {
- count = wl_display_dispatch_pending(server->display);
- wl_display_flush(server->display);
- }
-
- if (count < 0) {
- ds_err("Failed to dispatch Wayland Server");
- wl_display_terminate(wl_backend->display);
- return 0;
- }
-
- return count;
-}
+++ /dev/null
-#ifndef DS_BACKEND_WAYLAND_H
-#define DS_BACKEND_WAYLAND_H
-
-#include "libds/interfaces/backend.h"
-#include "libds/interfaces/output.h"
-#include "libds/interfaces/input_device.h"
-#include "libds/interfaces/pointer.h"
-#include "libds/interfaces/keyboard.h"
-#include "libds/interfaces/touch.h"
-
-struct ds_wl_backend_server
-{
- struct ds_wl_backend *backend;
- struct wl_display *display;
- struct wl_registry *registry;
- struct wl_compositor *compositor;
- struct xdg_wm_base *xdg_wm_base;
- struct wl_event_source *event_source;
- struct wl_shm *shm;
-};
-
-struct ds_wl_backend
-{
- struct ds_backend base;
-
- struct wl_display *display;
- struct wl_listener display_destroy;
-
- struct wl_list outputs; // ds_wl_output.link
- struct wl_list buffers; // ds_wl_buffer.link
- struct wl_list seats; // ds_wl_seat.link
-
- struct wl_event_source *server_event_source;
- struct ds_wl_backend_server server;
-
- size_t requested_outputs;
-};
-
-struct ds_wl_buffer
-{
- struct ds_buffer *buffer;
- struct wl_buffer *wl_buffer;
- struct wl_list link; // ds_wl_backend.buffers
- struct wl_listener buffer_destroy;
-
- bool released;
-};
-
-struct ds_wl_output
-{
- struct ds_output base;
-
- struct ds_wl_backend *backend;
-
- struct wl_surface *surface;
- struct xdg_surface *xdg_surface;
- struct xdg_toplevel *xdg_toplevel;
- struct wl_callback *frame_callback;
-
- struct wl_list link;
-
- struct {
- struct ds_wl_pointer *pointer;
- struct wl_surface *surface;
- int32_t hotspot_x, hotspot_y;
- uint32_t enter_serial;
- } cursor;
-};
-
-struct ds_wl_seat
-{
- struct ds_wl_backend *backend;
- struct ds_wl_output *output;
-
- struct wl_seat *wl_seat;
- char *name;
-
- struct ds_input_device *pointer_dev;
- struct ds_input_device *keyboard_dev;
- struct ds_input_device *touch_dev;
-
- struct wl_callback *initial_info_cb;
-
- struct wl_list link; // ds_wl_backend.seats
-
- enum wl_seat_capability caps;
-
- int version;
- uint32_t enter_serial;
-
- bool initialized;
-};
-
-struct ds_wl_input_device
-{
- struct ds_input_device base;
-
- struct ds_wl_backend *backend;
- struct ds_wl_seat *seat;
-};
-
-struct ds_wl_pointer
-{
- struct ds_pointer base;
-
- struct ds_wl_input_device *input_device;
- struct wl_pointer *wl_pointer;
-};
-
-struct ds_wl_keyboard
-{
- struct ds_keyboard base;
-
- struct wl_keyboard *wl_keyboard;
-};
-
-struct ds_wl_touch
-{
- struct ds_touch base;
-
- struct wl_touch *wl_touch;
-};
-
-struct ds_wl_backend *
-wl_backend_from_backend(struct ds_backend *backend);
-
-struct ds_wl_output *create_wl_output(struct ds_wl_backend *backend);
-
-void
-destroy_wl_buffer(struct ds_wl_buffer *buffer);
-
-struct ds_wl_seat *create_wl_seat(struct ds_wl_backend *backend, uint32_t id,
- uint32_t available_version);
-
-void destroy_wl_seat(struct ds_wl_seat *seat);
-
-void output_enter_pointer(struct ds_wl_output *output,
- struct ds_wl_pointer *pointer, uint32_t serial);
-
-void output_leave_pointer(struct ds_wl_output *output);
-
-#endif
+++ /dev/null
-libds_files += files(
- 'backend.c',
- 'output.c',
- 'seat.c',
-)
-
-protocols = {
- 'xdg-shell': wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml',
-}
-
-protocols_code = {}
-protocols_client_header = {}
-
-foreach name, path : protocols
- client_header = custom_target(
- name.underscorify() + '_client_h',
- input: path,
- output: '@BASENAME@-client-protocol.h',
- command: [wayland_scanner, 'client-header', '@INPUT@', '@OUTPUT@'],
- build_by_default: false,
- )
- libds_files += client_header
-endforeach
-
-libds_deps += [
- dependency('wayland-client', required: true),
-]
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#include <wayland-client.h>
-
-#include "libds/log.h"
-#include "libds/output.h"
-#include "xdg-shell-client-protocol.h"
-
-#include "output.h"
-#include "backend.h"
-
-const struct ds_output_interface wl_output_iface;
-static const struct xdg_surface_listener wl_output_xdg_surface_listener;
-static const struct xdg_toplevel_listener wl_output_xdg_toplevel_listener;
-
-static void output_update_cursor(struct ds_wl_output *output);
-static bool output_set_custom_mode(struct ds_output *ds_output,
- int32_t width, int32_t height, int32_t refresh);
-
-struct ds_output *
-ds_wl_backend_create_output(struct ds_backend *ds_backend)
-{
- struct ds_wl_backend *backend;
- struct ds_wl_output *output;
-
- backend = wl_backend_from_backend(ds_backend);
-
- if (!ds_backend->started) {
- backend->requested_outputs++;
- return NULL;
- }
-
- output = create_wl_output(backend);
- if (!output) {
- ds_err("Could not create ds_wl_output");
- return NULL;
- }
-
- return &output->base;
-}
-
-struct ds_wl_output *
-create_wl_output(struct ds_wl_backend *backend)
-{
- struct ds_wl_output *output;
-
- output = calloc(1, sizeof *output);
- if (!output) {
- ds_log_errno(DS_ERR, "Could not allocate ds_wl_output");
- return NULL;
- }
-
- ds_output_init(&output->base, &backend->base, &wl_output_iface,
- backend->display);
-
- output->backend = backend;
-
- output->surface = wl_compositor_create_surface(backend->server.compositor);
- if (!output->surface) {
- ds_log_errno(DS_ERR, "Could not create output surface");
- goto err;
- }
- wl_surface_set_user_data(output->surface, output);
-
- output->xdg_surface =
- xdg_wm_base_get_xdg_surface(backend->server.xdg_wm_base,
- output->surface);
- if (!output->xdg_surface) {
- ds_log_errno(DS_ERR, "Could not get xdg_surface");
- goto err;
- }
- xdg_surface_add_listener(output->xdg_surface,
- &wl_output_xdg_surface_listener, output);
-
- output->xdg_toplevel =
- xdg_surface_get_toplevel(output->xdg_surface);
- if (!output->xdg_toplevel) {
- ds_log_errno(DS_ERR, "Could not get xdg_toplevel");
- goto err;
- }
- xdg_toplevel_add_listener(output->xdg_toplevel,
- &wl_output_xdg_toplevel_listener, output);
-
- xdg_toplevel_set_app_id(output->xdg_toplevel, "libds");
-
- wl_surface_commit(output->surface);
-
- wl_display_roundtrip(backend->server.display);
-
- wl_list_insert(&backend->outputs, &output->link);
-
- wl_signal_emit(&backend->base.events.new_output, &output->base);
-
- ds_dbg("Wayland output(%p) created", output);
-
- return output;
-
-err:
- ds_output_destroy(&output->base);
-
- return NULL;
-}
-
-void
-destroy_wl_buffer(struct ds_wl_buffer *buffer)
-{
- if (buffer == NULL)
- return;
-
- wl_list_remove(&buffer->buffer_destroy.link);
- wl_list_remove(&buffer->link);
- wl_buffer_destroy(buffer->wl_buffer);
- free(buffer);
-}
-
-void
-output_enter_pointer(struct ds_wl_output *output,
- struct ds_wl_pointer *pointer, uint32_t serial)
-{
- output->cursor.pointer = pointer;
- output->cursor.enter_serial = serial;
-
- output_update_cursor(output);
-}
-
-void
-output_leave_pointer(struct ds_wl_output *output)
-{
- output->cursor.pointer = NULL;
- output->cursor.enter_serial = 0;
-}
-
-static void output_update_cursor(struct ds_wl_output *output)
-{
- struct ds_wl_pointer *pointer = output->cursor.pointer;
-
- wl_pointer_set_cursor(pointer->wl_pointer, output->cursor.enter_serial,
- output->cursor.surface, output->cursor.hotspot_x,
- output->cursor.hotspot_y);
-}
-
-static struct ds_wl_output *
-wl_output_from_output(struct ds_output *ds_output)
-{
- assert(ds_output->iface == &wl_output_iface);
- return (struct ds_wl_output *)ds_output;
-}
-
-static void
-wl_output_iface_destroy(struct ds_output *ds_output)
-{
- struct ds_wl_output *output;
-
- output = wl_output_from_output(ds_output);
-
- ds_dbg("Destroy wayland output(%p)", output);
-
- wl_list_remove(&output->link);
-
- if (output->frame_callback)
- wl_callback_destroy(output->frame_callback);
-
- if (output->xdg_toplevel)
- xdg_toplevel_destroy(output->xdg_toplevel);
-
- if (output->xdg_surface)
- xdg_surface_destroy(output->xdg_surface);
-
- if (output->surface)
- wl_surface_destroy(output->surface);
-
- wl_display_flush(output->backend->server.display);
-
- free(output);
-}
-
-static struct wl_buffer *
-import_shm(struct ds_wl_backend *backend, struct ds_shm_attributes *shm)
-{
- enum wl_shm_format wl_shm_format = WL_SHM_FORMAT_XRGB8888;
- struct wl_shm_pool *pool;
- struct wl_buffer *wl_buffer;
- uint32_t size;
-
- size = shm->stride * shm->height;
- pool = wl_shm_create_pool(backend->server.shm, shm->fd, size);
- if (!pool)
- return NULL;
-
- wl_buffer = wl_shm_pool_create_buffer(pool, shm->offset,
- shm->width, shm->height, shm->stride, wl_shm_format);
- wl_shm_pool_destroy(pool);
-
- return wl_buffer;
-}
-
-static void
-buffer_handle_release(void *data, struct wl_buffer *wl_buffer)
-{
- struct ds_wl_buffer *buffer = data;
-
- ds_dbg("Wayland output: Buffer(%p) released.", buffer->buffer);
- buffer->released = true;
- ds_buffer_unlock(buffer->buffer);
-}
-
-static const struct wl_buffer_listener buffer_listener =
-{
- .release = buffer_handle_release,
-};
-
-static void
-buffer_handle_buffer_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_wl_buffer *buffer;
-
- buffer = wl_container_of(listener, buffer, buffer_destroy);
- destroy_wl_buffer(buffer);
-}
-
-static struct ds_wl_buffer *
-create_wl_buffer(struct ds_wl_backend *backend, struct ds_buffer *ds_buffer)
-{
- struct ds_shm_attributes shm;
- struct ds_wl_buffer *buffer;
- struct wl_buffer *wl_buffer;
-
- if (ds_buffer_get_shm(ds_buffer, &shm)) {
- wl_buffer = import_shm(backend, &shm);
- }
-
- buffer = calloc(1, sizeof *buffer);
- if (!buffer) {
- wl_buffer_destroy(wl_buffer);
- return NULL;
- }
-
- buffer->wl_buffer = wl_buffer;
- buffer->buffer = ds_buffer_lock(ds_buffer);
- wl_list_insert(&backend->buffers, &buffer->link);
-
- wl_buffer_add_listener(wl_buffer, &buffer_listener, buffer);
-
- buffer->buffer_destroy.notify = buffer_handle_buffer_destroy;
- ds_buffer_add_destroy_listener(ds_buffer, &buffer->buffer_destroy);
-
- return buffer;
-}
-
-static struct ds_wl_buffer *
-get_or_create_wl_buffer(struct ds_wl_backend *backend, struct ds_buffer *ds_buffer)
-{
- struct ds_wl_buffer *buffer;
-
- wl_list_for_each(buffer, &backend->buffers, link) {
- if (buffer->buffer == ds_buffer && buffer->released) {
- buffer->released = false;
- ds_buffer_lock(buffer->buffer);
- return buffer;
- }
- }
-
- return create_wl_buffer(backend, ds_buffer);
-}
-
-static void
-surface_frame_callback(void *data, struct wl_callback *cb, uint32_t time)
-{
- struct ds_wl_output *output = data;
-
- wl_callback_destroy(cb);
- output->frame_callback = NULL;
-
- wl_signal_emit(&output->base.events.frame, &output->base);
-}
-
-static const struct wl_callback_listener frame_listener =
-{
- .done = surface_frame_callback
-};
-
-static bool
-wl_output_iface_commit(struct ds_output *ds_output)
-{
- struct ds_wl_output *output;
- struct ds_wl_buffer *buffer;
- struct ds_buffer *ds_buffer;
-
- output = wl_output_from_output(ds_output);
-
- if (ds_output->pending.committed & DS_OUTPUT_STATE_MODE) {
- if (!output_set_custom_mode(ds_output,
- ds_output->pending.custom_mode.width,
- ds_output->pending.custom_mode.height,
- ds_output->pending.custom_mode.refresh))
- return false;
- }
-
- ds_buffer = ds_output->pending.buffer;
- buffer = get_or_create_wl_buffer(output->backend, ds_buffer);
- if (!buffer)
- return NULL;
-
- if (ds_output->pending.committed & DS_OUTPUT_STATE_BUFFER) {
-
- if (output->frame_callback != NULL) {
- ds_err("Skipping buffer swap");
- return false;
- }
-
- output->frame_callback = wl_surface_frame(output->surface);
- wl_callback_add_listener(output->frame_callback, &frame_listener,
- output);
- wl_surface_attach(output->surface, buffer->wl_buffer, 0, 0);
- wl_surface_damage_buffer(output->surface, 0, 0, INT32_MAX, INT32_MAX);
- wl_surface_commit(output->surface);
- }
-
- wl_display_flush(output->backend->server.display);
-
- return true;
-}
-
-const struct ds_output_interface wl_output_iface =
-{
- .destroy = wl_output_iface_destroy,
- .commit = wl_output_iface_commit,
-};
-
-static void
-wl_output_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 wl_output_xdg_surface_listener =
-{
- .configure = wl_output_xdg_surface_handle_configure,
-};
-
-static void
-wl_output_xdg_toplevel_handle_configure(void *data,
- struct xdg_toplevel *xdg_toplevel,
- int32_t width, int32_t height, struct wl_array *states)
-{
- // TODO
- // struct ds_wl_output *output = data;
-
- if (width == 0 || height == 0)
- return;
-}
-
-static void
-wl_output_xdg_toplevel_handle_close(void *data,
- struct xdg_toplevel *xdg_toplevel)
-{
- struct ds_wl_output *output = data;
-
- ds_output_destroy(&output->base);
-}
-
-static const struct xdg_toplevel_listener wl_output_xdg_toplevel_listener =
-{
- .configure = wl_output_xdg_toplevel_handle_configure,
- .close = wl_output_xdg_toplevel_handle_close,
-};
-
-static bool output_set_custom_mode(struct ds_output *ds_output,
- int32_t width, int32_t height, int32_t refresh)
-{
- ds_output_update_custom_mode(ds_output, width, height, 0);
-
- return true;
-}
+++ /dev/null
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <alloca.h>
-#include <sys/mman.h>
-#include <wayland-client.h>
-#include <xkbcommon/xkbcommon.h>
-
-#include "libds/log.h"
-#include "libds/pointer.h"
-#include "libds/touch.h"
-
-#include "util.h"
-#include "backend.h"
-
-#ifdef MIN
-# undef MIN
-#endif
-
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-static const struct wl_seat_listener seat_listener;
-static const struct wl_callback_listener seat_callback_listener;
-
-static void seat_update_capabilities(struct ds_wl_seat *seat,
- enum wl_seat_capability caps);
-static struct ds_input_device *
-create_wl_input_device(struct ds_wl_seat *seat,
- enum ds_input_device_type type);
-static struct ds_pointer *create_wl_pointer(struct ds_wl_seat *seat);
-static struct ds_keyboard *create_wl_keyboard(struct ds_wl_seat *seat);
-static struct ds_touch *create_wl_touch(struct ds_wl_seat *seat);
-
-struct ds_wl_seat *
-create_wl_seat(struct ds_wl_backend *backend, uint32_t id,
- uint32_t available_version)
-{
- struct ds_wl_seat *seat;
-
- seat = calloc(1, sizeof *seat);
- if (!seat)
- return NULL;
-
- seat->backend = backend;
- seat->version = MIN(available_version, 5);
- seat->wl_seat = wl_registry_bind(backend->server.registry, id,
- &wl_seat_interface, seat->version);
-
- wl_seat_add_listener(seat->wl_seat, &seat_listener, seat);
-
- seat->initial_info_cb = wl_display_sync(backend->server.display);
- wl_callback_add_listener(seat->initial_info_cb, &seat_callback_listener,
- seat);
-
- ds_dbg("wl_backend: Seat(%p) created", seat);
-
- return seat;
-}
-
-void
-destroy_wl_seat(struct ds_wl_seat *seat)
-{
- ds_dbg("wl_backend: Seat(%p) destroy", seat);
-
- if (seat->pointer_dev)
- ds_input_device_destroy(seat->pointer_dev);
-
- if (seat->keyboard_dev)
- ds_input_device_destroy(seat->keyboard_dev);
-
- if (seat->touch_dev)
- ds_input_device_destroy(seat->touch_dev);
-
- if (seat->version >= WL_SEAT_RELEASE_SINCE_VERSION)
- wl_seat_release(seat->wl_seat);
- else
- wl_seat_destroy(seat->wl_seat);
-
- wl_list_remove(&seat->link);
-
- free(seat->name);
- free(seat);
-}
-
-static void
-seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
- enum wl_seat_capability caps)
-{
- struct ds_wl_seat *seat = data;
-
- if (seat->initialized)
- seat_update_capabilities(seat, caps);
- else
- seat->caps = caps;
-
- ds_dbg("wl_backend: Seat(%p) capabilities(%d)", seat, caps);
-}
-
-static void
-seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name)
-{
- struct ds_wl_seat *seat = data;
-
- if (seat->name)
- free(seat->name);
-
- ds_dbg("wl_backend: Seat(%p) name(%s)", seat, name);
-
- seat->name = strdup(name);
-}
-
-static const struct wl_seat_listener seat_listener = {
- .capabilities = seat_handle_capabilities,
- .name = seat_handle_name,
-};
-
-static void
-seat_add_callback_handle_done(void *data, struct wl_callback *callback,
- uint32_t callback_data)
-{
- struct ds_wl_seat *seat = data;
-
- wl_callback_destroy(seat->initial_info_cb);
- seat->initial_info_cb = NULL;
- seat->initialized = true;
-
- seat_update_capabilities(seat, seat->caps);
-}
-
-static const struct wl_callback_listener seat_callback_listener = {
- .done = seat_add_callback_handle_done,
-};
-
-static void
-seat_update_capabilities(struct ds_wl_seat *seat, enum wl_seat_capability caps)
-{
- if ((caps & WL_SEAT_CAPABILITY_POINTER) && seat->pointer_dev == NULL) {
- ds_dbg("wl_backend: Seat(%p) offered pointer", seat);
-
- seat->pointer_dev = create_wl_input_device(seat,
- DS_INPUT_DEVICE_POINTER);
- seat->pointer_dev->pointer = create_wl_pointer(seat);
-
- wl_signal_emit(&seat->backend->base.events.new_input,
- seat->pointer_dev);
- }
- else if (!(caps & WL_SEAT_CAPABILITY_POINTER) &&
- seat->pointer_dev != NULL) {
- ds_dbg("wl_backend: Seat(%p) dropped pointer", seat);
- ds_input_device_destroy(seat->pointer_dev);
- seat->pointer_dev = NULL;
- }
-
- if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->keyboard_dev == NULL) {
- ds_dbg("wl_backend: Seat(%p) offered keyboard", seat);
-
- seat->keyboard_dev = create_wl_input_device(seat,
- DS_INPUT_DEVICE_KEYBOARD);
- seat->keyboard_dev->keyboard = create_wl_keyboard(seat);
-
- wl_signal_emit(&seat->backend->base.events.new_input,
- seat->keyboard_dev);
- }
- else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) &&
- seat->keyboard_dev != NULL) {
- ds_dbg("wl_backend: Seat(%p) dropped keyboard", seat);
- ds_input_device_destroy(seat->keyboard_dev);
- seat->keyboard_dev = NULL;
- }
-
- if ((caps & WL_SEAT_CAPABILITY_TOUCH) && seat->touch_dev == NULL) {
- ds_dbg("wl_backend: Seat(%p) offered touch", seat);
- seat->touch_dev = create_wl_input_device(seat,
- DS_INPUT_DEVICE_TOUCH);
- seat->touch_dev->touch = create_wl_touch(seat);
- wl_signal_emit(&seat->backend->base.events.new_input,
- seat->touch_dev);
- }
- else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) &&
- seat->touch_dev != NULL) {
- ds_dbg("wl_backend: Seat(%p) dropped touch", seat);
- ds_input_device_destroy(seat->touch_dev);
- seat->touch_dev = NULL;
- }
-}
-
-static const struct ds_input_device_interface input_device_iface;
-
-static bool
-ds_input_device_is_wl(struct ds_input_device *ds_dev)
-{
- return ds_dev->iface == &input_device_iface;
-}
-
-static struct ds_wl_input_device *
-get_wl_input_device_from_input_device(struct ds_input_device *ds_dev)
-{
- assert(ds_input_device_is_wl(ds_dev));
- return (struct ds_wl_input_device *)ds_dev;
-}
-
-static void
-input_device_iface_destroy(struct ds_input_device *ds_dev)
-{
- struct ds_wl_input_device *dev;
-
- dev = get_wl_input_device_from_input_device(ds_dev);
-
- free(dev);
-}
-
-static const struct ds_input_device_interface input_device_iface =
-{
- .destroy = input_device_iface_destroy,
-};
-
-static struct ds_input_device *
-create_wl_input_device(struct ds_wl_seat *seat,
- enum ds_input_device_type type)
-{
- struct ds_wl_input_device *dev;
- unsigned int vendor = 0, product = 0;
- size_t name_size;
- char *name;
-
- dev = calloc(1, sizeof *dev);
- if (!dev)
- return NULL;
-
- dev->backend = seat->backend;
- dev->seat = seat;
-
- name_size = 8 + strlen(seat->name) + 1;
- name = alloca(name_size);
- (void) snprintf(name, name_size, "wayland-%s", seat->name);
-
- ds_input_device_init(&dev->base, type, &input_device_iface, name, vendor,
- product);
-
- return &dev->base;
-}
-
-static const struct ds_pointer_interface pointer_iface;
-
-static struct ds_wl_pointer *
-get_wl_pointer_from_pointer(struct ds_pointer *ds_pointer)
-{
- assert(ds_pointer->iface == &pointer_iface);
- return (struct ds_wl_pointer *)ds_pointer;
-}
-
-static void
-pointer_iface_destroy(struct ds_pointer *ds_pointer)
-{
- struct ds_wl_pointer *pointer;
-
- pointer = get_wl_pointer_from_pointer(ds_pointer);
-
- wl_pointer_release(pointer->wl_pointer);
-
- free(pointer);
-}
-
-static const struct ds_pointer_interface pointer_iface = {
- .destroy = pointer_iface_destroy,
-};
-
-static void
-pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
- uint32_t serial, struct wl_surface *surface,
- wl_fixed_t sx, wl_fixed_t sy)
-{
- struct ds_wl_seat *seat = data;
- struct ds_wl_pointer *pointer;
-
- if (!surface)
- return;
-
- ds_dbg("Enter pointer");
-
- seat->output = wl_surface_get_user_data(surface);
- seat->enter_serial = serial;
-
- pointer = get_wl_pointer_from_pointer(seat->pointer_dev->pointer);
- output_enter_pointer(seat->output, pointer, seat->enter_serial);
-}
-
-static void
-pointer_handle_leave(void *data, struct wl_pointer *wl_pointer,
- uint32_t serial, struct wl_surface *surface)
-{
- struct ds_wl_seat *seat = data;
- struct ds_wl_output *output;
-
- if (!seat->output)
- return;
-
- output = wl_surface_get_user_data(surface);
- if (seat->output != output)
- return;
-
- ds_dbg("Leave pointer");
-
- output_leave_pointer(seat->output);
-
- seat->output = NULL;
- seat->enter_serial = 0;
-}
-
-static void
-pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
- uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
-{
- struct ds_wl_seat *seat = data;
- struct ds_output *ds_output;
-
- if (!seat->output)
- return;
-
- ds_output = &seat->output->base;
-
- // FIXME take size size of a output into account
- struct ds_event_pointer_motion_absolute event = {
- .device = seat->pointer_dev,
- .time_msec = time,
- .x = wl_fixed_to_double(sx) / ds_output->width,
- .y = wl_fixed_to_double(sy) / ds_output->height,
- };
-
- wl_signal_emit(&seat->pointer_dev->pointer->events.motion_absolute,
- &event);
-}
-
-static void
-pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
- uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
-{
- struct ds_wl_seat *seat = data;
-
- if (!seat->output)
- return;
-
- struct ds_event_pointer_button event = {
- .device = seat->pointer_dev,
- .button = button,
- .state = state,
- .time_msec = time,
- };
-
- wl_signal_emit(&seat->pointer_dev->pointer->events.button, &event);
-}
-
-static void
-pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
- uint32_t time, uint32_t axis, wl_fixed_t value)
-{
- // TODO
-}
-
-static void
-pointer_handle_frame(void *data, struct wl_pointer *wl_pointer)
-{
- struct ds_wl_seat *seat = data;
-
- if (!seat->output)
- return;
-
- wl_signal_emit(&seat->pointer_dev->pointer->events.frame,
- seat->pointer_dev);
-}
-
-static void
-pointer_handle_axis_source(void *data, struct wl_pointer *wl_pointer,
- uint32_t axis_source)
-{
- // TODO
-}
-
-static void
-pointer_handle_axis_stop(void *data, struct wl_pointer *wl_pointer,
- uint32_t time, uint32_t axis)
-{
- // TODO
-}
-
-static void
-pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_pointer,
- uint32_t axis, int32_t discrete)
-{
- // TODO
-}
-
-static const struct wl_pointer_listener wl_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 struct ds_pointer *
-create_wl_pointer(struct ds_wl_seat *seat)
-{
- struct ds_wl_pointer *pointer;
-
- pointer = calloc(1, sizeof *pointer);
- if (!pointer) {
- ds_err("Could not allocate memory");
- return NULL;
- }
-
- ds_pointer_init(&pointer->base, &pointer_iface);
-
- pointer->wl_pointer = wl_seat_get_pointer(seat->wl_seat);
- wl_pointer_add_listener(pointer->wl_pointer, &wl_pointer_listener, seat);
-
- return &pointer->base;
-}
-
-static const struct ds_keyboard_interface keyboard_iface;
-
-static struct ds_wl_keyboard *
-get_wl_keyboard_from_keyboard(struct ds_keyboard *ds_keyboard)
-{
- assert(ds_keyboard->iface == &keyboard_iface);
- return (struct ds_wl_keyboard *)ds_keyboard;
-}
-
-static void
-keyboard_iface_destroy(struct ds_keyboard *ds_keyboard)
-{
- struct ds_wl_keyboard *keyboard;
-
- keyboard = get_wl_keyboard_from_keyboard(ds_keyboard);
-
- wl_keyboard_release(keyboard->wl_keyboard);
-
- free(keyboard);
-}
-
-static const struct ds_keyboard_interface keyboard_iface = {
- .destroy = keyboard_iface_destroy,
-};
-
-static void
-keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
- uint32_t format, int fd, uint32_t size)
-{
- struct ds_wl_seat *seat = data;
- struct xkb_context *context;
- struct xkb_keymap *keymap;
- char *map_str;
-
- ds_dbg("wl_keyboard: keymap");
-
- if (format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
- map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
- if (map_str == MAP_FAILED) {
- ds_log_errno(DS_ERR, "mmap failed");
- goto end;
- }
-
- context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
- keymap = xkb_keymap_new_from_string(context, map_str,
- XKB_KEYMAP_FORMAT_TEXT_V1, 0);
- munmap(map_str, size);
-
- if (!keymap) {
- ds_err("Failed to compile keymap");
- goto end;
- }
-
- ds_keyboard_set_keymap(seat->keyboard_dev->keyboard, keymap);
-
- xkb_keymap_unref(keymap);
- xkb_context_unref(context);
- }
-
- // TODO More case?
-
-end:
- close(fd);
-}
-
-static void
-keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard,
- uint32_t serial, struct wl_surface *surface, struct wl_array *keys)
-{
- struct ds_wl_seat *seat = data;
- uint32_t *keycode_ptr;
- uint32_t time;
-
- ds_dbg("wl_keyboard: enter");
-
- time = get_current_time_msec();
-
- wl_array_for_each(keycode_ptr, keys) {
- struct ds_event_keyboard_key event = {
- .keycode = *keycode_ptr,
- .state = WL_KEYBOARD_KEY_STATE_PRESSED,
- .time_msec = time,
- .update_state = false,
- };
-
- ds_keyboard_notify_key(seat->keyboard_dev->keyboard, &event);
- }
-}
-
-static void
-keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
- uint32_t serial, struct wl_surface *surface)
-{
- struct ds_wl_seat *seat = data;
- struct ds_keyboard *keyboard = seat->keyboard_dev->keyboard;
- uint32_t *pressed;
- uint32_t time, keycode;
- size_t num_keycodes;
-
- ds_dbg("wl_keyboard: leave");
-
- time = get_current_time_msec();
-
- num_keycodes = keyboard->num_keycodes;
- pressed = alloca(num_keycodes + 1);
- memcpy(pressed, keyboard->keycodes, num_keycodes * sizeof(uint32_t));
-
- for (size_t i = 0; i < num_keycodes; i++) {
- keycode = pressed[i];
-
- struct ds_event_keyboard_key event = {
- .keycode = keycode,
- .state = WL_KEYBOARD_KEY_STATE_RELEASED,
- .time_msec = time,
- .update_state = false,
- };
-
- ds_keyboard_notify_key(keyboard, &event);
- }
-}
-
-static void
-keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
- uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
-{
- struct ds_wl_seat *seat = data;
-
- ds_dbg("wl_keyboard: key");
-
- struct ds_event_keyboard_key event = {
- .keycode = key,
- .state = state,
- .time_msec = time,
- .update_state = false,
- };
-
- ds_keyboard_notify_key(seat->keyboard_dev->keyboard, &event);
-}
-
-static void
-keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
- uint32_t serial_in, uint32_t mods_depressed, uint32_t mods_latched,
- uint32_t mods_locked, uint32_t group)
-{
- struct ds_wl_seat *seat = data;
-
- ds_dbg("wl_keyboard: modifiers");
-
- ds_keyboard_notify_modifiers(seat->keyboard_dev->keyboard,
- mods_depressed, mods_latched, mods_locked, group);
-}
-
-static void
-keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard,
- int32_t rate, int32_t delay)
-{
- ds_dbg("wl_keyboard: repeat_info");
-
- // This space is intentionally left blank
-}
-
-static const struct wl_keyboard_listener wl_keyboard_listener = {
- .keymap = keyboard_handle_keymap,
- .enter = keyboard_handle_enter,
- .leave = keyboard_handle_leave,
- .key = keyboard_handle_key,
- .modifiers = keyboard_handle_modifiers,
- .repeat_info = keyboard_handle_repeat_info,
-};
-
-static struct ds_keyboard *
-create_wl_keyboard(struct ds_wl_seat *seat)
-{
- struct ds_wl_keyboard *keyboard;
-
- keyboard = calloc(1, sizeof *keyboard);
- if (!keyboard)
- return NULL;
-
- ds_keyboard_init(&keyboard->base, &keyboard_iface);
-
- keyboard->wl_keyboard = wl_seat_get_keyboard(seat->wl_seat);
- wl_keyboard_add_listener(keyboard->wl_keyboard,
- &wl_keyboard_listener, seat);
-
- return &keyboard->base;
-}
-
-static const struct ds_touch_interface touch_iface;
-
-static struct ds_wl_touch *
-get_wl_touch_from_touch(struct ds_touch *ds_touch)
-{
- assert(ds_touch->iface == &touch_iface);
- return (struct ds_wl_touch *)ds_touch;
-}
-
-static void
-touch_iface_destroy(struct ds_touch *ds_touch)
-{
- struct ds_wl_touch *touch;
-
- touch = get_wl_touch_from_touch(ds_touch);
-
- wl_touch_release(touch->wl_touch);
-
- free(touch);
-}
-
-static const struct ds_touch_interface touch_iface = {
- .destroy = touch_iface_destroy,
-};
-
-static void
-touch_handle_down(void *data, struct wl_touch *wl_touch,
- uint32_t serial, uint32_t time,
- struct wl_surface *surface, int32_t id,
- wl_fixed_t fixed_x, wl_fixed_t fixed_y)
-{
- struct ds_wl_seat *seat = data;
-
- ds_dbg("wl_touch: down");
-
- struct ds_event_touch_down event = {
- .device = seat->touch_dev,
- .id = id,
- .x = fixed_x,
- .y = fixed_y,
- };
-
- wl_signal_emit(&seat->touch_dev->touch->events.down, &event);
-}
-
-static void
-touch_handle_up(void *data, struct wl_touch *wl_touch,
- uint32_t serial, uint32_t time, int32_t id)
-{
- struct ds_wl_seat *seat = data;
-
- ds_dbg("wl_touch: up");
-
- struct ds_event_touch_up event = {
- .device = seat->touch_dev,
- .id = id,
- };
-
- wl_signal_emit(&seat->touch_dev->touch->events.up, &event);
-}
-
-static void
-touch_handle_motion(void *data, struct wl_touch *wl_touch,
- uint32_t time, int32_t id,
- wl_fixed_t fixed_x, wl_fixed_t fixed_y)
-{
- ds_dbg("wl_touch: motion");
-}
-
-static void
-touch_handle_frame(void *data, struct wl_touch *wl_touch)
-{
- ds_dbg("wl_touch: frame");
-}
-
-static void
-touch_handle_cancel(void *data, struct wl_touch *wl_touch)
-{
- ds_dbg("wl_touch: cancel");
-}
-
-static const struct wl_touch_listener wl_touch_listener = {
- .down = touch_handle_down,
- .up = touch_handle_up,
- .motion = touch_handle_motion,
- .frame = touch_handle_frame,
- .cancel = touch_handle_cancel,
-};
-
-static struct ds_touch *
-create_wl_touch(struct ds_wl_seat *seat)
-{
- struct ds_wl_touch *touch;
-
- touch = calloc(1, sizeof *touch);
- if (!touch) {
- ds_err("Could not allocate memory");
- return NULL;
- }
-
- ds_touch_init(&touch->base, &touch_iface);
-
- touch->wl_touch = wl_seat_get_touch(seat->wl_seat);
- wl_touch_add_listener(touch->wl_touch, &wl_touch_listener, seat);
-
- return &touch->base;
-}
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-#include "libds/interfaces/buffer.h"
-
-#include "buffer.h"
-#include "client_buffer.h"
-
-static struct wl_array buffer_resource_interfaces = {0};
-
-static void buffer_consider_destroy(struct ds_buffer *buffer);
-static bool ds_resource_is_buffer(struct wl_resource *resource);
-static const struct ds_buffer_resource_interface *
-get_buffer_resource_iface(struct wl_resource *resource);
-
-WL_EXPORT void
-ds_buffer_init(struct ds_buffer *buffer,
- const struct ds_buffer_interface *iface, int width, int height)
-{
- buffer->iface = iface;
- buffer->width = width;
- buffer->height = height;
-
- wl_signal_init(&buffer->events.destroy);
- wl_signal_init(&buffer->events.release);
-}
-
-WL_EXPORT struct ds_buffer *
-ds_buffer_from_resource(struct wl_resource *resource)
-{
- struct ds_buffer *buffer;
- const struct ds_buffer_resource_interface *iface;
-
- assert(resource && ds_resource_is_buffer(resource));
-
- if (wl_shm_buffer_get(resource) != NULL) {
- struct ds_shm_client_buffer *shm_client_buffer =
- ds_shm_client_buffer_get_or_create(resource);
- if (!shm_client_buffer) {
- ds_err("Failed to create shm client buffer");
- return NULL;
- }
-
- buffer = ds_buffer_lock(&shm_client_buffer->base);
- }
- else {
- iface = get_buffer_resource_iface(resource);
- if (!iface) {
- ds_err("Unknown buffer type");
- return NULL;
- }
-
- buffer = iface->from_resource(resource);
- if (!buffer) {
- ds_err("Failed to create %s buffer", iface->name);
- return NULL;
- }
-
- buffer = ds_buffer_lock(buffer);
- }
-
- return buffer;
-}
-
-WL_EXPORT void
-ds_buffer_drop(struct ds_buffer *buffer)
-{
- assert(!buffer->dropped);
- buffer->dropped = true;
- ds_dbg("Buffer(%p) dropped: n_locks(%zu)", buffer, buffer->n_locks);
- buffer_consider_destroy(buffer);
-}
-
-WL_EXPORT struct ds_buffer *
-ds_buffer_lock(struct ds_buffer *buffer)
-{
- buffer->n_locks++;
- ds_dbg("Buffer(%p) n_locks(%zu)", buffer, buffer->n_locks);
- return buffer;
-}
-
-WL_EXPORT void
-ds_buffer_unlock(struct ds_buffer *buffer)
-{
- assert(buffer->n_locks > 0);
- buffer->n_locks--;
- ds_dbg("Buffer(%p) n_locks(%zu)", buffer, buffer->n_locks);
-
- if (buffer->n_locks == 0)
- wl_signal_emit(&buffer->events.release, NULL);
-
- buffer_consider_destroy(buffer);
-}
-
-WL_EXPORT bool
-ds_buffer_begin_data_ptr_access(struct ds_buffer *buffer, uint32_t flags,
- void **data, uint32_t *format, size_t *stride)
-{
- assert(!buffer->accessing_data_ptr);
- if (!buffer->iface->begin_data_ptr_access)
- return false;
- if (!buffer->iface->begin_data_ptr_access(buffer,
- flags, data, format, stride))
- return false;
- buffer->accessing_data_ptr = true;
- return true;
-}
-
-WL_EXPORT void
-ds_buffer_end_data_ptr_access(struct ds_buffer *buffer)
-{
- assert(buffer->accessing_data_ptr);
- buffer->iface->end_data_ptr_access(buffer);
- buffer->accessing_data_ptr = false;
-}
-
-WL_EXPORT void
-ds_buffer_add_destroy_listener(struct ds_buffer *buffer,
- struct wl_listener *listener)
-{
- wl_signal_add(&buffer->events.destroy, listener);
-}
-
-void
-ds_buffer_add_release_listener(struct ds_buffer *buffer,
- struct wl_listener *listener)
-{
- wl_signal_add(&buffer->events.release, listener);
-}
-
-WL_EXPORT bool
-ds_buffer_get_shm(struct ds_buffer *buffer, struct ds_shm_attributes *attribs)
-{
- if (!buffer->iface->get_shm)
- return false;
-
- return buffer->iface->get_shm(buffer, attribs);
-}
-
-WL_EXPORT void
-ds_buffer_get_size(struct ds_buffer *buffer, int *out_width, int *out_height)
-{
- if (out_width)
- *out_width = buffer->width;
- if (out_height)
- *out_height = buffer->height;
-}
-
-WL_EXPORT void
-ds_buffer_register_resource_interface(
- const struct ds_buffer_resource_interface *iface)
-{
- const struct ds_buffer_resource_interface **iface_ptr;
-
- assert(iface);
- assert(iface->is_instance);
- assert(iface->from_resource);
-
- wl_array_for_each(iface_ptr, &buffer_resource_interfaces) {
- if (*iface_ptr == iface) {
- ds_dbg("ds_buffer_resource_interface %s has already "
- "been registered", iface->name);
- return;
- }
- }
-
- iface_ptr = wl_array_add(&buffer_resource_interfaces, sizeof(iface));
- *iface_ptr = iface;
-}
-
-static void
-buffer_consider_destroy(struct ds_buffer *buffer)
-{
- if (!buffer->dropped || buffer->n_locks > 0)
- return;
-
- assert(!buffer->accessing_data_ptr);
-
- wl_signal_emit(&buffer->events.destroy, NULL);
- buffer->iface->destroy(buffer);
-}
-
-static bool
-ds_resource_is_buffer(struct wl_resource *resource)
-{
- return strcmp(wl_resource_get_class(resource),
- wl_buffer_interface.name) == 0;
-}
-
-static const struct ds_buffer_resource_interface *
-get_buffer_resource_iface(struct wl_resource *resource)
-{
- struct ds_buffer_resource_interface **iface_ptr;
-
- wl_array_for_each(iface_ptr, &buffer_resource_interfaces) {
- if ((*iface_ptr)->is_instance(resource)) {
- return *iface_ptr;
- }
- }
-
- return NULL;
-}
+++ /dev/null
-#ifndef DS_BUFFER_H
-#define DS_BUFFER_H
-
-#include <wayland-server.h>
-
-#include "libds/buffer.h"
-
-#endif
+++ /dev/null
-#ifndef DS_CLIENT_BUFFER_H
-#define DS_CLIENT_BUFFER_H
-
-#include <wayland-server.h>
-
-#include "libds/buffer.h"
-#include "libds/interfaces/buffer.h"
-
-#include "util.h"
-
-struct ds_shm_client_buffer
-{
- struct ds_buffer base;
-
- uint32_t format;
- size_t stride;
-
- struct wl_resource *resource;
- struct wl_shm_buffer *shm_buffer;
-
- struct {
- struct wl_listener buffer_release;
- struct wl_listener resource_destroy;
- } listener;
-};
-
-struct ds_shm_client_buffer *
-ds_shm_client_buffer_get_or_create(struct wl_resource *resource);
-
-#endif
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#include <drm_fourcc.h>
-
-#include "libds/log.h"
-
-#include "pixel_format.h"
-#include "buffer.h"
-#include "client_buffer.h"
-
-static void
-shm_client_buffer_resource_handle_destroy(struct wl_listener *listener,
- void *data);
-static struct ds_shm_client_buffer *
-shm_client_buffer_create(struct wl_resource *resource);
-
-struct ds_shm_client_buffer *
-ds_shm_client_buffer_get_or_create(struct wl_resource *resource)
-{
- struct ds_shm_client_buffer *buffer;
- struct wl_listener *resource_destroy_listener;
-
- resource_destroy_listener = wl_resource_get_destroy_listener(resource,
- shm_client_buffer_resource_handle_destroy);
- if (resource_destroy_listener) {
- buffer = wl_container_of(resource_destroy_listener,
- buffer, listener.resource_destroy);
- return buffer;
- }
-
- return shm_client_buffer_create(resource);
-}
-
-static void
-shm_client_buffer_resource_handle_destroy(struct wl_listener *listener,
- void *data)
-{
- struct ds_shm_client_buffer *buffer;
-
- buffer = wl_container_of(listener, buffer, listener.resource_destroy);
- buffer->resource = NULL;
- buffer->shm_buffer = NULL;
- wl_list_remove(&buffer->listener.resource_destroy.link);
- wl_list_init(&buffer->listener.resource_destroy.link);
-
- ds_buffer_drop(&buffer->base);
-}
-
-static const struct ds_buffer_interface shm_client_buffer_iface;
-
-static struct ds_shm_client_buffer *
-shm_client_buffer_from_buffer(struct ds_buffer *buffer)
-{
- assert(buffer->iface == &shm_client_buffer_iface);
- return (struct ds_shm_client_buffer *)buffer;
-}
-
-static void
-shm_client_buffer_destroy(struct ds_buffer *ds_buffer)
-{
- struct ds_shm_client_buffer *buffer;
-
- buffer = shm_client_buffer_from_buffer(ds_buffer);
-
- ds_dbg("Destroy shm client buffer(%p)", buffer);
-
- wl_list_remove(&buffer->listener.resource_destroy.link);
- wl_list_remove(&buffer->listener.buffer_release.link);
- free(buffer);
-}
-
-static bool
-shm_client_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer,
- enum ds_buffer_data_ptr_access_flag flags, void **data,
- uint32_t *format, size_t *stride)
-{
- struct ds_shm_client_buffer *buffer;
-
- buffer = shm_client_buffer_from_buffer(ds_buffer);
- *format = buffer->format;
- *stride = buffer->stride;
- if (buffer->shm_buffer) {
- *data = wl_shm_buffer_get_data(buffer->shm_buffer);
- wl_shm_buffer_begin_access(buffer->shm_buffer);
- }
- else {
- return false;
- }
-
- return true;
-}
-
-static void
-shm_client_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer)
-{
- struct ds_shm_client_buffer *buffer;
-
- buffer = shm_client_buffer_from_buffer(ds_buffer);
- if (buffer->shm_buffer)
- wl_shm_buffer_end_access(buffer->shm_buffer);
-}
-
-static const struct ds_buffer_interface shm_client_buffer_iface =
-{
- .destroy = shm_client_buffer_destroy,
- .begin_data_ptr_access = shm_client_buffer_begin_data_ptr_access,
- .end_data_ptr_access = shm_client_buffer_end_data_ptr_access,
-};
-
-static void
-shm_client_buffer_handle_release(struct wl_listener *listener, void *data)
-{
- struct ds_shm_client_buffer *buffer;
-
- buffer = wl_container_of(listener, buffer, listener.buffer_release);
- if (buffer->resource)
- wl_buffer_send_release(buffer->resource);
-}
-
-static struct ds_shm_client_buffer *
-shm_client_buffer_create(struct wl_resource *resource)
-{
- struct ds_shm_client_buffer *buffer;
- struct wl_shm_buffer *shm_buffer;
- enum wl_shm_format wl_shm_format;
- int32_t width;
- int32_t height;
-
- shm_buffer = wl_shm_buffer_get(resource);
- width = wl_shm_buffer_get_width(shm_buffer);
- height = wl_shm_buffer_get_height(shm_buffer);
-
- buffer = calloc(1, sizeof(*buffer));
- if (!buffer)
- return NULL;
-
- ds_buffer_init(&buffer->base, &shm_client_buffer_iface, width, height);
-
- buffer->resource = resource;
- buffer->shm_buffer = shm_buffer;
-
- wl_shm_format = wl_shm_buffer_get_format(shm_buffer);
- buffer->format = convert_wl_shm_format_to_drm(wl_shm_format);
- buffer->stride = wl_shm_buffer_get_stride(shm_buffer);
-
- buffer->listener.buffer_release.notify =
- shm_client_buffer_handle_release;
- ds_buffer_add_release_listener(&buffer->base,
- &buffer->listener.buffer_release);
-
- buffer->listener.resource_destroy.notify =
- shm_client_buffer_resource_handle_destroy;
- wl_resource_add_destroy_listener(resource,
- &buffer->listener.resource_destroy);
-
- ds_dbg("Shm client buffer(%p) created", buffer);
-
- return buffer;
-}
+++ /dev/null
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-
-#include "subcompositor.h"
-#include "surface.h"
-#include "region.h"
-
-#define COMPOSITOR_VERSION 4
-
-struct ds_compositor
-{
- struct wl_global *global;
- struct ds_subcompositor subcompositor;
-
- struct {
- struct wl_signal new_surface;
- struct wl_signal destroy;
- } events;
-
- struct wl_listener display_destroy;
-};
-
-static void compositor_bind(struct wl_client *client, void *data,
- uint32_t version, uint32_t id);
-static void compositor_handle_display_destroy(struct wl_listener *listener,
- void *data);
-
-WL_EXPORT struct ds_compositor *
-ds_compositor_create(struct wl_display *display)
-{
- struct ds_compositor *compositor;
-
- compositor = calloc(1, sizeof *compositor);
- if (!compositor) {
- ds_log_errno(DS_ERR, "Could not allocate memory");
- return NULL;
- }
-
- compositor->global = wl_global_create(display, &wl_compositor_interface,
- COMPOSITOR_VERSION, compositor, compositor_bind);
- if (!compositor->global) {
- ds_log_errno(DS_ERR, "Could not create global");
- goto err_global;
- }
-
- if (!ds_subcompositor_init(&compositor->subcompositor, display)) {
- ds_err("Could not initialize subcompositor");
- goto err_subcomp;
- }
-
- wl_signal_init(&compositor->events.new_surface);
- wl_signal_init(&compositor->events.destroy);
-
- compositor->display_destroy.notify = compositor_handle_display_destroy;
- wl_display_add_destroy_listener(display, &compositor->display_destroy);
-
- ds_inf("Compositor(%p) created", compositor);
-
- return compositor;
-
-err_subcomp:
- wl_global_destroy(compositor->global);
-err_global:
- free(compositor);
-
- return NULL;
-}
-
-WL_EXPORT void
-ds_compositor_add_new_surface_listener(struct ds_compositor *compositor,
- struct wl_listener *listener)
-{
- wl_signal_add(&compositor->events.new_surface, listener);
-}
-
-WL_EXPORT void
-ds_compositor_add_destroy_listener(struct ds_compositor *compositor,
- struct wl_listener *listener)
-{
- wl_signal_add(&compositor->events.destroy, listener);
-}
-
-static void
-compositor_handle_create_surface(struct wl_client *client,
- struct wl_resource *resource, uint32_t id)
-{
- struct ds_compositor *compositor;
- struct ds_surface *surface;
-
- compositor = wl_resource_get_user_data(resource);
- surface = ds_surface_create(client,
- wl_resource_get_version(resource), id);
- if (!surface) {
- ds_err("Could not create ds_surface");
- return;
- }
-
- wl_signal_emit(&compositor->events.new_surface, surface);
-}
-
-static void
-compositor_handle_create_region(struct wl_client *client,
- struct wl_resource *resource, uint32_t id)
-{
- ds_region_add(client, wl_resource_get_version(resource), id);
-}
-
-static const struct wl_compositor_interface compositor_impl =
-{
- .create_surface = compositor_handle_create_surface,
- .create_region = compositor_handle_create_region,
-};
-
-static void compositor_bind(struct wl_client *client, void *data,
- uint32_t version, uint32_t id)
-{
- struct ds_compositor *compositor = data;
- struct wl_resource *resource;
-
- resource = wl_resource_create(client, &wl_compositor_interface,
- version, id);
- if (resource == NULL) {
- wl_client_post_no_memory(client);
- return;
- }
-
- wl_resource_set_implementation(resource, &compositor_impl,
- compositor, NULL);
-}
-
-static void
-compositor_handle_display_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_compositor *compositor;
-
- compositor = wl_container_of(listener, compositor, display_destroy);
-
- ds_dbg("Destroy compositor(%p)", compositor);
-
- wl_signal_emit(&compositor->events.destroy, compositor);
-
- wl_list_remove(&compositor->display_destroy.link);
- ds_subcompositor_finish(&compositor->subcompositor);
- free(compositor);
-}
+++ /dev/null
-#define _POSIX_C_SOURCE 200809L
-#include <stdlib.h>
-#include <string.h>
-#include <wayland-server.h>
-
-#include "libds/log.h"
-#include "libds/interfaces/input_device.h"
-#include "libds/interfaces/pointer.h"
-#include "libds/interfaces/keyboard.h"
-#include "libds/interfaces/touch.h"
-
-WL_EXPORT enum ds_input_device_type
-ds_input_device_get_type(struct ds_input_device *dev)
-{
- return dev->type;
-}
-
-WL_EXPORT const char *
-ds_input_device_get_name(struct ds_input_device *dev)
-{
- return dev->name;
-}
-
-WL_EXPORT struct ds_pointer *
-ds_input_device_get_pointer(struct ds_input_device *dev)
-{
- if (dev->type != DS_INPUT_DEVICE_POINTER) {
- ds_err("Given ds_input_device is not a pointer device");
- return NULL;
- }
-
- return dev->pointer;
-}
-
-WL_EXPORT struct ds_keyboard *
-ds_input_device_get_keyboard(struct ds_input_device *dev)
-{
- if (dev->type != DS_INPUT_DEVICE_KEYBOARD) {
- ds_err("Given ds_input_device is not a keyboard device");
- return NULL;
- }
-
- return dev->keyboard;
-}
-
-WL_EXPORT struct ds_touch *
-ds_input_device_get_touch(struct ds_input_device *dev)
-{
- if (dev->type != DS_INPUT_DEVICE_TOUCH) {
- ds_err("Given ds_input_device is not a touch device");
- return NULL;
- }
-
- return dev->touch;
-}
-
-WL_EXPORT void
-ds_input_device_add_destroy_listener(struct ds_input_device *dev,
- struct wl_listener *listener)
-{
- wl_signal_add(&dev->events.destroy, listener);
-}
-
-void
-ds_input_device_init(struct ds_input_device *dev,
- enum ds_input_device_type type,
- const struct ds_input_device_interface *iface,
- const char *name, int vendor, int product)
-{
- dev->type = type;
- dev->iface = iface;
- dev->name = strdup(name);
-
- wl_signal_init(&dev->events.destroy);
-}
-
-void
-ds_input_device_destroy(struct ds_input_device *dev)
-{
- wl_signal_emit(&dev->events.destroy, dev);
-
- if (dev->_device) {
- switch (dev->type) {
- case DS_INPUT_DEVICE_POINTER:
- ds_pointer_destroy(dev->pointer);
- break;
- case DS_INPUT_DEVICE_KEYBOARD:
- ds_keyboard_destroy(dev->keyboard);
- break;
- case DS_INPUT_DEVICE_TOUCH:
- ds_touch_destroy(dev->touch);
- break;
- default:
- ds_err("Warning: leaking memory %p %p %d",
- dev->_device, dev, dev->type);
- break;
- }
- }
-
- free(dev->name);
- if (dev->iface && dev->iface->destroy)
- dev->iface->destroy(dev);
- else
- free(dev);
-}
+++ /dev/null
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/mman.h>
-
-#include <wayland-server.h>
-
-#include "libds/log.h"
-#include "libds/interfaces/keyboard.h"
-#include "util.h"
-
-static bool keyboard_modifier_update(struct ds_keyboard *keyboard);
-static void keyboard_key_update(struct ds_keyboard *keyboard,
- struct ds_event_keyboard_key *event);
-static void keyboard_led_update(struct ds_keyboard *keyboard);
-
-WL_EXPORT bool
-ds_keyboard_set_keymap(struct ds_keyboard *keyboard, struct xkb_keymap *keymap)
-{
- char *tmp_keymap_string;
- void *dst;
- int rw_fd, ro_fd;
- xkb_keycode_t keycode;
- const char *led_names[DS_LED_COUNT] = {
- XKB_LED_NAME_NUM,
- XKB_LED_NAME_CAPS,
- XKB_LED_NAME_SCROLL,
- };
- const char *mod_names[DS_MODIFIER_COUNT] = {
- XKB_MOD_NAME_SHIFT,
- XKB_MOD_NAME_CAPS,
- XKB_MOD_NAME_CTRL,
- XKB_MOD_NAME_ALT,
- XKB_MOD_NAME_NUM,
- "Mod3",
- XKB_MOD_NAME_LOGO,
- "Mod5",
- };
-
- if (keyboard->keymap)
- xkb_keymap_unref(keyboard->keymap);
-
- keyboard->keymap = xkb_keymap_ref(keymap);
-
- if (keyboard->xkb_state)
- xkb_state_unref(keyboard->xkb_state);
-
- keyboard->xkb_state = xkb_state_new(keyboard->keymap);
- if (!keyboard->xkb_state) {
- ds_err("Failed to create XKB state");
- goto err_state;
- }
-
- for (size_t i = 0; i < DS_LED_COUNT; i++) {
- keyboard->led_indexes[i] =
- xkb_map_led_get_index(keyboard->keymap, led_names[i]);
- }
-
- for (size_t i = 0; i < DS_MODIFIER_COUNT; i++) {
- keyboard->mod_indexes[i] =
- xkb_map_mod_get_index(keyboard->keymap, mod_names[i]);
- }
-
- tmp_keymap_string = xkb_keymap_get_as_string(keyboard->keymap,
- XKB_KEYMAP_FORMAT_TEXT_V1);
- if (!tmp_keymap_string) {
- ds_err("Failed to get string version of keymap");
- goto err_keymap_string;
- }
-
- if (keyboard->keymap_string)
- free(keyboard->keymap_string);
- keyboard->keymap_string = tmp_keymap_string;
- keyboard->keymap_size = strlen(keyboard->keymap_string) + 1;
-
- if (!allocate_shm_file_pair(keyboard->keymap_size, &rw_fd, &ro_fd)) {
- ds_err("Failed to allocate shm_file for keymap");
- goto err_shm_file;
- }
-
- dst = mmap(NULL, keyboard->keymap_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, rw_fd, 0);
- if (dst == MAP_FAILED) {
- ds_log_errno(DS_ERR, "mmap failed");
- goto err_mmap;
- }
-
- memcpy(dst, keyboard->keymap_string, keyboard->keymap_size);
- munmap(dst, keyboard->keymap_size);
- close(rw_fd);
-
- if (keyboard->keymap_fd >= 0)
- close(keyboard->keymap_fd);
- keyboard->keymap_fd = ro_fd;
-
- for (size_t i = 0; i < keyboard->num_keycodes; i++) {
- keycode = keyboard->keycodes[i] + 8;
- xkb_state_update_key(keyboard->xkb_state, keycode, XKB_KEY_DOWN);
- }
-
- keyboard_modifier_update(keyboard);
-
- wl_signal_emit(&keyboard->events.keymap, keyboard);
-
- return true;
-
-err_mmap:
- close(rw_fd);
- close(ro_fd);
-err_shm_file:
- free(keyboard->keymap_string);
- keyboard->keymap_string = NULL;
-err_keymap_string:
- xkb_state_unref(keyboard->xkb_state);
- keyboard->xkb_state = NULL;
-err_state:
- xkb_keymap_unref(keymap);
- keyboard->keymap = NULL;
-
- return false;
-}
-
-WL_EXPORT void
-ds_keyboard_set_repeat_info(struct ds_keyboard *keyboard,
- int32_t rate, int32_t delay)
-{
- if (keyboard->repeat_info.rate == rate &&
- keyboard->repeat_info.delay == delay)
- return;
- keyboard->repeat_info.rate = rate;
- keyboard->repeat_info.delay = delay;
-
- wl_signal_emit(&keyboard->events.repeat_info, keyboard);
-}
-
-WL_EXPORT uint32_t
-ds_keyboard_get_modifiers(struct ds_keyboard *keyboard)
-{
- xkb_mod_mask_t mask;
- uint32_t modifiers = 0;
-
- mask = keyboard->modifiers.depressed | keyboard->modifiers.latched;
- for (size_t i = 0; i < DS_MODIFIER_COUNT; i++) {
- if (keyboard->mod_indexes[i] != XKB_MOD_INVALID &&
- (mask & (1 << keyboard->mod_indexes[i])))
- modifiers |= (1 << i);
- }
-
- return modifiers;
-}
-
-WL_EXPORT struct xkb_state *
-ds_keyboard_get_xkb_state(struct ds_keyboard *keyboard)
-{
- return keyboard->xkb_state;
-}
-
-WL_EXPORT void
-ds_keyboard_notify_key(struct ds_keyboard *keyboard,
- struct ds_event_keyboard_key *event)
-{
- uint32_t keycode;
- enum xkb_key_direction dir;
- bool updated;
-
- keyboard_key_update(keyboard, event);
-
- wl_signal_emit(&keyboard->events.key, event);
-
- if (!keyboard->xkb_state)
- return;
-
- if (event->update_state) {
- keycode = event->keycode + 8;
- dir = (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) ?
- XKB_KEY_DOWN : XKB_KEY_UP;
- xkb_state_update_key(keyboard->xkb_state, keycode, dir);
- }
-
- updated = keyboard_modifier_update(keyboard);
- if (updated)
- wl_signal_emit(&keyboard->events.modifiers, keyboard);
-
- keyboard_led_update(keyboard);
-}
-
-WL_EXPORT void
-ds_keyboard_notify_modifiers(struct ds_keyboard *keyboard,
- uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked,
- uint32_t group)
-{
- bool updated;
-
- if (!keyboard->xkb_state)
- return;
-
- xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched,
- mods_locked, 0, 0, group);
-
- updated = keyboard_modifier_update(keyboard);
- if (updated)
- wl_signal_emit(&keyboard->events.modifiers, keyboard);
-
- keyboard_led_update(keyboard);
-}
-
-WL_EXPORT void
-ds_keyboard_add_destroy_listener(struct ds_keyboard *keyboard,
- struct wl_listener *listener)
-{
- wl_signal_add(&keyboard->events.destroy, listener);
-}
-
-WL_EXPORT void
-ds_keyboard_add_key_listener(struct ds_keyboard *keyboard,
- struct wl_listener *listener)
-{
- wl_signal_add(&keyboard->events.key, listener);
-}
-
-WL_EXPORT void
-ds_keyboard_add_modifiers_listener(struct ds_keyboard *keyboard,
- struct wl_listener *listener)
-{
- wl_signal_add(&keyboard->events.modifiers, listener);
-}
-
-WL_EXPORT void
-ds_keyboard_add_keymap_listener(struct ds_keyboard *keyboard,
- struct wl_listener *listener)
-{
- wl_signal_add(&keyboard->events.keymap, listener);
-}
-
-WL_EXPORT void
-ds_keyboard_add_repeat_info_listener(struct ds_keyboard *keyboard,
- struct wl_listener *listener)
-{
- wl_signal_add(&keyboard->events.repeat_info, listener);
-}
-
-void
-ds_keyboard_init(struct ds_keyboard *keyboard,
- const struct ds_keyboard_interface *iface)
-{
- keyboard->iface = iface;
- keyboard->keymap_fd = -1;
-
- wl_signal_init(&keyboard->events.destroy);
- wl_signal_init(&keyboard->events.key);
- wl_signal_init(&keyboard->events.modifiers);
- wl_signal_init(&keyboard->events.keymap);
- wl_signal_init(&keyboard->events.repeat_info);
-}
-
-void
-ds_keyboard_destroy(struct ds_keyboard *keyboard)
-{
- if (keyboard->iface && keyboard->iface->destroy)
- keyboard->iface->destroy(keyboard);
- else
- free(keyboard);
-}
-
-static bool
-keyboard_modifier_update(struct ds_keyboard *keyboard)
-{
- xkb_mod_mask_t depressed, latched, locked, group;
-
- if (!keyboard->xkb_state)
- return false;
-
- depressed = xkb_state_serialize_mods(keyboard->xkb_state,
- XKB_STATE_MODS_DEPRESSED);
- latched = xkb_state_serialize_mods(keyboard->xkb_state,
- XKB_STATE_MODS_LATCHED);
- locked = xkb_state_serialize_mods(keyboard->xkb_state,
- XKB_STATE_MODS_LOCKED);
- group = xkb_state_serialize_layout(keyboard->xkb_state,
- XKB_STATE_LAYOUT_EFFECTIVE);
- if (depressed == keyboard->modifiers.depressed &&
- latched == keyboard->modifiers.latched &&
- locked == keyboard->modifiers.locked &&
- group == keyboard->modifiers.group)
- return false;
-
- keyboard->modifiers.depressed = depressed;
- keyboard->modifiers.latched = latched;
- keyboard->modifiers.locked = locked;
- keyboard->modifiers.group = group;
-
- return true;
-}
-
-static void keyboard_key_update(struct ds_keyboard *keyboard,
- struct ds_event_keyboard_key *event)
-{
- // TODO
-}
-
-static void keyboard_led_update(struct ds_keyboard *keyboard)
-{
- // TODO
-}
+++ /dev/null
-#include <error.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <wayland-server.h>
-
-#include "libds/log.h"
-
-static bool colored = true;
-static enum ds_log_level log_level = DS_ERR;
-
-static const char *level_colors[] = {
- [DS_SILENT] = "",
- [DS_ERR] = "\x1B[1;31m",
- [DS_INF] = "\x1B[1;34m",
- [DS_DBG] = "\x1B[1;90m",
-};
-
-static const char *level_headers[] = {
- [DS_SILENT] = "",
- [DS_ERR] = "[ERROR]",
- [DS_INF] = "[INFO]",
- [DS_DBG] = "[DEBUG]",
-};
-
-static void log_stderr(enum ds_log_level level, const char *fmt, va_list args);
-static void log_wl(const char *fmt, va_list args);
-
-static ds_log_func_t log_callback = log_stderr;
-
-WL_EXPORT void
-ds_log_init(enum ds_log_level level, ds_log_func_t callback)
-{
- if (level < DS_LOG_LEVEL_LAST)
- log_level = level;
- if (callback)
- log_callback = callback;
-
- wl_log_set_handler_server(log_wl);
-}
-
-WL_EXPORT void
-_ds_vlog(enum ds_log_level level, const char *fmt, va_list args)
-{
- log_callback(level, fmt, args);
-}
-
-WL_EXPORT void
-_ds_log(enum ds_log_level level, const char *fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
- log_callback(level, fmt, args);
- va_end(args);
-}
-
-enum ds_log_level
-ds_log_get_level(void)
-{
- return log_level;
-}
-
-static void
-log_stderr(enum ds_log_level level, const char *fmt, va_list args)
-{
- bool colored_tty = false;
- unsigned c;
-
- if (level > log_level)
- return;
-
- c = (level < DS_LOG_LEVEL_LAST) ? level : DS_LOG_LEVEL_LAST - 1;
-
- colored_tty = colored && isatty(STDERR_FILENO);
- if (colored_tty)
- fprintf(stderr, "%s", level_colors[c]);
- else
- fprintf(stderr, "%s ", level_headers[c]);
-
- vfprintf(stderr, fmt, args);
-
- if (colored_tty)
- fprintf(stderr, "\x1B[0m");
- fprintf(stderr, "\n");
-}
-
-static void
-log_wl(const char *fmt, va_list args)
-{
- static char ds_fmt[1024];
- int n;
-
- n = snprintf(ds_fmt, sizeof(ds_fmt), "[wayland] %s", fmt);
- if (n > 0 && ds_fmt[n - 1] == '\n')
- ds_fmt[n - 1] = '\0';
- _ds_vlog(DS_INF, ds_fmt, args);
-}
+++ /dev/null
-libds_files = [
- 'log.c',
- 'addon.c',
- 'buffer.c',
- 'allocator.c',
- 'swapchain.c',
- 'output.c',
- 'compositor.c',
- 'subcompositor.c',
- 'region.c',
- 'util/time.c',
- 'util/shm.c',
- 'surface/surface.c',
- 'surface/subsurface.c',
- 'client_buffer/shm_client_buffer.c',
- 'xdg_shell/xdg_shell.c',
- 'xdg_shell/xdg_surface.c',
- 'xdg_shell/xdg_toplevel.c',
- 'pixel_format.c',
- 'backend.c',
- 'input_device.c',
- 'pointer.c',
- 'keyboard.c',
- 'touch.c',
- 'seat/seat.c',
- 'seat/seat_pointer.c',
- 'seat/seat_keyboard.c',
- 'seat/seat_touch.c',
- 'shell.c',
- 'shell_surface.c',
-]
-
-protocols = {
- 'xdg-shell': wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml',
-}
-
-protocols_code = {}
-protocols_server_header = {}
-
-foreach name, path : protocols
- code = custom_target(
- name.underscorify() + '_c',
- input: path,
- output: '@BASENAME@-protocol.c',
- command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'],
- )
- libds_files += code
-
- server_header = custom_target(
- name.underscorify() + '_server_h',
- input: path,
- output: '@BASENAME@-server-protocol.h',
- command: [wayland_scanner, 'server-header', '@INPUT@', '@OUTPUT@'],
- build_by_default: false,
- )
- libds_files += server_header
-endforeach
-
-math = meson.get_compiler('c').find_library('m')
-wayland_server = dependency('wayland-server', required: true)
-pixman = dependency('pixman-1', required: true)
-libdrm = dependency('libdrm', required: true)
-xkbcommon = dependency('xkbcommon', required: true)
-rt = meson.get_compiler('c').find_library('rt')
-
-if wayland_server.version().version_compare('>= 1.19')
- cdata.set('HAVE_WL_SEAT_ERROR_MISSING_CAPABILITY', '1')
-endif
-
-libds_deps = [
- math,
- wayland_server,
- pixman,
- libdrm,
- xkbcommon,
- rt,
-]
-
-subdir('backend')
-subdir('allocator')
-
-lib_libds = shared_library('ds', libds_files,
- dependencies: libds_deps,
- include_directories: [ common_inc, include_directories('.') ],
- version: meson.project_version(),
- install: true
-)
-
-dep_libds = declare_dependency(
- link_with: lib_libds,
- dependencies: libds_deps,
- include_directories: [ common_inc, include_directories('.') ],
-)
-
-pkgconfig = import('pkgconfig')
-pkgconfig.generate(lib_libds,
- version: meson.project_version(),
- filebase: meson.project_name(),
- name: meson.project_name(),
- description: 'Wayland compositor library',
-)
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-#include "libds/output.h"
-#include "libds/interfaces/output.h"
-
-static void output_handle_display_destroy(struct wl_listener *listener,
- void *data);
-static void output_enable(struct ds_output *output, bool enable);
-static void output_state_clear(struct ds_output_state *state);
-static void output_state_clear_buffer(struct ds_output_state *state);
-static void output_state_clear_mode(struct ds_output_state *state);
-
-WL_EXPORT void
-ds_output_init(struct ds_output *output, struct ds_backend *backend,
- const struct ds_output_interface *iface, struct wl_display *display)
-{
- assert(iface->commit);
-
- output->backend = backend;
- output->iface = iface;
- output->display = display;
-
- wl_list_init(&output->modes);
-
- wl_signal_init(&output->events.destroy);
- wl_signal_init(&output->events.frame);
- wl_signal_init(&output->events.commit);
-
- output->display_destroy.notify = output_handle_display_destroy;
- wl_display_add_destroy_listener(display, &output->display_destroy);
-}
-
-WL_EXPORT void
-ds_output_destroy(struct ds_output *output)
-{
- wl_list_remove(&output->display_destroy.link);
-
- wl_signal_emit(&output->events.destroy, output);
-
- if (output->iface && output->iface->destroy)
- output->iface->destroy(output);
- else
- free(output);
-}
-
-void
-ds_output_enable(struct ds_output *output)
-{
- output_enable(output, true);
-}
-
-void
-ds_output_disable(struct ds_output *output)
-{
- output_enable(output, false);
-}
-
-WL_EXPORT bool
-ds_output_commit(struct ds_output *output)
-{
- // TODO signal precommit
-
- if (!output->iface->commit(output)) {
- return false;
- }
-
- output_state_clear(&output->pending);
-
- // TODO signal commit
-
- return true;
-}
-
-WL_EXPORT void
-ds_output_attach_buffer(struct ds_output *output, struct ds_buffer *buffer)
-{
- output_state_clear_buffer(&output->pending);
- output->pending.committed |= DS_OUTPUT_STATE_BUFFER;
- output->pending.buffer = ds_buffer_lock(buffer);
-}
-
-WL_EXPORT const struct ds_output_mode *
-ds_output_get_preferred_mode(struct ds_output *output)
-{
- struct ds_output_mode *mode;
-
- if (wl_list_empty(&output->modes))
- return NULL;
-
- wl_list_for_each(mode, &output->modes, link) {
- if (mode->preferred)
- return mode;
- }
-
- // No preferred mode, choose the first one
- return wl_container_of(output->modes.next, mode, link);
-}
-
-WL_EXPORT void
-ds_output_set_mode(struct ds_output *output, const struct ds_output_mode *mode)
-{
- output_state_clear_mode(&output->pending);
-
- if (output->current_mode == mode) {
- return;
- }
-
- output->pending.committed |= DS_OUTPUT_STATE_MODE;
- output->pending.mode_type = DS_OUTPUT_STATE_MODE_FIXED;
- output->pending.mode = mode;
-}
-
-WL_EXPORT void
-ds_output_set_custom_mode(struct ds_output *output,
- int32_t width, int32_t height, int32_t refresh)
-{
- output_state_clear_mode(&output->pending);
-
- if (output->width == width && output->height == height &&
- output->refresh == refresh)
- return;
-
- output->pending.committed |= DS_OUTPUT_STATE_MODE;
- output->pending.mode_type = DS_OUTPUT_STATE_MODE_CUSTOM;
- output->pending.custom_mode.width = width;
- output->pending.custom_mode.height = height;
- output->pending.custom_mode.refresh = refresh;
-}
-
-WL_EXPORT void
-ds_output_add_destroy_listener(struct ds_output *output,
- struct wl_listener *listener)
-{
- wl_signal_add(&output->events.destroy, listener);
-}
-
-WL_EXPORT void
-ds_output_add_frame_listener(struct ds_output *output,
- struct wl_listener *listener)
-{
- wl_signal_add(&output->events.frame, listener);
-}
-
-WL_EXPORT void
-ds_output_add_commit_listener(struct ds_output *output,
- struct wl_listener *listener)
-{
- wl_signal_add(&output->events.commit, listener);
-}
-
-void
-ds_output_update_custom_mode(struct ds_output *output,
- int32_t width, int32_t height, int32_t refresh)
-{
- if (output->width == width && output->height == height &&
- output->refresh == refresh)
- return;
-
- output->width = width;
- output->height = height;
- output->refresh = refresh;
-}
-
-static void
-output_handle_display_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_output *output;
-
- output = wl_container_of(listener, output, display_destroy);
- // TODO
- // destroy wl_global
-}
-
-static void
-output_state_clear(struct ds_output_state *state)
-{
- output_state_clear_buffer(state);
- state->committed = 0;
-}
-
-static void
-output_state_clear_buffer(struct ds_output_state *state)
-{
- if (!(state->committed & DS_OUTPUT_STATE_BUFFER))
- return;
-
- ds_buffer_unlock(state->buffer);
- state->buffer = NULL;
-
- state->committed &= ~DS_OUTPUT_STATE_BUFFER;
-}
-
-static void
-output_enable(struct ds_output *output, bool enable)
-{
- if (output->enabled == enable) {
- output->pending.committed &= ~DS_OUTPUT_STATE_ENABLED;
- return;
- }
-
- output->pending.committed |= DS_OUTPUT_STATE_ENABLED;
- output->pending.enabled = enable;
-}
-
-static void
-output_state_clear_mode(struct ds_output_state *state)
-{
- if (!(state->committed & DS_OUTPUT_STATE_MODE))
- return;
-
- state->mode = NULL;
- state->committed &= ~DS_OUTPUT_STATE_MODE;
-}
+++ /dev/null
-#ifndef DS_OUTPUT_H
-#define DS_OUTPUT_H
-
-#include <stdint.h>
-
-#include "libds/output.h"
-
-void ds_output_update_custom_mode(struct ds_output *output,
- int32_t width, int32_t height, int32_t refresh);
-
-#endif
+++ /dev/null
-#include <drm_fourcc.h>
-
-#include "pixel_format.h"
-
-uint32_t
-convert_wl_shm_format_to_drm(enum wl_shm_format fmt)
-{
- switch (fmt) {
- case WL_SHM_FORMAT_XRGB8888:
- return DRM_FORMAT_XRGB8888;
- case WL_SHM_FORMAT_ARGB8888:
- return DRM_FORMAT_ARGB8888;
- default:
- return (uint32_t)fmt;
- }
-}
+++ /dev/null
-#ifndef DS_PIXEL_FORMAT_H
-#define DS_PIXEL_FORMAT_H
-
-#include <stdint.h>
-#include <wayland-server.h>
-
-uint32_t convert_wl_shm_format_to_drm(enum wl_shm_format fmt);
-
-#endif
+++ /dev/null
-#include <stdlib.h>
-#include <wayland-server.h>
-#include "libds/interfaces/pointer.h"
-
-void
-ds_pointer_init(struct ds_pointer *pointer,
- const struct ds_pointer_interface *iface)
-{
- pointer->iface = iface;
-
- wl_signal_init(&pointer->events.motion);
- wl_signal_init(&pointer->events.motion_absolute);
- wl_signal_init(&pointer->events.button);
- wl_signal_init(&pointer->events.frame);
-}
-
-void
-ds_pointer_destroy(struct ds_pointer *pointer)
-{
- if (!pointer)
- return;
-
- if (pointer->iface && pointer->iface->destroy)
- pointer->iface->destroy(pointer);
- else
- free(pointer);
-}
-
-WL_EXPORT void
-ds_pointer_add_motion_listener(struct ds_pointer *pointer,
- struct wl_listener *listener)
-{
- wl_signal_add(&pointer->events.motion, listener);
-}
-
-WL_EXPORT void
-ds_pointer_add_motion_absolute_listener(struct ds_pointer *pointer,
- struct wl_listener *listener)
-{
- wl_signal_add(&pointer->events.motion_absolute, listener);
-}
-
-WL_EXPORT void
-ds_pointer_add_button_listener(struct ds_pointer *pointer,
- struct wl_listener *listener)
-{
- wl_signal_add(&pointer->events.button, listener);
-}
-
-WL_EXPORT void
-ds_pointer_add_frame_listener(struct ds_pointer *pointer,
- struct wl_listener *listener)
-{
- wl_signal_add(&pointer->events.frame, listener);
-}
+++ /dev/null
-// TODO
-
-#include "libds-private.h"
-#include "presentation-time-protocol.h"
-
-#define PRESENTATION_VERSION 1
-
-struct ds_presentation
-{
- struct wl_global *global;
-
- struct {
- struct wl_signal destroy;
- } events;
-};
-
-struct ds_presentation_feedback
-{
- struct wl_list resources;
-
-}
-
-struct ds_presentation_surface_state
-{
-};
-
-struct ds_presentation_feedback
-{
- struct wl_resource *resource;
- struct wl_list link;
- uint32_t psf_flags;
-};
-
-static void presentation_bind(struct wl_client *client, void *data,
- uint32_t version, uint32_t id);
-static void handle_display_destroy(struct wl_listener *listener, void *data);
-
-struct ds_presentation *
-ds_presentation_create(struct wl_display *display, clockid_t clk_id)
-{
- struct ds_presentation *presentation;
-
- presentation = calloc(1, sizeof *presentation);
- if (!presentation)
- return NULL;
-
- presentation->global = wl_global_create(display, &wp_presentation_interface,
- PRESENTATION_VERSION, presentation, presentation_bind);
- if (!presentation->global) {
- free(presentation);
- return NULL;
- }
-
- presentation->clock = clk_id;
-
- wl_signal_init(&presentation->events.destroy);
-
- presentation->display_destroy.notify = handle_display_destroy;
- wl_display_add_destroy_listener(display, &presentation->display_destroy);
-}
-
-static void
-presentation_handle_destroy(struct wl_client *client, struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static void
-presentation_handle_feedback(struct wl_client *client,
- struct wl_resource *presentation_resource,
- struct wl_resource *surface_resource, uint32_t id)
-{
- struct ds_presentation *presentation;
- struct ds_surface *surface;
-
- presentation = wl_resource_get_user_data(presentation_resource);
- surface = ds_surface_from_resource(surface_resource);
-}
-
-static const struct wp_presentation_interface presentation_impl =
-{
- .destroy = presentation_handle_destroy,
- .feedback = presentation_handle_feedback,
-};
-
-static void
-presentation_bind(struct wl_client *client, void *data,
- uint32_t version, uint32_t id)
-{
- struct ds_presentation *presentation = data;
- struct wl_resource *resource;
-
- resource = wl_resource_create(client, &wp_presentation_interface,
- version, id);
- if (!resource) {
- wl_client_post_no_memory(client);
- return;
- }
- wl_resource_set_implementation(resource, &presentation_impl,
- presentation, NULL);
-
- wp_presentation_send_clock_id(resource, (uint32_t)presentation->clock);
-}
-
-static void
-handle_display_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_presentation *presentation;
-
- presentation = wl_container_of(listener, presentation, display_destroy);
- wl_signal_emit(&presentation->events.destroy, presentation);
- wl_list_remove(&presentation->display_destroy.link);
- wl_global_destroy(presentation->global);
- free(presentation);
-}
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-#include <math.h>
-#include <pixman.h>
-
-#include "libds/log.h"
-
-#include "region.h"
-
-static const struct wl_region_interface region_impl;
-
-static void region_handle_resource_destroy(struct wl_resource *resource);
-
-void
-ds_region_add(struct wl_client *client, uint32_t version, uint32_t id)
-{
- struct wl_resource *resource;
- pixman_region32_t *region;
-
- region = calloc(1, sizeof *region);
- if (!region) {
- wl_client_post_no_memory(client);
- return;
- }
-
- pixman_region32_init(region);
-
- resource = wl_resource_create(client, &wl_region_interface, version, id);
- if (!resource) {
- free(region);
- wl_client_post_no_memory(client);
- return;
- }
-
- wl_resource_set_implementation(resource, ®ion_impl, region,
- region_handle_resource_destroy);
-}
-
-pixman_region32_t *
-ds_region_from_resource(struct wl_resource *resource)
-{
- assert(wl_resource_instance_of(resource, &wl_region_interface,
- ®ion_impl));
- return wl_resource_get_user_data(resource);
-}
-
-void
-ds_region_transform(pixman_region32_t *dst, pixman_region32_t *src,
- enum wl_output_transform transform, int width, int height)
-{
- pixman_box32_t *src_rects, *dst_rects;
- int nrects, i;
-
- if (transform == WL_OUTPUT_TRANSFORM_NORMAL) {
- pixman_region32_copy(dst, src);
- return;
- }
-
- src_rects = pixman_region32_rectangles(src, &nrects);
- dst_rects = malloc(nrects * sizeof *dst_rects);
- if (!dst_rects)
- return;
-
- for (i = 0; i < nrects; i++) {
- switch (transform) {
- default:
- ds_err("Unkown transform value(%d)", transform);
- case WL_OUTPUT_TRANSFORM_NORMAL:
- dst_rects[i].x1 = src_rects[i].x1;
- dst_rects[i].y1 = src_rects[i].y1;
- dst_rects[i].x2 = src_rects[i].x2;
- dst_rects[i].y2 = src_rects[i].y2;
- break;
- case WL_OUTPUT_TRANSFORM_90:
- dst_rects[i].x1 = height - src_rects[i].y2;
- dst_rects[i].y1 = src_rects[i].x1;
- dst_rects[i].x2 = height - src_rects[i].y1;
- dst_rects[i].y2 = src_rects[i].x2;
- break;
- case WL_OUTPUT_TRANSFORM_180:
- dst_rects[i].x1 = width - src_rects[i].x2;
- dst_rects[i].y1 = height - src_rects[i].y2;
- dst_rects[i].x2 = width - src_rects[i].x1;
- dst_rects[i].y2 = height - src_rects[i].y1;
- break;
- case WL_OUTPUT_TRANSFORM_270:
- dst_rects[i].x1 = src_rects[i].y1;
- dst_rects[i].y1 = width - src_rects[i].x2;
- dst_rects[i].x2 = src_rects[i].y2;
- dst_rects[i].y2 = width - src_rects[i].x1;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED:
- dst_rects[i].x1 = width - src_rects[i].x2;
- dst_rects[i].y1 = src_rects[i].y1;
- dst_rects[i].x2 = width - src_rects[i].x1;
- dst_rects[i].y2 = src_rects[i].y2;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- dst_rects[i].x1 = src_rects[i].y1;
- dst_rects[i].y1 = src_rects[i].x1;
- dst_rects[i].x2 = src_rects[i].y2;
- dst_rects[i].y2 = src_rects[i].x2;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_180:
- dst_rects[i].x1 = src_rects[i].x1;
- dst_rects[i].y1 = height - src_rects[i].y2;
- dst_rects[i].x2 = src_rects[i].x2;
- dst_rects[i].y2 = height - src_rects[i].y1;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- dst_rects[i].x1 = height - src_rects[i].y2;
- dst_rects[i].y1 = width - src_rects[i].x2;
- dst_rects[i].x2 = height - src_rects[i].y1;
- dst_rects[i].y2 = width - src_rects[i].x1;
- break;
- }
- }
-
- pixman_region32_fini(dst);
- pixman_region32_init_rects(dst, dst_rects, nrects);
- free(dst_rects);
-}
-
-void
-ds_region_scale_xy(pixman_region32_t *dst, pixman_region32_t *src,
- float scale_x, float scale_y)
-{
- pixman_box32_t *src_rects, *dst_rects;
- int nrects, i;
-
- if (scale_x == 1.0 && scale_y == 1.0)
- pixman_region32_copy(dst, src);
-
- src_rects = pixman_region32_rectangles(src, &nrects);
- dst_rects = malloc(nrects * sizeof *dst_rects);
- if (!dst_rects)
- return;
-
- for (i = 0; i < nrects; i++) {
- dst_rects[i].x1 = floor(src_rects[i].x1 * scale_x);
- dst_rects[i].x2 = ceil(src_rects[i].x2 * scale_x);
- dst_rects[i].y1 = floor(src_rects[i].y1 * scale_y);
- dst_rects[i].y2 = ceil(src_rects[i].y2 * scale_y);
- }
-
- pixman_region32_fini(dst);
- pixman_region32_init_rects(dst, dst_rects, nrects);
- free(dst_rects);
-}
-
-void
-ds_region_scale(pixman_region32_t *dst, pixman_region32_t *src, float scale)
-{
- ds_region_scale_xy(dst, src, scale, scale);
-}
-
-static void
-region_destroy(struct wl_client *client, struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static void
-region_add(struct wl_client *client, struct wl_resource *resource,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- pixman_region32_t *region = wl_resource_get_user_data(resource);
- pixman_region32_union_rect(region, region, x, y, width, height);
-}
-
-static void
-region_subtract(struct wl_client *client, struct wl_resource *resource,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- pixman_region32_t *region = wl_resource_get_user_data(resource);
- pixman_region32_t rect;
-
- pixman_region32_union_rect(region, region, x, y, width, height);
- pixman_region32_init_rect(&rect, x, y, width, height);
- pixman_region32_subtract(region, region, &rect);
- pixman_region32_fini(&rect);
-}
-
-static const struct wl_region_interface region_impl =
-{
- .destroy = region_destroy,
- .add = region_add,
- .subtract = region_subtract,
-};
-
-static void
-region_handle_resource_destroy(struct wl_resource *resource)
-{
- pixman_region32_t *region = wl_resource_get_user_data(resource);
- pixman_region32_fini(region);
- free(region);
-}
+++ /dev/null
-#ifndef DS_REGION_H
-#define DS_REGION_H
-
-#include <pixman.h>
-#include <wayland-server.h>
-
-void
-ds_region_add(struct wl_client *client, uint32_t version, uint32_t id);
-
-pixman_region32_t *
-ds_region_from_resource(struct wl_resource *resource);
-
-void
-ds_region_transform(pixman_region32_t *dst, pixman_region32_t *src,
- enum wl_output_transform transform, int width, int height);
-
-void
-ds_region_scale_xy(pixman_region32_t *dst, pixman_region32_t *src,
- float scale_x, float scale_y);
-
-void
-ds_region_scale(pixman_region32_t *dst, pixman_region32_t *src, float scale);
-
-#endif
+++ /dev/null
-#ifndef DS_SEAT_H
-#define DS_SEAT_H
-
-#include "libds/keyboard.h"
-#include "libds/seat.h"
-
-struct ds_seat_pointer_grab;
-
-struct ds_pointer_grab_interface
-{
- void (*enter)(struct ds_seat_pointer_grab *grab,
- struct ds_surface *surface, double sx, double sy);
- void (*clear_focus)(struct ds_seat_pointer_grab *grab);
- void (*motion)(struct ds_seat_pointer_grab *grab, uint32_t time_msec,
- double sx, double sy);
- uint32_t (*button)(struct ds_seat_pointer_grab *grab, uint32_t time_msec,
- uint32_t button, enum ds_button_state state);
- void (*axis)(struct ds_seat_pointer_grab *grab, uint32_t time_msec,
- enum ds_axis_orientation orientation, double value,
- int32_t value_discrete, enum ds_axis_source source);
- void (*frame)(struct ds_seat_pointer_grab *grab);
- void (*cancel)(struct ds_seat_pointer_grab *grab);
-};
-
-struct ds_seat_keyboard_grab;
-
-struct ds_keyboard_grab_interface
-{
- void (*enter)(struct ds_seat_keyboard_grab *grab,
- struct ds_surface *surface, uint32_t keycodes[],
- size_t num_keycodes, struct ds_keyboard_modifiers *modifiers);
- void (*clear_focus)(struct ds_seat_keyboard_grab *grab);
- void (*key)(struct ds_seat_keyboard_grab *grab, uint32_t time_msec,
- uint32_t key, uint32_t state);
- void (*modifiers)(struct ds_seat_keyboard_grab *grab,
- struct ds_keyboard_modifiers *modifiers);
- void (*cancel)(struct ds_seat_keyboard_grab *grab);
-};
-
-struct ds_touch_point;
-
-struct ds_seat_touch_grab;
-
-struct ds_touch_grab_interface
-{
- uint32_t (*down)(struct ds_seat_touch_grab *grab, uint32_t time_msec,
- struct ds_touch_point *point);
- void (*up)(struct ds_seat_touch_grab *grab, uint32_t time_msec,
- struct ds_touch_point *point);
- void (*motion)(struct ds_seat_touch_grab *grab, uint32_t time_msec,
- struct ds_touch_point *point);
- void (*enter)(struct ds_seat_touch_grab *grab, uint32_t time_msec,
- struct ds_touch_point *point);
- void (*frame)(struct ds_seat_touch_grab *grab);
- void (*cancel)(struct ds_seat_touch_grab *grab);
-};
-
-struct ds_seat_pointer_grab
-{
- const struct ds_pointer_grab_interface *iface;
- struct ds_seat *seat;
- void *data;
-};
-
-struct ds_seat_keyboard_grab
-{
- const struct ds_keyboard_grab_interface *iface;
- struct ds_seat *seat;
- void *data;
-};
-
-struct ds_seat_touch_grab
-{
- const struct ds_touch_grab_interface *iface;
- struct ds_seat *seat;
- void *data;
-};
-
-void ds_seat_pointer_start_grab(struct ds_seat *seat,
- struct ds_seat_pointer_grab *grab);
-
-void ds_seat_pointer_end_grab(struct ds_seat *seat);
-
-void ds_seat_pointer_enter(struct ds_seat *seat, struct ds_surface *surface,
- double sx, double sy);
-
-void ds_seat_pointer_clear_focus(struct ds_seat *seat);
-
-void ds_seat_pointer_send_motion(struct ds_seat *seat, uint32_t time_msec,
- double sx, double sy);
-
-uint32_t ds_seat_pointer_send_button(struct ds_seat *seat, uint32_t time_msec,
- uint32_t button, enum ds_button_state state);
-
-void ds_seat_pointer_send_axis(struct ds_seat *seat, uint32_t time_msec,
- enum ds_axis_orientation orientation, double value,
- int32_t value_discrete, enum ds_axis_source source);
-
-void ds_seat_pointer_send_frame(struct ds_seat *seat);
-
-void ds_seat_keyboard_start_grab(struct ds_seat *seat,
- struct ds_seat_keyboard_grab *grab);
-
-void ds_seat_keyboard_end_grab(struct ds_seat *seat);
-
-void ds_seat_keyboard_enter(struct ds_seat *seat, struct ds_surface *surface,
- uint32_t keycodes[], size_t num_keycodes,
- struct ds_keyboard_modifiers *modifiers);
-
-void ds_seat_keyboard_clear_focus(struct ds_seat *seat);
-
-void ds_seat_keyboard_send_key(struct ds_seat *seat, uint32_t time_msec,
- uint32_t key, uint32_t state);
-
-void ds_seat_keyboard_send_modifiers(struct ds_seat *seat,
- struct ds_keyboard_modifiers *modifiers);
-
-void ds_seat_touch_start_grab(struct ds_seat *seat,
- struct ds_seat_touch_grab *grab);
-
-void ds_seat_touch_end_grab(struct ds_seat *seat);
-
-uint32_t ds_seat_touch_send_down(struct ds_seat *seat,
- struct ds_surface *surface, uint32_t time_msec, int32_t touch_id,
- double sx, double sy);
-
-void ds_seat_touch_send_up(struct ds_seat *seat, uint32_t time_msec,
- int32_t touch_id);
-
-void ds_seat_touch_send_motion(struct ds_seat *seat, uint32_t time_msec,
- int32_t touch_id, double sx, double sy);
-
-void ds_seat_touch_send_frame(struct ds_seat *seat);
-
-#endif
+++ /dev/null
-#include "config.h"
-
-#define _POSIX_C_SOURCE 200809L
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libds/log.h"
-#include "seat_private.h"
-
-#define SEAT_VERSION 7
-
-static void seat_handle_bind(struct wl_client *wl_client, void *data,
- uint32_t version, uint32_t id);
-static void seat_handle_display_destroy(struct wl_listener *listener,
- void *data);
-static void seat_destroy(struct ds_seat *seat);
-static struct ds_seat_client *seat_client_create(struct ds_seat *seat,
- struct wl_client *wl_client);
-static void seat_client_destroy(struct ds_seat_client *seat_client);
-static void
-seat_client_send_capabilities(struct ds_seat_client *seat_client);
-static void seat_client_send_name(struct ds_seat_client *seat_client);
-
-WL_EXPORT struct ds_seat *
-ds_seat_create(struct wl_display *display, const char *name)
-{
- struct ds_seat *seat;
-
- seat = calloc(1, sizeof *seat);
- if (!seat)
- return NULL;
-
- if (!seat_pointer_init(seat)) {
- ds_err("Failed to initialize pointer for seat(%s)", name);
- goto err_ptr;
- }
-
- if (!seat_keyboard_init(seat)) {
- ds_err("Failed to initialize keyboard for seat(%s)", name);
- goto err_kbd;
- }
-
- if (!seat_touch_init(seat)) {
- ds_err("Failed to initialize touch for seat(%s)", name);
- goto err_touch;
- }
-
- seat->global = wl_global_create(display, &wl_seat_interface,
- SEAT_VERSION, seat, seat_handle_bind);
- if (!seat->global) {
- ds_err("Failed to create wl_global for seat(%s)", name);
- goto err_global;
- }
-
- seat->display = display;
- seat->name = strdup(name);
-
- wl_list_init(&seat->clients);
-
- wl_signal_init(&seat->events.destroy);
- wl_signal_init(&seat->events.pointer_grab_begin);
- wl_signal_init(&seat->events.pointer_grab_end);
- wl_signal_init(&seat->events.keyboard_grab_begin);
- wl_signal_init(&seat->events.keyboard_grab_end);
- wl_signal_init(&seat->events.touch_grab_begin);
- wl_signal_init(&seat->events.touch_grab_end);
-
- seat->display_destroy.notify = seat_handle_display_destroy;
- wl_display_add_destroy_listener(display, &seat->display_destroy);
-
- return seat;
-
-err_global:
- seat_touch_finish(seat);
-err_touch:
- seat_keyboard_finish(seat);
-err_kbd:
- seat_pointer_finish(seat);
-err_ptr:
- free(seat);
-
- return NULL;
-}
-
-WL_EXPORT void
-ds_seat_destroy(struct ds_seat *seat)
-{
- seat_destroy(seat);
-}
-
-WL_EXPORT void
-ds_seat_set_capabilities(struct ds_seat *seat,
- enum wl_seat_capability capabilities)
-{
- struct ds_seat_client *seat_client;
-
- if (capabilities == seat->capabilities)
- return;
-
- seat->capabilities = capabilities;
- seat->accumulated_capabilities |= capabilities;
-
- wl_list_for_each(seat_client, &seat->clients, link) {
- if (!(capabilities & WL_SEAT_CAPABILITY_POINTER)) {
- seat_client_remove_all_pointer_resources(seat_client);
- }
- if (!(capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) {
- seat_client_remove_all_keyboard_resources(seat_client);
- }
- if (!(capabilities & WL_SEAT_CAPABILITY_TOUCH)) {
- seat_client_remove_all_touch_resources(seat_client);
- }
-
- seat_client_send_capabilities(seat_client);
- }
-}
-
-WL_EXPORT void
-ds_seat_set_name(struct ds_seat *seat, const char *name)
-{
- struct ds_seat_client *seat_client;
-
- free(seat->name);
- seat->name = strdup(name);
-
- wl_list_for_each(seat_client, &seat->clients, link) {
- seat_client_send_name(seat_client);
- }
-}
-
-WL_EXPORT void
-ds_seat_add_destroy_listener(struct ds_seat *seat,
- struct wl_listener *listener)
-{
- wl_signal_add(&seat->events.destroy, listener);
-}
-
-struct ds_seat_client *
-seat_client_for_wl_client(struct ds_seat *seat, struct wl_client *wl_client)
-{
- struct ds_seat_client *seat_client;
-
- wl_list_for_each(seat_client, &seat->clients, link) {
- if (seat_client->wl_client == wl_client)
- return seat_client;
- }
-
- return NULL;
-}
-
-static struct ds_seat_client *
-ds_seat_client_get_or_create(struct ds_seat *seat, struct wl_client *wl_client)
-{
- struct ds_seat_client *seat_client;
-
- seat_client = seat_client_for_wl_client(seat, wl_client);
- if (!seat_client) {
- seat_client = seat_client_create(seat, wl_client);
- if (!seat_client)
- return NULL;
-
- wl_list_insert(&seat->clients, &seat_client->link);
- }
-
- return seat_client;
-}
-
-static void
-seat_handle_get_pointer(struct wl_client *wl_client,
- struct wl_resource *resource, uint32_t id)
-{
- struct ds_seat_client *seat_client;
-
- seat_client = wl_resource_get_user_data(resource);
- if (!seat_client)
- return;
-
- if (!(seat_client->seat->accumulated_capabilities &
- WL_SEAT_CAPABILITY_POINTER)) {
-#ifdef HAVE_WL_SEAT_ERROR_MISSING_CAPABILITY
- wl_resource_post_error(resource, WL_SEAT_ERROR_MISSING_CAPABILITY,
- "wl_seat.get_pointer called when no "
- "pointer capability has existed");
-#endif
- return;
- }
-
- seat_client_add_pointer_resource(seat_client,
- wl_resource_get_version(resource), id);
-}
-
-static void
-seat_handle_get_keyboard(struct wl_client *wl_client,
- struct wl_resource *resource, uint32_t id)
-{
- struct ds_seat_client *seat_client;
-
- seat_client = wl_resource_get_user_data(resource);
- if (!seat_client)
- return;
-
- if (!(seat_client->seat->accumulated_capabilities &
- WL_SEAT_CAPABILITY_KEYBOARD)) {
-#ifdef HAVE_WL_SEAT_ERROR_MISSING_CAPABILITY
- wl_resource_post_error(resource, WL_SEAT_ERROR_MISSING_CAPABILITY,
- "wl_seat.get_keyboard called when no "
- "keyboard capability has existed");
-#endif
- return;
- }
-
- seat_client_add_keyboard_resource(seat_client,
- wl_resource_get_version(resource), id);
-}
-
-static void
-seat_handle_get_touch(struct wl_client *wl_client,
- struct wl_resource *resource, uint32_t id)
-{
- struct ds_seat_client *seat_client;
-
- seat_client = wl_resource_get_user_data(resource);
- if (!seat_client)
- return;
-
- if (!(seat_client->seat->accumulated_capabilities &
- WL_SEAT_CAPABILITY_TOUCH)) {
-#ifdef HAVE_WL_SEAT_ERROR_MISSING_CAPABILITY
- wl_resource_post_error(resource, WL_SEAT_ERROR_MISSING_CAPABILITY,
- "wl_seat.get_touch called when no "
- "touch capability has existed");
-#endif
- return;
- }
-
- seat_client_add_touch_resource(seat_client,
- wl_resource_get_version(resource), id);
-}
-
-static void
-seat_handle_release(struct wl_client *wl_client, struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static const struct wl_seat_interface seat_impl =
-{
- .get_pointer = seat_handle_get_pointer,
- .get_keyboard = seat_handle_get_keyboard,
- .get_touch = seat_handle_get_touch,
- .release = seat_handle_release,
-};
-
-static void
-seat_client_handle_resource_destroy(struct wl_resource *resource)
-{
- struct ds_seat_client *seat_client;
-
- seat_client = wl_resource_get_user_data(resource);
- if (!seat_client)
- return;
-
- wl_list_remove(wl_resource_get_link(resource));
- if (!wl_list_empty(&seat_client->resources))
- return;
-
- seat_client_destroy(seat_client);
-}
-
-static void
-seat_handle_bind(struct wl_client *wl_client, void *data, uint32_t version,
- uint32_t id)
-{
- struct ds_seat *seat = data;
- struct ds_seat_client *seat_client;
- struct wl_resource *resource;
-
- resource = wl_resource_create(wl_client, &wl_seat_interface, version, id);
- if (!resource) {
- wl_client_post_no_memory(wl_client);
- return;
- }
-
- seat_client = ds_seat_client_get_or_create(seat, wl_client);
- if (!seat_client) {
- wl_resource_destroy(resource);
- wl_client_post_no_memory(wl_client);
- return;
- }
-
- wl_resource_set_implementation(resource, &seat_impl,
- seat_client, seat_client_handle_resource_destroy);
-
- wl_list_insert(&seat_client->resources, wl_resource_get_link(resource));
-
- wl_seat_send_capabilities(resource, seat->capabilities);
-
- if (version >= WL_SEAT_NAME_SINCE_VERSION)
- wl_seat_send_name(resource, seat->name);
-}
-
-static void
-seat_handle_display_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_seat *seat;
-
- seat = wl_container_of(listener, seat, display_destroy);
- seat_destroy(seat);
-}
-
-static void
-seat_destroy(struct ds_seat *seat)
-{
- struct ds_seat_client *seat_client, *tmp;
- struct wl_resource *resource, *next;
-
- wl_signal_emit(&seat->events.destroy, seat);
-
- wl_list_remove(&seat->display_destroy.link);
-
- wl_list_for_each_safe(seat_client, tmp, &seat->clients, link) {
- wl_resource_for_each_safe(resource, next, &seat_client->resources) {
- wl_list_remove(wl_resource_get_link(resource));
- wl_resource_set_user_data(resource, NULL);
- }
- seat_client_destroy(seat_client);
- }
-
- seat_pointer_finish(seat);
- seat_keyboard_finish(seat);
- seat_touch_finish(seat);
-
- wl_global_destroy(seat->global);
- free(seat->name);
- free(seat);
-}
-
-static struct ds_seat_client *
-seat_client_create(struct ds_seat *seat, struct wl_client *wl_client)
-{
- struct ds_seat_client *seat_client;
-
- seat_client = calloc(1, sizeof *seat_client);
- seat_client->seat = seat;
- seat_client->wl_client = wl_client;
-
- wl_list_init(&seat_client->resources);
- wl_list_init(&seat_client->pointers);
- wl_list_init(&seat_client->keyboards);
- wl_list_init(&seat_client->touches);
-
- wl_signal_init(&seat_client->events.destroy);
-
- return seat_client;
-}
-
-static void
-seat_client_destroy(struct ds_seat_client *seat_client)
-{
- wl_signal_emit(&seat_client->events.destroy, seat_client);
-
- seat_client_remove_all_pointer_resources(seat_client);
- seat_client_remove_all_keyboard_resources(seat_client);
- seat_client_remove_all_touch_resources(seat_client);
-
- wl_list_remove(&seat_client->link);
-
- free(seat_client);
-}
-
-static void
-seat_client_send_capabilities(struct ds_seat_client *seat_client)
-{
- struct wl_resource *resource;
-
- wl_resource_for_each(resource, &seat_client->resources) {
- wl_seat_send_capabilities(resource, seat_client->seat->capabilities);
- }
-}
-
-static void
-seat_client_send_name(struct ds_seat_client *seat_client)
-{
- struct wl_resource *resource;
-
- wl_resource_for_each(resource, &seat_client->resources) {
- wl_seat_send_name(resource, seat_client->seat->name);
- }
-}
+++ /dev/null
-#include <assert.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "libds/log.h"
-#include "seat_private.h"
-
-static const struct ds_keyboard_grab_interface default_keyboard_grab_iface;
-static const struct wl_keyboard_interface keyboard_impl;
-
-static void
-seat_client_send_keyboard_leave_raw(struct ds_seat_client *seat_client,
- struct ds_surface *surface);
-static void
-seat_keyboard_handle_surface_destroy(struct wl_listener *listener,
- void *data);
-static void keyboard_handle_resource_destroy(struct wl_resource *resource);
-
-WL_EXPORT void
-ds_seat_keyboard_notify_enter(struct ds_seat *seat,
- struct ds_surface *surface, uint32_t keycodes[], size_t num_keycodes,
- struct ds_keyboard_modifiers *modifiers)
-{
- struct ds_seat_keyboard_grab *grab = seat->keyboard.grab;
-
- grab->iface->enter(grab, surface, keycodes, num_keycodes, modifiers);
-}
-
-WL_EXPORT void
-ds_seat_keyboard_notify_clear_focus(struct ds_seat *seat)
-{
- struct ds_seat_keyboard_grab *grab = seat->keyboard.grab;
-
- grab->iface->clear_focus(grab);
-}
-
-WL_EXPORT void
-ds_seat_keyboard_notify_modifiers(struct ds_seat *seat,
- struct ds_keyboard_modifiers *modifiers)
-{
- struct ds_seat_keyboard_grab *grab = seat->keyboard.grab;
-
- clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
- grab->iface->modifiers(grab, modifiers);
-}
-
-WL_EXPORT void
-ds_seat_keyboard_notify_key(struct ds_seat *seat, uint32_t time_msec,
- uint32_t key, uint32_t state)
-{
- struct ds_seat_keyboard_grab *grab = seat->keyboard.grab;
-
- clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
- grab->iface->key(grab, time_msec, key, state);
-}
-
-WL_EXPORT void
-ds_seat_keyboard_add_grab_begin_listener(struct ds_seat *seat,
- struct wl_listener *listener)
-{
- wl_signal_add(&seat->events.keyboard_grab_begin, listener);
-}
-
-WL_EXPORT void
-ds_seat_keyboard_add_grab_end_listener(struct ds_seat *seat,
- struct wl_listener *listener)
-{
- wl_signal_add(&seat->events.keyboard_grab_end, listener);
-}
-
-WL_EXPORT void
-ds_seat_keyboard_add_focus_change_listener(struct ds_seat *seat,
- struct wl_listener *listener)
-{
- wl_signal_add(&seat->keyboard.events.focus_change, listener);
-}
-
-void
-ds_seat_keyboard_start_grab(struct ds_seat *seat,
- struct ds_seat_keyboard_grab *grab)
-{
- grab->seat = seat;
- seat->keyboard.grab = grab;
-
- wl_signal_emit(&seat->events.keyboard_grab_begin, grab);
-}
-
-void
-ds_seat_keyboard_end_grab(struct ds_seat *seat)
-{
- struct ds_seat_keyboard *keyboard = &seat->keyboard;
- struct ds_seat_keyboard_grab *grab = keyboard->grab;
-
- if (grab != keyboard->default_grab) {
- keyboard->grab = keyboard->default_grab;
- wl_signal_emit(&seat->events.keyboard_grab_end, grab);
- if (grab->iface->cancel)
- grab->iface->cancel(grab);
- }
-}
-
-void
-ds_seat_keyboard_enter(struct ds_seat *seat, struct ds_surface *surface,
- uint32_t keycodes[], size_t num_keycodes,
- struct ds_keyboard_modifiers *modifiers)
-{
- struct ds_seat_keyboard *keyboard = &seat->keyboard;
- struct ds_seat_client *seat_client = NULL, *focused_client;
- struct ds_surface *focused_surface;
- struct wl_client *wl_client;
- struct wl_array keys;
- struct wl_resource *resource;
- uint32_t *p;
- uint32_t serial;
-
- if (keyboard->focused_surface == surface)
- return;
-
- if (surface) {
- wl_client =
- wl_resource_get_client(ds_surface_get_wl_resource(surface));
- seat_client = seat_client_for_wl_client(seat, wl_client);
- }
-
- focused_client = keyboard->focused_client;
- focused_surface = keyboard->focused_surface;
-
- if (focused_client != NULL && focused_surface != NULL)
- seat_client_send_keyboard_leave_raw(focused_client, focused_surface);
-
- if (seat_client) {
- wl_array_init(&keys);
-
- for (size_t i = 0; i < num_keycodes; i++) {
- p = wl_array_add(&keys, sizeof(uint32_t));
- if (!p) {
- ds_err("Cannot allocate memory, skipping keycode: %" PRIu32
- "\n", keycodes[i]);
- continue;
- }
- *p = keycodes[i];
- }
-
- serial = wl_display_next_serial(seat->display);
-
- wl_resource_for_each(resource, &seat_client->keyboards) {
- wl_keyboard_send_enter(resource, serial,
- ds_surface_get_wl_resource(surface), &keys);
- }
- wl_array_release(&keys);
- }
-
- wl_list_remove(&keyboard->surface_destroy.link);
- wl_list_init(&keyboard->surface_destroy.link);
-
- if (surface) {
- keyboard->surface_destroy.notify =
- seat_keyboard_handle_surface_destroy;
- ds_surface_add_destroy_listener(surface, &keyboard->surface_destroy);
- }
-
- keyboard->focused_client = seat_client;
- keyboard->focused_surface = surface;
-
- if (seat_client) {
- ds_seat_keyboard_send_modifiers(seat, modifiers);
-
- // TODO handle selection
- }
-
- struct ds_event_seat_keyboard_focus_change event = {
- .seat = seat,
- .old_surface = focused_surface,
- .new_surface = surface,
- };
- wl_signal_emit(&keyboard->events.focus_change, &event);
-}
-
-void
-ds_seat_keyboard_clear_focus(struct ds_seat *seat)
-{
- ds_seat_keyboard_enter(seat, NULL, NULL, 0, NULL);
-}
-
-void
-ds_seat_keyboard_send_key(struct ds_seat *seat, uint32_t time_msec,
- uint32_t key, uint32_t state)
-{
- struct ds_seat_client *seat_client;
- struct wl_resource *resource;
- uint32_t serial;
-
- seat_client = seat->keyboard.focused_client;
- if (!seat_client)
- return;
-
- serial = wl_display_next_serial(seat->display);
- wl_resource_for_each(resource, &seat_client->keyboards)
- wl_keyboard_send_key(resource, serial, time_msec, key, state);
-}
-
-void
-ds_seat_keyboard_send_modifiers(struct ds_seat *seat,
- struct ds_keyboard_modifiers *modifiers)
-{
- struct ds_seat_keyboard *keyboard = &seat->keyboard;
- struct ds_seat_client *seat_client = keyboard->focused_client;
- struct wl_resource *resource;
- uint32_t serial;
-
- if (!seat_client)
- return;
-
- serial = wl_display_next_serial(seat->display);
- wl_resource_for_each(resource, &seat_client->keyboards) {
- if (!modifiers) {
- wl_keyboard_send_modifiers(resource, serial, 0, 0, 0, 0);
- }
- else {
- wl_keyboard_send_modifiers(resource, serial,
- modifiers->depressed, modifiers->latched,
- modifiers->locked, modifiers->group);
- }
- }
-}
-
-bool
-seat_keyboard_init(struct ds_seat *seat)
-{
- struct ds_seat_keyboard *keyboard = &seat->keyboard;
- struct ds_seat_keyboard_grab *grab;
-
- grab = calloc(1, sizeof *grab);
- if (!grab)
- return false;
-
- grab->iface = &default_keyboard_grab_iface;
- grab->seat = seat;
-
- keyboard->default_grab = grab;
- keyboard->grab = grab;
- keyboard->seat = seat;
-
- wl_list_init(&keyboard->surface_destroy.link);
-
- wl_signal_init(&keyboard->events.focus_change);
-
- return true;
-}
-
-void seat_keyboard_finish(struct ds_seat *seat)
-{
- struct ds_seat_keyboard *keyboard = &seat->keyboard;
-
- wl_list_remove(&keyboard->surface_destroy.link);
- free(keyboard->default_grab);
-}
-
-void
-seat_client_add_keyboard_resource(struct ds_seat_client *seat_client,
- uint32_t version, uint32_t id)
-{
- struct wl_resource *resource;
-
- resource = wl_resource_create(seat_client->wl_client,
- &wl_keyboard_interface, version, id);
- if (!resource) {
- wl_client_post_no_memory(seat_client->wl_client);
- return;
- }
-
- wl_resource_set_implementation(resource, &keyboard_impl, seat_client,
- keyboard_handle_resource_destroy);
-
- wl_list_insert(&seat_client->keyboards, wl_resource_get_link(resource));
-
- if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) {
- wl_resource_set_user_data(resource, NULL);
- return;
- }
-}
-
-void
-seat_client_remove_all_keyboard_resources(struct ds_seat_client *seat_client)
-{
- struct wl_resource *resource, *tmp;
-
- wl_resource_for_each_safe(resource, tmp, &seat_client->keyboards) {
- wl_list_remove(wl_resource_get_link(resource));
- wl_resource_set_user_data(resource, NULL);
- }
-}
-
-static void
-keyboard_handle_release(struct wl_client *client, struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static const struct wl_keyboard_interface keyboard_impl =
-{
- .release = keyboard_handle_release,
-};
-
-static void
-keyboard_handle_resource_destroy(struct wl_resource *resource)
-{
- if (!wl_resource_get_user_data(resource))
- return;
-
- wl_list_remove(wl_resource_get_link(resource));
-}
-
-static void
-default_keyboard_grab_iface_enter(struct ds_seat_keyboard_grab *grab,
- struct ds_surface *surface, uint32_t keycodes[],
- size_t num_keycodes, struct ds_keyboard_modifiers *modifiers)
-{
- ds_seat_keyboard_enter(grab->seat, surface, keycodes, num_keycodes,
- modifiers);
-}
-
-static void
-default_keyboard_grab_iface_clear_focus(struct ds_seat_keyboard_grab *grab)
-{
- ds_seat_keyboard_clear_focus(grab->seat);
-}
-
-static void
-default_keyboard_grab_iface_key(struct ds_seat_keyboard_grab *grab,
- uint32_t time_msec, uint32_t key, uint32_t state)
-{
- ds_seat_keyboard_send_key(grab->seat, time_msec, key, state);
-}
-
-static void
-default_modifiers_grab_iface_key(struct ds_seat_keyboard_grab *grab,
- struct ds_keyboard_modifiers *modifiers)
-{
- ds_seat_keyboard_send_modifiers(grab->seat, modifiers);
-}
-
-static void
-default_cancel_grab_iface_key(struct ds_seat_keyboard_grab *grab)
-{
- // cannot be cancelled
-}
-
-static const struct ds_keyboard_grab_interface default_keyboard_grab_iface = {
- .enter = default_keyboard_grab_iface_enter,
- .clear_focus = default_keyboard_grab_iface_clear_focus,
- .key = default_keyboard_grab_iface_key,
- .modifiers = default_modifiers_grab_iface_key,
- .cancel = default_cancel_grab_iface_key,
-};
-
-static void
-seat_client_send_keyboard_leave_raw(struct ds_seat_client *seat_client,
- struct ds_surface *surface)
-{
- struct wl_resource *resource;
- uint32_t serial;
-
- serial = wl_display_next_serial(wl_client_get_display(seat_client->wl_client));
- wl_resource_for_each(resource, &seat_client->keyboards) {
- wl_keyboard_send_leave(resource, serial,
- ds_surface_get_wl_resource(surface));
- }
-}
-
-static void
-seat_keyboard_handle_surface_destroy(struct wl_listener *listener,
- void *data)
-{
- struct ds_seat_keyboard *keyboard;
-
- keyboard = wl_container_of(listener, keyboard, surface_destroy);
-
- wl_list_remove(&keyboard->surface_destroy.link);
- wl_list_init(&keyboard->surface_destroy.link);
- ds_seat_keyboard_clear_focus(keyboard->seat);
-}
+++ /dev/null
-#include <assert.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "seat_private.h"
-
-static const struct ds_pointer_grab_interface default_pointer_grab_iface;
-static const struct wl_pointer_interface pointer_impl;
-
-static void seat_pointer_warp(struct ds_seat *seat, double sx, double sy);
-static void
-seat_client_send_pointer_leave_raw(struct ds_seat_client *seat_client,
- struct ds_surface *surface);
-static void
-seat_pointer_handle_surface_destroy(struct wl_listener *listener,
- void *data);
-static void pointer_handle_resource_destroy(struct wl_resource *resource);
-static void pointer_send_frame(struct wl_resource *resource);
-
-WL_EXPORT void
-ds_seat_pointer_notify_enter(struct ds_seat *seat, struct ds_surface *surface,
- double sx, double sy)
-{
- struct ds_seat_pointer_grab *grab = seat->pointer.grab;
-
- assert(surface);
- grab->iface->enter(grab, surface, sx, sy);
-}
-
-WL_EXPORT void
-ds_seat_pointer_notify_clear_focus(struct ds_seat *seat)
-{
- struct ds_seat_pointer_grab *grab = seat->pointer.grab;
-
- grab->iface->clear_focus(grab);
-}
-
-WL_EXPORT void
-ds_seat_pointer_notify_motion(struct ds_seat *seat, uint32_t time_msec,
- double sx, double sy)
-{
- struct ds_seat_pointer_grab *grab = seat->pointer.grab;
-
- grab->iface->motion(grab, time_msec, sx, sy);
-}
-
-WL_EXPORT uint32_t
-ds_seat_pointer_notify_button(struct ds_seat *seat, uint32_t time_msec,
- uint32_t button, enum ds_button_state state)
-{
- struct ds_seat_pointer *pointer = &seat->pointer;
- struct ds_seat_pointer_grab *grab = pointer->grab;
- uint32_t serial;
-
- if (state == DS_BUTTON_PRESSED) {
- if (pointer->button_count == 0) {
- pointer->grab_button = button;
- pointer->grab_time = time_msec;
- }
- // TODO need a set struct for assigning pointer->buttons
- }
- else {
- // TODO
- }
-
- serial = grab->iface->button(grab, time_msec, button, state);
- if (serial && pointer->button_count == 1 &&
- state == DS_BUTTON_PRESSED)
- pointer->grab_serial = serial;
-
- return serial;
-}
-
-WL_EXPORT void
-ds_seat_pointer_notify_axis(struct ds_seat *seat, uint32_t time_msec,
- enum ds_axis_orientation orientation, double value,
- int32_t value_discrete, enum ds_axis_source source)
-{
- struct ds_seat_pointer_grab *grab = seat->pointer.grab;
-
- clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
- grab->iface->axis(grab, time_msec, orientation, value, value_discrete, source);
-}
-
-WL_EXPORT void
-ds_seat_pointer_notify_frame(struct ds_seat *seat)
-{
- struct ds_seat_pointer_grab *grab = seat->pointer.grab;
-
- clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
- if (grab->iface->frame)
- grab->iface->frame(grab);
-}
-
-WL_EXPORT void
-ds_seat_pointer_add_grab_begin_listener(struct ds_seat *seat,
- struct wl_listener *listener)
-{
- wl_signal_add(&seat->events.pointer_grab_begin, listener);
-}
-
-WL_EXPORT void
-ds_seat_pointer_add_grab_end_listener(struct ds_seat *seat,
- struct wl_listener *listener)
-{
- wl_signal_add(&seat->events.pointer_grab_end, listener);
-}
-
-WL_EXPORT void
-ds_seat_pointer_add_focus_change_listener(struct ds_seat *seat,
- struct wl_listener *listener)
-{
- wl_signal_add(&seat->pointer.events.focus_change, listener);
-}
-
-void
-ds_seat_pointer_start_grab(struct ds_seat *seat,
- struct ds_seat_pointer_grab *grab)
-{
- grab->seat = seat;
- seat->pointer.grab = grab;
- wl_signal_emit(&seat->events.pointer_grab_begin, grab);
-}
-
-void
-ds_seat_pointer_end_grab(struct ds_seat *seat)
-{
- struct ds_seat_pointer *pointer = &seat->pointer;
- struct ds_seat_pointer_grab *grab = pointer->grab;
-
- if (grab != pointer->default_grab) {
- pointer->grab = pointer->default_grab;
- wl_signal_emit(&seat->events.pointer_grab_end, grab);
- if (grab->iface->cancel)
- grab->iface->cancel(grab);
- }
-}
-
-void
-ds_seat_pointer_enter(struct ds_seat *seat, struct ds_surface *surface,
- double sx, double sy)
-{
- struct ds_seat_pointer *pointer = &seat->pointer;
- struct ds_seat_client *seat_client = NULL, *focused_client;
- struct ds_surface *focused_surface;
- struct wl_client *wl_client;
- struct wl_resource *resource;
- uint32_t serial;
-
- if (pointer->focused_surface == surface) {
- // this surface already got an enter notify
- return;
- }
-
- focused_client = pointer->focused_client;
- focused_surface = pointer->focused_surface;
-
- if (focused_client != NULL && focused_surface != NULL)
- seat_client_send_pointer_leave_raw(focused_client, focused_surface);
-
- if (surface) {
- wl_client =
- wl_resource_get_client(ds_surface_get_wl_resource(surface));
- seat_client = seat_client_for_wl_client(seat, wl_client);
- }
-
- if (seat_client) {
- serial = wl_display_next_serial(seat->display);
- wl_resource_for_each(resource, &seat_client->pointers) {
- wl_pointer_send_enter(resource, serial,
- ds_surface_get_wl_resource(surface),
- wl_fixed_from_double(sx), wl_fixed_from_double(sy));
- pointer_send_frame(resource);
- }
- }
-
- wl_list_remove(&pointer->surface_destroy.link);
- wl_list_init(&pointer->surface_destroy.link);
-
- if (surface) {
- pointer->surface_destroy.notify =
- seat_pointer_handle_surface_destroy;
- ds_surface_add_destroy_listener(surface, &pointer->surface_destroy);
- }
-
- pointer->focused_client = seat_client;
- pointer->focused_surface = surface;
- if (surface)
- seat_pointer_warp(seat, sx, sy);
- else
- seat_pointer_warp(seat, NAN, NAN);
-
- struct ds_event_seat_pointer_focus_change event = {
- .seat = seat,
- .new_surface = surface,
- .old_surface = focused_surface,
- .sx = sx,
- .sy = sy,
- };
- wl_signal_emit(&pointer->events.focus_change, &event);
-}
-
-void
-ds_seat_pointer_clear_focus(struct ds_seat *seat)
-{
- ds_seat_pointer_enter(seat, NULL, 0, 0);
-}
-
-void
-ds_seat_pointer_send_motion(struct ds_seat *seat, uint32_t time_msec,
- double sx, double sy)
-{
- struct ds_seat_pointer *pointer = &seat->pointer;
- struct ds_seat_client *seat_client = pointer->focused_client;
- struct wl_resource *resource;
- wl_fixed_t sx_fixed, sy_fixed;
-
- if (!seat_client)
- return;
-
- sx_fixed = wl_fixed_from_double(sx);
- sy_fixed = wl_fixed_from_double(sy);
- if (wl_fixed_from_double(pointer->sx) != sx_fixed ||
- wl_fixed_from_double(pointer->sy) != sy_fixed) {
- wl_resource_for_each(resource, &seat_client->pointers)
- wl_pointer_send_motion(resource, time_msec, sx_fixed, sy_fixed);
- }
-
- seat_pointer_warp(seat, sx, sy);
-}
-
-uint32_t
-ds_seat_pointer_send_button(struct ds_seat *seat, uint32_t time_msec,
- uint32_t button, enum ds_button_state state)
-{
- struct ds_seat_client *seat_client = seat->pointer.focused_client;
- struct wl_resource *resource;
- uint32_t serial;
-
- if (!seat_client)
- return 0;
-
- serial = wl_display_next_serial(seat->display);
- wl_resource_for_each(resource, &seat_client->pointers)
- wl_pointer_send_button(resource, serial, time_msec, button, state);
-
- return serial;
-}
-
-void
-ds_seat_pointer_send_axis(struct ds_seat *seat, uint32_t time_msec,
- enum ds_axis_orientation orientation, double value,
- int32_t value_discrete, enum ds_axis_source source)
-{
- struct ds_seat_pointer *pointer = &seat->pointer;
- struct ds_seat_client *seat_client = pointer->focused_client;
- struct wl_resource *resource;
- uint32_t version;
- bool send_source = false;
-
- if (!seat_client)
- return;
-
- if (pointer->sent_axis_source) {
- assert(pointer->cached_axis_source == source);
- }
- else {
- pointer->sent_axis_source = true;
- pointer->cached_axis_source = source;
- send_source = true;
- }
-
- wl_resource_for_each(resource, &seat_client->pointers) {
- version = wl_resource_get_version(resource);
-
- if (send_source && version >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION)
- wl_pointer_send_axis_source(resource, source);
-
- if (value) {
- if (value_discrete &&
- version >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION) {
- wl_pointer_send_axis_discrete(resource, orientation,
- value_discrete);
- }
-
- wl_pointer_send_axis(resource, time_msec, orientation,
- wl_fixed_from_double(value));
- }
- else if (version >= WL_POINTER_AXIS_STOP_SINCE_VERSION) {
- wl_pointer_send_axis_stop(resource, time_msec, orientation);
- }
- }
-}
-
-void
-ds_seat_pointer_send_frame(struct ds_seat *seat)
-{
- struct ds_seat_pointer *pointer = &seat->pointer;
- struct ds_seat_client *seat_client = pointer->focused_client;
- struct wl_resource *resource;
-
- if (!seat_client)
- return;
-
- pointer->sent_axis_source = false;
-
- wl_resource_for_each(resource, &seat_client->pointers)
- pointer_send_frame(resource);
-}
-
-bool
-seat_pointer_init(struct ds_seat *seat)
-{
- struct ds_seat_pointer *pointer = &seat->pointer;
- struct ds_seat_pointer_grab *grab;
-
- grab = calloc(1, sizeof *grab);
- if (!grab)
- return false;
-
- grab->iface = &default_pointer_grab_iface;
- grab->seat = seat;
-
- pointer->default_grab = grab;
- pointer->grab = grab;
- pointer->seat = seat;
-
- wl_list_init(&pointer->surface_destroy.link);
-
- wl_signal_init(&pointer->events.focus_change);
-
- return true;
-}
-
-void
-seat_pointer_finish(struct ds_seat *seat)
-{
- struct ds_seat_pointer *pointer = &seat->pointer;
-
- wl_list_remove(&pointer->surface_destroy.link);
- free(pointer->default_grab);
-}
-
-void
-seat_client_add_pointer_resource(struct ds_seat_client *seat_client,
- uint32_t version, uint32_t id)
-{
- struct wl_resource *resource;
-
- resource = wl_resource_create(seat_client->wl_client,
- &wl_pointer_interface, version, id);
- if (!resource) {
- wl_client_post_no_memory(seat_client->wl_client);
- return;
- }
-
- wl_resource_set_implementation(resource, &pointer_impl, seat_client,
- &pointer_handle_resource_destroy);
-
- if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_POINTER)) {
- wl_resource_set_user_data(resource, NULL);
- return;
- }
-
- wl_list_insert(&seat_client->pointers, wl_resource_get_link(resource));
-}
-
-void
-seat_client_remove_all_pointer_resources(struct ds_seat_client *seat_client)
-{
- struct wl_resource *resource, *tmp;
-
- wl_resource_for_each_safe(resource, tmp, &seat_client->pointers) {
- wl_list_remove(wl_resource_get_link(resource));
- wl_resource_set_user_data(resource, NULL);
- }
-}
-
-static void
-seat_pointer_warp(struct ds_seat *seat, double sx, double sy)
-{
- seat->pointer.sx = sx;
- seat->pointer.sy = sy;
-}
-
-static void
-seat_client_send_pointer_leave_raw(struct ds_seat_client *seat_client,
- struct ds_surface *surface)
-{
- struct wl_resource *resource;
- uint32_t serial;
-
- serial = wl_display_next_serial(seat_client->seat->display);
- wl_resource_for_each(resource, &seat_client->pointers) {
- wl_pointer_send_leave(resource, serial,
- ds_surface_get_wl_resource(surface));
- pointer_send_frame(resource);
- }
-}
-
-static void
-seat_pointer_handle_surface_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_seat_pointer *pointer;
-
- pointer = wl_container_of(listener, pointer, surface_destroy);
- wl_list_remove(&pointer->surface_destroy.link);
- wl_list_init(&pointer->surface_destroy.link);
- ds_seat_pointer_clear_focus(pointer->seat);
-}
-
-static void
-default_pointer_grab_iface_enter(struct ds_seat_pointer_grab *grab,
- struct ds_surface *surface, double sx, double sy)
-{
- ds_seat_pointer_enter(grab->seat, surface, sx, sy);
-}
-
-static void
-default_pointer_grab_iface_clear_focus(struct ds_seat_pointer_grab *grab)
-{
- ds_seat_pointer_clear_focus(grab->seat);
-}
-
-static void
-default_pointer_grab_iface_motion(struct ds_seat_pointer_grab *grab,
- uint32_t time_msec, double sx, double sy)
-{
- ds_seat_pointer_send_motion(grab->seat, time_msec, sx, sy);
-}
-
-static uint32_t
-default_pointer_grab_iface_button(struct ds_seat_pointer_grab *grab,
- uint32_t time_msec, uint32_t button, enum ds_button_state state)
-{
- return ds_seat_pointer_send_button(grab->seat, time_msec, button, state);
-}
-
-static void
-default_pointer_grab_iface_axis(struct ds_seat_pointer_grab *grab,
- uint32_t time_msec, enum ds_axis_orientation orientation, double value,
- int32_t value_discrete, enum ds_axis_source source)
-{
- ds_seat_pointer_send_axis(grab->seat, time_msec, orientation, value,
- value_discrete, source);
-}
-
-static void
-default_pointer_grab_iface_frame(struct ds_seat_pointer_grab *grab)
-{
- ds_seat_pointer_send_frame(grab->seat);
-}
-
-static void
-default_pointer_grab_iface_cancel(struct ds_seat_pointer_grab *grab)
-{
- // cannot be cancelled
-}
-
-static const struct ds_pointer_grab_interface default_pointer_grab_iface = {
- .enter = default_pointer_grab_iface_enter,
- .clear_focus = default_pointer_grab_iface_clear_focus,
- .motion = default_pointer_grab_iface_motion,
- .button = default_pointer_grab_iface_button,
- .axis = default_pointer_grab_iface_axis,
- .frame = default_pointer_grab_iface_frame,
- .cancel = default_pointer_grab_iface_cancel,
-};
-
-static void
-pointer_handle_set_cursor(struct wl_client *client,
- struct wl_resource *pointer_resource, uint32_t serial,
- struct wl_resource *surface_resource,
- int32_t hotspot_x, int32_t hotspot_y)
-{
- struct ds_seat_client *seat_client;
-
- seat_client = wl_resource_get_user_data(pointer_resource);
- if (!seat_client)
- return;
-
- // TODO
-}
-
-static void
-pointer_handle_release(struct wl_client *client, struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static const struct wl_pointer_interface pointer_impl =
-{
- .set_cursor = pointer_handle_set_cursor,
- .release = pointer_handle_release,
-};
-
-static void pointer_handle_resource_destroy(struct wl_resource *resource)
-{
- if (!wl_resource_get_user_data(resource))
- return;
-
- wl_list_remove(wl_resource_get_link(resource));
-}
-
-static void
-pointer_send_frame(struct wl_resource *resource)
-{
- if (wl_resource_get_version(resource) >=
- WL_POINTER_FRAME_SINCE_VERSION)
- wl_pointer_send_frame(resource);
-}
+++ /dev/null
-#ifndef DS_SEAT_PRIVATE_H
-#define DS_SEAT_PRIVATE_H
-
-#include <time.h>
-#include <wayland-server.h>
-
-#include "libds/seat.h"
-#include "seat.h"
-#include "surface.h"
-
-struct ds_seat_client
-{
- struct ds_seat *seat;
- struct wl_client *wl_client;
- struct wl_list link;
-
- struct wl_list resources; // wl_seat
- struct wl_list pointers; // wl_pointer
- struct wl_list keyboards; // wl_keyboard
- struct wl_list touches; // wl_touch
-
- struct {
- struct wl_signal destroy;
- } events;
-
- bool needs_touch_frame;
-};
-
-#define DS_POINTER_BUTTONS_CAP 16
-
-struct ds_seat_pointer
-{
- struct ds_seat *seat;
- struct ds_seat_client *focused_client;
- struct ds_surface *focused_surface;
- double sx, sy;
-
- struct ds_seat_pointer_grab *grab;
- struct ds_seat_pointer_grab *default_grab;
-
- bool sent_axis_source;
- enum ds_axis_source cached_axis_source;
-
- uint32_t buttons[DS_POINTER_BUTTONS_CAP];
- size_t button_count;
- uint32_t grab_button;
- uint32_t grab_serial;
- uint32_t grab_time;
-
- struct wl_listener surface_destroy;
-
- struct {
- struct wl_signal focus_change;
- } events;
-};
-
-struct ds_seat_keyboard
-{
- struct ds_seat *seat;
-
- struct ds_seat_client *focused_client;
- struct ds_surface *focused_surface;
-
- struct wl_listener surface_destroy;
-
- struct ds_seat_keyboard_grab *grab;
- struct ds_seat_keyboard_grab *default_grab;
-
- struct {
- struct wl_signal focus_change;
- } events;
-};
-
-struct ds_touch_point
-{
- int32_t touch_id;
- struct ds_surface *surface;
- struct ds_seat_client *seat_client;
-
- struct ds_seat_client *focused_client;
- struct ds_surface *focused_surface;
- double sx, sy;
-
- struct wl_listener surface_destroy;
- struct wl_listener focused_surface_destroy;
- struct wl_listener client_destroy;
-
- struct {
- struct wl_signal destroy;
- } events;
-
- struct wl_list link;
-};
-
-struct ds_seat_touch
-{
- struct ds_seat *seat;
- struct wl_list touch_points; // ds_touch_point::link
-
- uint32_t grab_serial;
- uint32_t grab_id;
-
- struct ds_seat_touch_grab *grab;
- struct ds_seat_touch_grab *default_grab;
-};
-
-struct ds_seat
-{
- char *name;
- enum wl_seat_capability capabilities;
- enum wl_seat_capability accumulated_capabilities;
- struct timespec last_event;
-
- struct wl_display *display;
- struct wl_global *global;
-
- struct wl_list clients; // ds_seat_client::link
-
- struct ds_seat_pointer pointer;
- struct ds_seat_keyboard keyboard;
- struct ds_seat_touch touch;
-
- struct wl_listener display_destroy;
-
- struct {
- struct wl_signal destroy;
-
- struct wl_signal pointer_grab_begin;
- struct wl_signal pointer_grab_end;
-
- struct wl_signal keyboard_grab_begin;
- struct wl_signal keyboard_grab_end;
-
- struct wl_signal touch_grab_begin;
- struct wl_signal touch_grab_end;
- } events;
-};
-
-struct ds_seat_client *
-seat_client_for_wl_client(struct ds_seat *seat, struct wl_client *wl_client);
-
-bool seat_pointer_init(struct ds_seat *seat);
-
-void seat_pointer_finish(struct ds_seat *seat);
-
-void seat_client_add_pointer_resource(struct ds_seat_client *seat_client,
- uint32_t version, uint32_t id);
-
-void
-seat_client_remove_all_pointer_resources(struct ds_seat_client *seat_client);
-
-bool seat_keyboard_init(struct ds_seat *seat);
-
-void seat_keyboard_finish(struct ds_seat *seat);
-
-void seat_client_add_keyboard_resource(struct ds_seat_client *seat_client,
- uint32_t version, uint32_t id);
-
-void
-seat_client_remove_all_keyboard_resources(struct ds_seat_client *seat_client);
-
-bool seat_touch_init(struct ds_seat *seat);
-
-void seat_touch_finish(struct ds_seat *seat);
-
-void seat_client_add_touch_resource(struct ds_seat_client *seat_client,
- uint32_t version, uint32_t id);
-
-void
-seat_client_remove_all_touch_resources(struct ds_seat_client *seat_client);
-
-#endif
+++ /dev/null
-#include <assert.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-#include "seat_private.h"
-
-static const struct ds_touch_grab_interface default_touch_grab_iface;
-static const struct wl_touch_interface touch_impl;
-
-static void touch_handle_resource_destroy(struct wl_resource *resource);
-static struct ds_touch_point *touch_point_create(struct ds_seat *seat,
- int32_t touch_id, struct ds_surface *surface, double sx, double sy);
-static void touch_point_destroy(struct ds_touch_point *point);
-static void touch_point_clear_focus(struct ds_touch_point *point);
-static struct ds_touch_point *seat_find_touch_point(struct ds_seat *seat,
- int32_t touch_id);
-static int seat_touch_num_points(struct ds_seat *seat);
-
-WL_EXPORT uint32_t
-ds_seat_touch_notify_down(struct ds_seat *seat, struct ds_surface *surface,
- uint32_t time_msec, int32_t touch_id, double sx, double sy)
-{
- struct ds_seat_touch_grab *grab = seat->touch.grab;
- struct ds_touch_point *point;
- uint32_t serial;
-
- // FIXME
- // What if ds_touch_point is already exist associated with given touch_id?
- point = touch_point_create(seat, touch_id, surface, sx, sy);
- if (!point) {
- ds_err("Could not create touch point");
- return 0;
- }
-
- serial = grab->iface->down(grab, time_msec, point);
- if (!serial) {
- touch_point_destroy(point);
- return 0;
- }
-
- if (serial && seat_touch_num_points(seat) == 1) {
- seat->touch.grab_serial = serial;
- seat->touch.grab_id = touch_id;
- }
-
- return serial;
-}
-
-WL_EXPORT void
-ds_seat_touch_notify_up(struct ds_seat *seat, uint32_t time_msec,
- int32_t touch_id)
-{
- struct ds_seat_touch_grab *grab = seat->touch.grab;
- struct ds_touch_point *point;
-
- clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
-
- point = seat_find_touch_point(seat, touch_id);
- if (!point)
- return;
-
- grab->iface->up(grab, time_msec, point);
-
- touch_point_destroy(point);
-}
-
-WL_EXPORT void
-ds_seat_touch_notify_motion(struct ds_seat *seat, uint32_t time_msec,
- int32_t touch_id, double sx, double sy)
-{
- struct ds_seat_touch_grab *grab = seat->touch.grab;
- struct ds_touch_point *point;
-
- clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
-
- point = seat_find_touch_point(seat, touch_id);
- if (!point)
- return;
-
- point->sx = sx;
- point->sy = sy;
-
- grab->iface->motion(grab, time_msec, point);
-}
-
-WL_EXPORT void
-ds_seat_touch_notify_frame(struct ds_seat *seat)
-{
- struct ds_seat_touch_grab *grab = seat->touch.grab;
-
- if (grab->iface->frame)
- grab->iface->frame(grab);
-}
-
-WL_EXPORT void
-ds_seat_touch_add_grab_start_listener(struct ds_seat *seat,
- struct wl_listener *listener)
-{
- wl_signal_add(&seat->events.touch_grab_begin, listener);
-}
-
-WL_EXPORT void
-ds_seat_touch_end_grab_start_listener(struct ds_seat *seat,
- struct wl_listener *listener)
-{
- wl_signal_add(&seat->events.touch_grab_end, listener);
-}
-
-uint32_t
-ds_seat_touch_send_down(struct ds_seat *seat, struct ds_surface *surface,
- uint32_t time_msec, int32_t touch_id, double sx, double sy)
-{
- struct ds_touch_point *point;
- struct wl_resource *resource;
- uint32_t serial;
-
- point = seat_find_touch_point(seat, touch_id);
- if (!point) {
- ds_err("Got touch down for unknown touch point");
- return 0;
- }
-
- serial = wl_display_next_serial(seat->display);
- wl_resource_for_each(resource, &point->seat_client->touches) {
- wl_touch_send_down(resource, serial, time_msec,
- ds_surface_get_wl_resource(surface), touch_id,
- wl_fixed_from_double(sx), wl_fixed_from_double(sy));
- }
-
- point->seat_client->needs_touch_frame = true;
-
- return serial;
-}
-
-void
-ds_seat_touch_send_up(struct ds_seat *seat, uint32_t time_msec,
- int32_t touch_id)
-{
- struct ds_touch_point *point;
- struct wl_resource *resource;
- uint32_t serial;
-
- point = seat_find_touch_point(seat, touch_id);
- if (!point) {
- ds_err("Got touch up for unknown touch point");
- return;
- }
-
- serial = wl_display_next_serial(seat->display);
- wl_resource_for_each(resource, &point->seat_client->touches)
- wl_touch_send_up(resource, serial, time_msec, touch_id);
-
- point->seat_client->needs_touch_frame = true;
-}
-
-void
-ds_seat_touch_send_motion(struct ds_seat *seat, uint32_t time_msec,
- int32_t touch_id, double sx, double sy)
-{
- struct ds_touch_point *point;
- struct wl_resource *resource;
-
- point = seat_find_touch_point(seat, touch_id);
- if (!point) {
- ds_err("Got touch motion for unknown touch point");
- return;
- }
-
- wl_resource_for_each(resource, &point->seat_client->touches) {
- wl_touch_send_motion(resource, time_msec, touch_id,
- wl_fixed_from_double(sx), wl_fixed_from_double(sy));
- }
-
- point->seat_client->needs_touch_frame = true;
-}
-
-void
-ds_seat_touch_send_frame(struct ds_seat *seat)
-{
- struct ds_seat_client *seat_client;
- struct wl_resource *resource;
-
- wl_list_for_each(seat_client, &seat->clients, link) {
- if (!seat_client->needs_touch_frame)
- continue;
-
- wl_resource_for_each(resource, &seat_client->touches)
- wl_touch_send_frame(resource);
-
- seat_client->needs_touch_frame = false;
- }
-}
-
-bool
-seat_touch_init(struct ds_seat *seat)
-{
- struct ds_seat_touch *touch = &seat->touch;
- struct ds_seat_touch_grab *grab;
-
- grab = calloc(1, sizeof *grab);
- if (!grab)
- return false;
-
- grab->iface = &default_touch_grab_iface;
- grab->seat = seat;
-
- touch->default_grab = grab;
- touch->grab = grab;
- touch->seat = seat;
-
- wl_list_init(&touch->touch_points);
-
- return true;
-}
-
-void
-seat_touch_finish(struct ds_seat *seat)
-{
- struct ds_seat_touch *touch = &seat->touch;
- struct ds_touch_point *point;
-
- wl_list_for_each(point, &touch->touch_points, link)
- touch_point_clear_focus(point);
-
- free(touch->default_grab);
-}
-
-void
-seat_client_add_touch_resource(struct ds_seat_client *seat_client,
- uint32_t version, uint32_t id)
-{
- struct wl_resource *resource;
-
- resource = wl_resource_create(seat_client->wl_client,
- &wl_touch_interface, version, id);
- if (!resource) {
- wl_client_post_no_memory(seat_client->wl_client);
- return;
- }
-
- wl_resource_set_implementation(resource, &touch_impl, seat_client,
- touch_handle_resource_destroy);
-
- wl_list_insert(&seat_client->touches, wl_resource_get_link(resource));
-
- if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_TOUCH))
- wl_resource_set_user_data(resource, NULL);
-}
-
-void
-seat_client_remove_all_touch_resources(struct ds_seat_client *seat_client)
-{
- struct wl_resource *resource, *tmp;
-
- wl_resource_for_each_safe(resource, tmp, &seat_client->touches) {
- wl_list_remove(wl_resource_get_link(resource));
- wl_resource_set_user_data(resource, NULL);
- }
-}
-
-static uint32_t
-default_touch_grab_iface_down(struct ds_seat_touch_grab *grab,
- uint32_t time_msec, struct ds_touch_point *point)
-{
- return ds_seat_touch_send_down(grab->seat, point->surface, time_msec,
- point->touch_id, point->sx, point->sy);
-}
-
-static void
-default_touch_grab_iface_up(struct ds_seat_touch_grab *grab,
- uint32_t time_msec, struct ds_touch_point *point)
-{
- ds_seat_touch_send_up(grab->seat, time_msec, point->touch_id);
-}
-
-static void
-default_touch_grab_iface_motion(struct ds_seat_touch_grab *grab,
- uint32_t time_msec, struct ds_touch_point *point)
-{
- if (!point->focused_surface || point->focused_surface == point->surface) {
- ds_seat_touch_send_motion(grab->seat, time_msec, point->touch_id,
- point->sx, point->sy);
- }
-}
-
-static void
-default_touch_grab_iface_enter(struct ds_seat_touch_grab *grab,
- uint32_t time_msec, struct ds_touch_point *point)
-{
- // not handled by default
-}
-
-static void
-default_touch_grab_iface_frame(struct ds_seat_touch_grab *grab)
-{
- ds_seat_touch_send_frame(grab->seat);
-}
-
-static void
-default_touch_grab_iface_cancel(struct ds_seat_touch_grab *grab)
-{
- // cannot be cancelled
-}
-
-static const struct ds_touch_grab_interface default_touch_grab_iface = {
- .down = default_touch_grab_iface_down,
- .up = default_touch_grab_iface_up,
- .motion = default_touch_grab_iface_motion,
- .enter = default_touch_grab_iface_enter,
- .frame = default_touch_grab_iface_frame,
- .cancel = default_touch_grab_iface_cancel,
-};
-
-static void
-touch_handle_release(struct wl_client *client, struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static const struct wl_touch_interface touch_impl =
-{
- .release = touch_handle_release,
-};
-
-static void
-touch_handle_resource_destroy(struct wl_resource *resource)
-{
- if (!wl_resource_get_user_data(resource))
- return;
-
- wl_list_remove(wl_resource_get_link(resource));
-}
-
-static void
-touch_point_handle_surface_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_touch_point *point;
-
- point = wl_container_of(listener, point, surface_destroy);
- point->surface = NULL;
- wl_list_remove(&point->surface_destroy.link);
- wl_list_init(&point->surface_destroy.link);
-}
-
-static void
-touch_point_handle_client_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_touch_point *point;
-
- point = wl_container_of(listener, point, surface_destroy);
- touch_point_destroy(point);
-}
-
-static struct ds_touch_point *
-touch_point_create(struct ds_seat *seat, int32_t touch_id,
- struct ds_surface *surface, double sx, double sy)
-{
- struct ds_touch_point *point;
- struct ds_seat_client *seat_client;
- struct wl_client *wl_client;
-
- wl_client = wl_resource_get_client(ds_surface_get_wl_resource(surface));
- seat_client = seat_client_for_wl_client(seat, wl_client);
- if (!seat_client || wl_list_empty(&seat_client->touches))
- return NULL;
-
- point = calloc(1, sizeof *point);
- if (!point)
- return NULL;
-
- point->touch_id = touch_id;
- point->surface = surface;
- point->seat_client = seat_client;
- point->sx = sx;
- point->sy = sy;
-
- wl_signal_init(&point->events.destroy);
-
- point->surface_destroy.notify = touch_point_handle_surface_destroy;
- ds_surface_add_destroy_listener(surface, &point->surface_destroy);
-
- point->client_destroy.notify = touch_point_handle_client_destroy;
- wl_signal_add(&seat_client->events.destroy, &point->client_destroy);
-
- wl_list_insert(&seat->touch.touch_points, &point->link);
-
- return point;
-}
-
-static void
-touch_point_destroy(struct ds_touch_point *point)
-{
- wl_signal_emit(&point->events.destroy, point);
-
- touch_point_clear_focus(point);
-
- wl_list_remove(&point->surface_destroy.link);
- wl_list_remove(&point->client_destroy.link);
- wl_list_remove(&point->link);
- free(point);
-}
-
-static void
-touch_point_clear_focus(struct ds_touch_point *point)
-{
- if (!point->focused_surface)
- return;
-
- wl_list_remove(&point->focused_surface_destroy.link);
- point->focused_client = NULL;
- point->focused_surface = NULL;
-}
-
-static struct ds_touch_point *seat_find_touch_point(struct ds_seat *seat,
- int32_t touch_id)
-{
- struct ds_touch_point *point;
-
- wl_list_for_each(point, &seat->touch.touch_points, link) {
- if (point->touch_id == touch_id)
- return point;
- }
-
- return NULL;
-}
-
-static int
-seat_touch_num_points(struct ds_seat *seat)
-{
- return wl_list_length(&seat->touch.touch_points);
-}
+++ /dev/null
-#include <assert.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-#include "libds/shell.h"
-
-#include "shell.h"
-
-#define WL_SHELL_VERSION 1
-#define SHELL_PING_TIMEOUT 10000
-
-static void shell_handle_display_destroy(struct wl_listener *listener,
- void *data);
-static void shell_bind(struct wl_client *wl_client, void *data,
- uint32_t verison, uint32_t id);
-
-WL_EXPORT struct ds_shell *
-ds_shell_create(struct wl_display *display)
-{
- struct ds_shell *shell;
-
- shell = calloc(1, sizeof *shell);
- if (!shell) {
- return NULL;
- }
-
- shell->global = wl_global_create(display, &wl_shell_interface,
- WL_SHELL_VERSION, shell, shell_bind);
- if (!shell->global) {
- free(shell);
- return NULL;
- }
-
- wl_list_init(&shell->clients);
-
- shell->display_destroy.notify = shell_handle_display_destroy;
- wl_display_add_destroy_listener(display, &shell->display_destroy);
-
- wl_signal_init(&shell->events.destroy);
- wl_signal_init(&shell->events.new_surface);
-
- shell->ping_timeout = SHELL_PING_TIMEOUT;
-
- ds_inf("Global created: xdg_wm_base shell(%p)", shell);
-
- return shell;
-}
-
-WL_EXPORT void
-ds_shell_add_destroy_listener(struct ds_shell *shell,
- struct wl_listener *listener)
-{
- wl_signal_add(&shell->events.destroy, listener);
-}
-
-WL_EXPORT void
-ds_shell_add_new_surface_listener(struct ds_shell *shell,
- struct wl_listener *listener)
-{
- wl_signal_add(&shell->events.new_surface, listener);
-}
-
-static void
-shell_handle_display_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_shell *shell;
-
- shell = wl_container_of(listener, shell, display_destroy);
-
- ds_inf("Global destroy: xdg_wm_base shell(%p)", shell);
-
- wl_signal_emit(&shell->events.destroy, shell);
- wl_list_remove(&shell->display_destroy.link);
- wl_global_destroy(shell->global);
- free(shell);
-}
-
-static void
-shell_handle_get_shell_surface(struct wl_client *wl_client,
- struct wl_resource *resource, uint32_t id,
- struct wl_resource *surface_resource)
-{
- struct ds_shell_client *client;
- struct ds_surface *surface;
-
- client = wl_resource_get_user_data(resource);
- surface = ds_surface_from_resource(surface_resource);
- create_shell_surface(client, surface, id);
-}
-
-static const struct wl_shell_interface shell_impl =
-{
- .get_shell_surface = shell_handle_get_shell_surface,
-};
-
-static void
-shell_client_handle_resource_destroy(struct wl_resource *resource)
-{
- struct ds_shell_client *client;
- struct ds_shell_surface *shell_surface, *tmp;
-
- client = wl_resource_get_user_data(resource);
-
- wl_list_for_each_safe(shell_surface, tmp, &client->shell_surfaces, link)
- destroy_shell_surface(shell_surface);
-
- if (client->ping_timer != NULL)
- wl_event_source_remove(client->ping_timer);
-
- wl_list_remove(&client->link);
- free(client);
-}
-
-static int
-shell_client_handle_ping_timeout(void *user_data)
-{
- struct ds_shell_client *client = user_data;
- struct ds_shell_surface *surface;
-
- wl_list_for_each(surface, &client->shell_surfaces, link)
- wl_signal_emit(&surface->events.ping_timeout, surface);
-
- client->ping_serial = 0;
-
- return 1;
-}
-
-static void
-shell_client_init_ping_timer(struct ds_shell_client *client)
-{
- struct wl_display *display;
- struct wl_event_loop *loop;
-
- display = wl_client_get_display(client->wl_client);
- loop = wl_display_get_event_loop(display);
- client->ping_timer = wl_event_loop_add_timer(loop,
- shell_client_handle_ping_timeout, client);
- if (client->ping_timer == NULL)
- wl_client_post_no_memory(client->wl_client);
-}
-
-static void
-shell_bind(struct wl_client *wl_client, void *data, uint32_t version,
- uint32_t id)
-{
- struct ds_shell *shell = data;
- struct ds_shell_client *client;
-
- client = calloc(1, sizeof *client);
- if (client == NULL) {
- wl_client_post_no_memory(wl_client);
- return;
- }
-
- client->wl_client = wl_client;
- client->shell = shell;
-
- wl_list_init(&client->shell_surfaces);
-
- client->resource =
- wl_resource_create(wl_client, &wl_shell_interface, version, id);
- if (client->resource == NULL) {
- free(client);
- wl_client_post_no_memory(wl_client);
- return;
- }
-
- wl_resource_set_implementation(client->resource, &shell_impl, client,
- shell_client_handle_resource_destroy);
-
- wl_list_insert(&shell->clients, &client->link);
-
- shell_client_init_ping_timer(client);
-}
+++ /dev/null
-#ifndef DS_SHELL_H
-#define DS_SHELL_H
-
-#include <wayland-server.h>
-
-#include "libds/output.h"
-
-#include "surface.h"
-
-enum ds_shell_surface_role
-{
- DS_SHELL_SURFACE_ROLE_NONE,
- DS_SHELL_SURFACE_ROLE_TOPLEVEL,
- DS_SHELL_SURFACE_ROLE_POPUP,
-};
-
-struct ds_shell
-{
- struct wl_global *global;
-
- struct wl_list clients;
-
- struct wl_listener display_destroy;
-
- struct {
- struct wl_signal destroy;
- struct wl_signal new_surface;
- } events;
-
- uint32_t ping_timeout;
-};
-
-struct ds_shell_client
-{
- struct ds_shell *shell;
-
- struct wl_resource *resource;
- struct wl_client *wl_client;
- struct wl_event_source *ping_timer;
-
- struct wl_list shell_surfaces;
-
- struct wl_list link; // ds_shell::clients
-
- uint32_t ping_serial;
-};
-
-struct ds_shell_toplevel_state
-{
- bool maximized, fullscreen, resizing, activated;
- uint32_t tiled;
- uint32_t width, height;
- uint32_t max_width, max_height;
- uint32_t min_width, min_height;
-};
-
-struct ds_shell_toplevel_requested
-{
- bool maximized, minimized, fullscreen;
- struct ds_output *fullscreen_output;
- struct wl_listener fullscreen_output_destroy;
-};
-
-struct ds_shell_toplevel
-{
- struct ds_shell_surface *base;
- bool added;
-
- struct ds_shell_surface *parent;
- struct wl_listener parent_unmap;
-
- struct ds_shell_toplevel_state current, pending;
- struct ds_shell_toplevel_requested requested;
-
- char *title;
- char *app_id;
-
- struct {
- struct wl_signal request_maximize;
- struct wl_signal request_fullscreen;
- struct wl_signal request_minimize;
- struct wl_signal request_move;
- struct wl_signal request_resize;
- struct wl_signal request_show_window_menu;
- struct wl_signal set_parent;
- struct wl_signal set_title;
- struct wl_signal set_app_id;
- } events;
-};
-
-struct ds_xdg_popup
-{
-
-};
-
-struct ds_shell_surface_state
-{
- uint32_t configure_serial;
- struct {
- int x, y;
- int width, height;
- } geometry;
-};
-
-struct ds_shell_surface
-{
- struct ds_shell_client *client;
- struct ds_surface *surface;
-
- enum ds_shell_surface_role role;
-
- union {
- struct ds_shell_toplevel *toplevel;
- struct ds_xdg_popup *popup;
- };
-
- struct wl_resource *resource;
-
- struct wl_event_source *configure_idle;
- uint32_t scheduled_serial;
- struct wl_list configure_list;
-
- struct ds_shell_surface_state current, pending;
-
- struct wl_list link; // ds_shell_client::surfaces
-
- struct {
- struct wl_listener surface_destroy;
- struct wl_listener surface_commit;
- } listener;
-
- struct {
- struct wl_signal destroy;
- struct wl_signal ping_timeout;
- struct wl_signal new_popup;
- struct wl_signal map;
- struct wl_signal unmap;
- struct wl_signal configure;
- } events;
-
- bool added, configured, mapped;
-};
-
-struct ds_shell_surface_configure
-{
- struct ds_shell_surface *shell_surface;
- struct wl_list link;
- uint32_t serial;
-};
-
-struct ds_shell_surface *
-create_shell_surface(struct ds_shell_client *client, struct ds_surface *surface,
- uint32_t id);
-
-void destroy_shell_surface(struct ds_shell_surface *surface);
-
-#endif
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libds/log.h"
-
-#include "shell.h"
-
-static const struct wl_shell_surface_interface shell_surface_impl;
-
-static void reset_shell_surface(struct ds_shell_surface *shell_surface);
-static void shell_surface_handle_surface_destroy(struct wl_listener *listener,
- void *data);
-static void shell_surface_handle_surface_commit(struct wl_listener *listener,
- void *data);
-static void shell_surface_handle_resource_destroy(struct wl_resource *resource);
-static void shell_surface_configure_destroy(struct ds_shell_surface_configure *configure);
-static void surface_send_configure(void *user_data);
-static void handle_shell_surface_commit(struct ds_surface *surface);
-
-WL_EXPORT void
-ds_shell_surface_add_destroy_listener(struct ds_shell_surface *shell_surface,
- struct wl_listener *listener)
-{
- wl_signal_add(&shell_surface->events.destroy, listener);
-}
-
-WL_EXPORT void
-ds_shell_surface_add_map_listener(struct ds_shell_surface *shell_surface,
- struct wl_listener *listener)
-{
- wl_signal_add(&shell_surface->events.map, listener);
-}
-
-WL_EXPORT void
-ds_shell_surface_add_unmap_listener(struct ds_shell_surface *shell_surface,
- struct wl_listener *listener)
-{
- wl_signal_add(&shell_surface->events.unmap, listener);
-}
-
-WL_EXPORT struct ds_surface *
-ds_shell_surface_get_surface(struct ds_shell_surface *shell_surface)
-{
- return shell_surface->surface;
-}
-
-static const struct ds_surface_role shell_surface_role =
-{
- .name = "shell_surface",
- .commit = handle_shell_surface_commit,
-};
-
-struct ds_shell_surface *
-create_shell_surface(struct ds_shell_client *client, struct ds_surface *surface,
- uint32_t id)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = calloc(1, sizeof *shell_surface);
- if (!shell_surface) {
- wl_client_post_no_memory(client->wl_client);
- return NULL;
- }
-
- shell_surface->client = client;
- shell_surface->role = DS_SHELL_SURFACE_ROLE_NONE;
- shell_surface->surface = surface;
- shell_surface->resource = wl_resource_create(client->wl_client,
- &wl_shell_surface_interface, wl_resource_get_version(client->resource),
- id);
- if (!shell_surface->resource) {
- free(shell_surface);
- wl_client_post_no_memory(client->wl_client);
- return NULL;
- }
-
- if (!ds_surface_set_role(shell_surface->surface, &shell_surface_role,
- shell_surface, shell_surface->resource, -1)) {
- free(shell_surface);
- return NULL;
- }
-
- wl_list_init(&shell_surface->configure_list);
-
- wl_signal_init(&shell_surface->events.destroy);
- wl_signal_init(&shell_surface->events.ping_timeout);
- wl_signal_init(&shell_surface->events.new_popup);
- wl_signal_init(&shell_surface->events.map);
- wl_signal_init(&shell_surface->events.unmap);
- wl_signal_init(&shell_surface->events.configure);
-
- shell_surface->listener.surface_destroy.notify =
- shell_surface_handle_surface_destroy;
- ds_surface_add_destroy_listener(surface,
- &shell_surface->listener.surface_destroy);
-
- shell_surface->listener.surface_commit.notify =
- shell_surface_handle_surface_commit;
- ds_surface_add_commit_listener(surface,
- &shell_surface->listener.surface_commit);
-
- wl_resource_set_implementation(shell_surface->resource, &shell_surface_impl,
- shell_surface, shell_surface_handle_resource_destroy);
-
- wl_list_insert(&client->shell_surfaces, &shell_surface->link);
-
- ds_inf("New shell_surface %p (res %p)", shell_surface, shell_surface->resource);
-
- return shell_surface;
-}
-
-void
-destroy_shell_surface(struct ds_shell_surface *shell_surface)
-{
- reset_shell_surface(shell_surface);
-
- wl_resource_set_user_data(shell_surface->resource, NULL);
-
- ds_surface_reset_role_data(shell_surface->surface);
-
- wl_list_remove(&shell_surface->link);
- wl_list_remove(&shell_surface->listener.surface_destroy.link);
- wl_list_remove(&shell_surface->listener.surface_commit.link);
-
- free(shell_surface);
-}
-
-static void
-unmap_shell_surface(struct ds_shell_surface *shell_surface)
-{
- struct ds_shell_surface_configure *configure, *tmp;
-
- // TODO handle popup
-
- if (shell_surface->mapped)
- wl_signal_emit(&shell_surface->events.unmap, shell_surface);
-
- switch (shell_surface->role) {
- case DS_SHELL_SURFACE_ROLE_TOPLEVEL:
- if (shell_surface->toplevel->parent) {
- wl_list_remove(&shell_surface->toplevel->parent_unmap.link);
- shell_surface->toplevel->parent = NULL;
- }
- free(shell_surface->toplevel->title);
- shell_surface->toplevel->title = NULL;
- free(shell_surface->toplevel->app_id);
- shell_surface->toplevel->app_id = NULL;
- break;
- case DS_SHELL_SURFACE_ROLE_POPUP:
- // TODO
- break;
- case DS_SHELL_SURFACE_ROLE_NONE:
- assert(false && "not reached");
- }
-
- wl_list_for_each_safe(configure, tmp, &shell_surface->configure_list, link)
- shell_surface_configure_destroy(configure);
-
- if (shell_surface->configure_idle) {
- wl_event_source_remove(shell_surface->configure_idle);
- shell_surface->configure_idle = NULL;
- }
-
- shell_surface->configured = false;
- shell_surface->mapped = false;
-}
-
-static void
-reset_shell_surface(struct ds_shell_surface *shell_surface)
-{
- struct ds_shell_toplevel_requested *req;
-
- if (shell_surface->role != DS_SHELL_SURFACE_ROLE_NONE)
- unmap_shell_surface(shell_surface);
-
- if (shell_surface->added) {
- wl_signal_emit(&shell_surface->events.destroy, shell_surface);
- shell_surface->added = false;
- }
-
- switch (shell_surface->role) {
- case DS_SHELL_SURFACE_ROLE_TOPLEVEL:
- req = &shell_surface->toplevel->requested;
- if (req->fullscreen_output)
- wl_list_remove(&req->fullscreen_output_destroy.link);
- free(shell_surface->toplevel);
- shell_surface->toplevel = NULL;
- break;
- case DS_SHELL_SURFACE_ROLE_POPUP:
- // TODO
- break;
- case DS_SHELL_SURFACE_ROLE_NONE:
- // This space is intentionally left blank
- break;
- }
-
- shell_surface->role = DS_SHELL_SURFACE_ROLE_NONE;
-}
-
-static uint32_t
-ds_shell_surface_schedule_configure(struct ds_shell_surface *shell_surface)
-{
- struct wl_display *display;
- struct wl_event_loop *loop;
-
- display = wl_client_get_display(shell_surface->client->wl_client);
- loop = wl_display_get_event_loop(display);
-
- if (!shell_surface->configure_idle) {
- shell_surface->scheduled_serial = wl_display_next_serial(display);
- shell_surface->configure_idle = wl_event_loop_add_idle(loop,
- surface_send_configure, shell_surface);
- if (!shell_surface->configure_idle)
- wl_client_post_no_memory(shell_surface->client->wl_client);
- }
-
- return shell_surface->scheduled_serial;
-}
-
-static void
-handle_shell_surface_commit(struct ds_surface *surface)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = ds_surface_get_role_data(surface);
- shell_surface->current = shell_surface->pending;
-
- switch (shell_surface->role) {
- case DS_SHELL_SURFACE_ROLE_NONE:
- // inert toplevel or popup
- break;
- case DS_SHELL_SURFACE_ROLE_TOPLEVEL:
- if (!shell_surface->toplevel->added) {
- ds_shell_surface_schedule_configure(shell_surface);
- shell_surface->toplevel->added = true;
- }
- // TODO
- break;
- case DS_SHELL_SURFACE_ROLE_POPUP:
- // TODO
- break;
- }
-
- if (!shell_surface->added) {
- shell_surface->added = true;
- wl_signal_emit(&shell_surface->client->shell->events.new_surface, shell_surface);
- }
-
- if (shell_surface->configured &&
- ds_surface_has_buffer(shell_surface->surface) &&
- !shell_surface->mapped) {
- shell_surface->mapped = true;
- wl_signal_emit(&shell_surface->events.map, shell_surface);
- }
-}
-
-void handle_shell_surface_precommit(struct ds_surface *surface)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = ds_surface_get_role_data(surface);
-
- // TODO
- (void)shell_surface;
-}
-
-void
-ds_shell_surface_ping(struct ds_shell_surface *shell_surface)
-{
-}
-
-static void
-shell_surface_handle_surface_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = wl_container_of(listener, shell_surface, listener.surface_destroy);
- destroy_shell_surface(shell_surface);
-}
-
-static void
-shell_surface_handle_surface_commit(struct wl_listener *listener, void *data)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = wl_container_of(listener, shell_surface, listener.surface_commit);
-
- if (ds_surface_has_buffer(shell_surface->surface) &&
- !shell_surface->configured) {
- wl_resource_post_error(shell_surface->resource,
- -1,
- "shell_surface has never been configured");
- return;
- }
-
- if (!ds_surface_get_role(shell_surface->surface)) {
- wl_resource_post_error(shell_surface->resource,
- -1,
- "shell_surface must have a role");
- return;
- }
-}
-
-static void
-shell_surface_handle_resource_destroy(struct wl_resource *resource)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = wl_resource_get_user_data(resource);
- if (!shell_surface)
- return;
-
- destroy_shell_surface(shell_surface);
-}
-
-static void
-shell_surface_configure_destroy(struct ds_shell_surface_configure *configure)
-{
- wl_list_remove(&configure->link);
- free(configure);
-}
-
-static void
-create_shell_surface_toplevel(struct ds_shell_surface *shell_surface)
-{
- assert(shell_surface->toplevel == NULL);
-
- shell_surface->toplevel = calloc(1, sizeof *shell_surface->toplevel);
- if (!shell_surface->toplevel) {
- wl_resource_post_no_memory(shell_surface->resource);
- return;
- }
-
- shell_surface->toplevel->base = shell_surface;
-
- wl_signal_init(&shell_surface->toplevel->events.request_maximize);
- wl_signal_init(&shell_surface->toplevel->events.request_fullscreen);
- wl_signal_init(&shell_surface->toplevel->events.request_minimize);
- wl_signal_init(&shell_surface->toplevel->events.request_move);
- wl_signal_init(&shell_surface->toplevel->events.request_resize);
- wl_signal_init(&shell_surface->toplevel->events.request_show_window_menu);
- wl_signal_init(&shell_surface->toplevel->events.set_parent);
- wl_signal_init(&shell_surface->toplevel->events.set_title);
- wl_signal_init(&shell_surface->toplevel->events.set_app_id);
-
- shell_surface->role = DS_SHELL_SURFACE_ROLE_TOPLEVEL;
-}
-
-static void
-shell_surface_handle_pong(struct wl_client *wl_client,
- struct wl_resource *resource, uint32_t serial)
-{
- struct ds_shell_surface *shell_surface;
- struct ds_shell_client *client;
-
- shell_surface = wl_resource_get_user_data(resource);
-
- client = shell_surface->client;
- if (client->ping_serial != serial)
- return;
-
- wl_event_source_timer_update(client->ping_timer, 0);
- client->ping_serial = 0;
-}
-
-static void
-shell_surface_handle_move(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *seat_resource,
- uint32_t serial)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = wl_resource_get_user_data(resource);
-
- // TODO
- (void)shell_surface;
-}
-
-static void
-shell_surface_handle_resize(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *seat_resource,
- uint32_t serial, uint32_t edges)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = wl_resource_get_user_data(resource);
-
- // TODO
- (void)shell_surface;
-}
-
-static void
-shell_surface_handle_set_toplevel(struct wl_client *client, struct wl_resource *resource)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = wl_resource_get_user_data(resource);
- create_shell_surface_toplevel(shell_surface);
-}
-
-static void
-shell_surface_handle_set_transient(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *parent_resource,
- int32_t x, int32_t y, uint32_t flags)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = wl_resource_get_user_data(resource);
-
- // TODO
- (void)shell_surface;
- ds_err("Not implemented yet.");
-}
-
-static void
-shell_surface_handle_set_fullscreen(struct wl_client *client,
- struct wl_resource *resource, uint32_t method, uint32_t framerate,
- struct wl_resource *output_resource)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = wl_resource_get_user_data(resource);
-
- // TODO
- (void)shell_surface;
- ds_err("Not implemented yet.");
-}
-
-static void
-shell_surface_handle_set_popup(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *seat_resource,
- uint32_t serial, struct wl_resource *parent_resource,
- int32_t x, int32_t y, uint32_t flags)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = wl_resource_get_user_data(resource);
-
- // TODO
- (void)shell_surface;
- ds_err("Not implemented yet.");
-}
-
-static void
-shell_surface_handle_set_maximized(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *output_resource)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = wl_resource_get_user_data(resource);
-
- shell_surface->toplevel->requested.maximized = true;
- wl_signal_emit(&shell_surface->toplevel->events.request_maximize, shell_surface);
- ds_shell_surface_schedule_configure(shell_surface);
-}
-
-static void
-shell_surface_handle_set_title(struct wl_client *client,
- struct wl_resource *resource, const char *title)
-{
- struct ds_shell_surface *shell_surface;
- char *tmp;
-
- shell_surface = wl_resource_get_user_data(resource);
- tmp = strdup(title);
- if (!tmp) {
- wl_resource_post_no_memory(resource);
- return;
- }
-
- if (shell_surface->toplevel->title)
- free(shell_surface->toplevel->title);
-
- shell_surface->toplevel->title = tmp;
- wl_signal_emit(&shell_surface->toplevel->events.set_title, shell_surface);
-}
-
-static void
-shell_surface_handle_set_class(struct wl_client *client,
- struct wl_resource *resource, const char *clas)
-{
- struct ds_shell_surface *shell_surface;
-
- shell_surface = wl_resource_get_user_data(resource);
-
- // TODO
- (void)shell_surface;
- ds_err("Not implemented yet.");
-}
-
-static const struct wl_shell_surface_interface shell_surface_impl =
-{
- .pong = shell_surface_handle_pong,
- .move = shell_surface_handle_move,
- .resize = shell_surface_handle_resize,
- .set_toplevel = shell_surface_handle_set_toplevel,
- .set_transient = shell_surface_handle_set_transient,
- .set_fullscreen = shell_surface_handle_set_fullscreen,
- .set_popup = shell_surface_handle_set_popup,
- .set_maximized = shell_surface_handle_set_maximized,
- .set_title = shell_surface_handle_set_title,
- .set_class = shell_surface_handle_set_class,
-};
-
-static void
-surface_send_configure(void *user_data)
-{
- struct ds_shell_surface *shell_surface;
- struct ds_shell_surface_configure *configure;
- uint32_t width, height;
- uint32_t edges = 0;
-
- shell_surface = user_data;
- shell_surface->configure_idle = NULL;
-
- // TDOO: Not sure if shell needs the struct ds_shell_surface_configure.
- configure = calloc(1, sizeof *configure);
- if (!configure) {
- wl_client_post_no_memory(shell_surface->client->wl_client);
- return;
- }
-
- wl_list_insert(shell_surface->configure_list.prev, &configure->link);
- configure->serial = shell_surface->scheduled_serial;
- configure->shell_surface = shell_surface;
-
- wl_signal_emit(&shell_surface->events.configure, configure);
-
- edges = (WL_SHELL_SURFACE_RESIZE_TOP | WL_SHELL_SURFACE_RESIZE_LEFT); // fixed default value
- width = shell_surface->current.geometry.width;
- height = shell_surface->current.geometry.height;
-
- wl_shell_surface_send_configure(shell_surface->resource, edges, width, height);
-
- shell_surface->configured = true;
-
- // TDOO: Not sure if shell needs the struct ds_shell_surface_configure.
- shell_surface_configure_destroy(configure);
-}
+++ /dev/null
-#include "libds/log.h"
-
-#include "subcompositor.h"
-#include "surface.h"
-
-#define SUBCOMPOSITOR_VERSION 1
-
-static void subcompositor_bind(struct wl_client *client, void *data,
- uint32_t version, uint32_t id);
-
-bool
-ds_subcompositor_init(struct ds_subcompositor *subcomp,
- struct wl_display *display)
-{
- subcomp->global = wl_global_create(display, &wl_subcompositor_interface,
- SUBCOMPOSITOR_VERSION, subcomp, subcompositor_bind);
- if (!subcomp->global) {
- ds_log_errno(DS_ERR, "Could not create global");
- return false;
- }
-
- return true;
-}
-
-void
-ds_subcompositor_finish(struct ds_subcompositor *subcomp)
-{
- wl_global_destroy(subcomp->global);
-}
-
-static void
-subcompositor_handle_destroy(struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static void
-subcompositor_handle_get_subsurface(struct wl_client *client,
- struct wl_resource *resource, uint32_t id,
- struct wl_resource *surface_resource,
- struct wl_resource *parent_resource)
-{
- struct ds_surface *surface, *parent;
-
- surface = ds_surface_from_resource(surface_resource);
- parent = ds_surface_from_resource(parent_resource);
- if (surface == parent) {
- ds_inf("ds_surface(%p) cannot be its own parent", surface);
- wl_resource_post_error(resource,
- WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
- "%d: wl_surface@%d cannot be its own parent",
- id, wl_resource_get_id(surface_resource));
- return;
- }
-
- if (ds_surface_is_subsurface(surface)) {
- ds_inf("ds_surface(%p) is already a sub-surface", surface);
- wl_resource_post_error(resource,
- WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
- "%d: wl_surface@%d is already a sub-surface",
- id, wl_resource_get_id(surface_resource));
- return;
- }
-
- if (ds_surface_is_ancestor_of(surface, parent)) {
- ds_inf("ds_surface(%p) is an ancestor of given parent(%p)",
- surface, parent);
- wl_resource_post_error(resource,
- WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
- "%d: wl_surface@%d is an ancestor of parent",
- id, wl_resource_get_id(surface_resource));
- return;
- }
-
- ds_subsurface_create(resource, surface, parent,
- wl_resource_get_version(resource), id);
-}
-
-static const struct wl_subcompositor_interface subcompositor_impl =
-{
- .destroy = subcompositor_handle_destroy,
- .get_subsurface = subcompositor_handle_get_subsurface,
-};
-
-static void
-subcompositor_bind(struct wl_client *client, void *data,
- uint32_t version, uint32_t id)
-{
- struct ds_subcompositor *subcomp = data;
- struct wl_resource *resource;
-
- resource = wl_resource_create(client, &wl_subcompositor_interface, 1, id);
- if (resource == NULL) {
- wl_client_post_no_memory(client);
- return;
- }
-
- wl_resource_set_implementation(resource, &subcompositor_impl,
- subcomp, NULL);
-}
+++ /dev/null
-#ifndef DS_SUBCOMPOSITOR_H
-#define DS_SUBCOMPOSITOR_H
-
-#include <wayland-server.h>
-
-struct ds_subcompositor
-{
- struct wl_global *global;
-};
-
-bool
-ds_subcompositor_init(struct ds_subcompositor *subcomp,
- struct wl_display *display);
-
-void
-ds_subcompositor_finish(struct ds_subcompositor *subcomp);
-
-#endif
+++ /dev/null
-#ifndef DS_SURFACE_H
-#define DS_SURFACE_H
-
-#include <wayland-server.h>
-
-#include "libds/surface.h"
-
-struct ds_surface_role
-{
- const char *name;
- void (*commit)(struct ds_surface *surface);
-};
-
-struct ds_surface *
-ds_surface_create(struct wl_client *client, uint32_t version, uint32_t id);
-
-struct ds_surface *
-ds_surface_from_resource(struct wl_resource *resource);
-
-bool
-ds_surface_set_role(struct ds_surface *surface,
- const struct ds_surface_role *role, void *role_data,
- struct wl_resource *error_resource, uint32_t error_code);
-
-const struct ds_surface_role *
-ds_surface_get_role(struct ds_surface *surface);
-
-void *
-ds_surface_get_role_data(struct ds_surface *surface);
-
-void
-ds_surface_reset_role_data(struct ds_surface *surface);
-
-bool
-ds_surface_has_buffer(struct ds_surface *surface);
-
-bool
-ds_surface_is_ancestor_of(struct ds_surface *surface,
- struct ds_surface *target_surface);
-
-bool
-ds_surface_is_subsurface(struct ds_surface *surface);
-
-struct ds_subsurface *
-ds_subsurface_create(struct wl_resource *subcomp_resource,
- struct ds_surface *surface, struct ds_surface *parent,
- uint32_t version, uint32_t id);
-
-struct wl_resource *
-ds_surface_get_wl_resource(struct ds_surface *surface);
-
-#endif
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-#include "libds/surface.h"
-
-#include "surface-private.h"
-
-static const struct wl_subsurface_interface subsurface_impl;
-static const struct ds_surface_role subsurface_role;
-
-static void subsurface_handle_resource_destroy(struct wl_resource *resource);
-static void subsurface_handle_surface_destroy(struct wl_listener *listener,
- void *data);
-static void subsurface_link_surface(struct ds_subsurface *subsurface,
- struct ds_surface *surface);
-static void subsurface_unlink_surface(struct ds_subsurface *subsurface);
-static void subsurface_link_parent(struct ds_subsurface *subsurface,
- struct ds_surface *parent);
-static void subsurface_unlink_parent(struct ds_subsurface *subsurface);
-static struct ds_subsurface *subsurface_find_sibling(struct ds_subsurface *subsurface,
- struct ds_surface *surface);
-
-struct ds_subsurface *
-ds_subsurface_create(struct wl_resource *subcomp_resource,
- struct ds_surface *surface, struct ds_surface *parent,
- uint32_t version, uint32_t id)
-{
- struct wl_client *client;
- struct ds_subsurface *subsurface;
-
- client = wl_resource_get_client(subcomp_resource);
-
- subsurface = calloc(1, sizeof *subsurface);
- if (!subsurface) {
- ds_log_errno(DS_ERR, "Could not allocate memory");
- wl_client_post_no_memory(client);
- return NULL;
- }
-
- if (!ds_surface_set_role(surface, &subsurface_role, subsurface,
- subcomp_resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE)) {
- free(subsurface);
- return NULL;
- }
-
- subsurface->resource = wl_resource_create(client, &wl_subsurface_interface,
- version, id);
- if (!subsurface->resource) {
- ds_log_errno(DS_ERR, "Could not create resource");
- free(subsurface);
- wl_client_post_no_memory(client);
- return NULL;
- }
- wl_resource_set_implementation(subsurface->resource, &subsurface_impl,
- subsurface, subsurface_handle_resource_destroy);
-
- subsurface->synchronized = true;
-
- wl_signal_init(&subsurface->events.destroy);
-
- subsurface_link_surface(subsurface, surface);
- subsurface_link_parent(subsurface, parent);
-
- ds_inf("New ds_subsurface %p: surface %p, parent surface %p",
- subsurface, surface, parent);
-
- wl_signal_emit(&parent->events.new_subsurface, subsurface);
-
- return subsurface;
-}
-
-bool
-ds_surface_is_subsurface(struct ds_surface *surface)
-{
- return ds_surface_get_role(surface) == &subsurface_role;
-}
-
-struct ds_subsurface *
-ds_subsurface_from_ds_surface(struct ds_surface *surface)
-{
- assert(ds_surface_is_subsurface(surface));
- return (struct ds_subsurface *)surface->role_data;
-}
-
-struct ds_surface *
-ds_subsurface_get_parent(struct ds_subsurface *subsurface)
-{
- return subsurface->parent;
-}
-
-static const struct ds_surface_role subsurface_role =
-{
- .name = "wl_subsurface",
-};
-
-static void
-subsurface_handle_destroy(struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static void
-subsurface_handle_set_position(struct wl_client *client,
- struct wl_resource *resource, int32_t x, int32_t y)
-{
- struct ds_subsurface *subsurface;
-
- subsurface = wl_resource_get_user_data(resource);
- if (!subsurface)
- return;
-
- subsurface->pending.x = x;
- subsurface->pending.y = y;
-}
-
-static void
-subsurface_handle_place_above(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *sibling_resource)
-{
- struct ds_subsurface *subsurface, *sibling;
- struct ds_surface *sibling_surface;
- struct wl_list *node;
-
- subsurface = wl_resource_get_user_data(resource);
- if (!subsurface)
- return;
-
- sibling_surface = ds_surface_from_resource(sibling_resource);
- if (sibling_surface == subsurface->parent) {
- node = &subsurface->parent->pending.subsurfaces_above;
- }
- else {
- sibling = subsurface_find_sibling(subsurface, sibling_surface);
- if (!sibling) {
- wl_resource_post_error(subsurface->resource,
- WL_SUBSURFACE_ERROR_BAD_SURFACE,
- "%s: wl_surface@%d is not a parent or sibling",
- "place_above", wl_resource_get_id(sibling_resource));
- return;
- }
- node = &sibling->pending.link;
- }
-
- wl_list_remove(&subsurface->pending.link);
- wl_list_insert(node, &subsurface->pending.link);
-
- subsurface->reordered = true;
-}
-
-static void
-subsurface_handle_place_below(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *sibling_resource)
-{
- struct ds_subsurface *subsurface, *sibling;
- struct ds_surface *sibling_surface;
- struct wl_list *node;
-
- subsurface = wl_resource_get_user_data(resource);
- if (!subsurface)
- return;
-
- sibling_surface = ds_surface_from_resource(sibling_resource);
- if (sibling_surface == subsurface->parent) {
- node = &subsurface->parent->pending.subsurfaces_below;
- }
- else {
- sibling = subsurface_find_sibling(subsurface, sibling_surface);
- if (!sibling) {
- wl_resource_post_error(subsurface->resource,
- WL_SUBSURFACE_ERROR_BAD_SURFACE,
- "%s: wl_surface@%d is not a parent or sibling",
- "place_below", wl_resource_get_id(sibling_resource));
- return;
- }
- node = &sibling->pending.link;
-
- }
-
- wl_list_remove(&subsurface->pending.link);
- wl_list_insert(node->prev, &subsurface->pending.link);
-
- subsurface->reordered = true;
-}
-
-static void
-subsurface_handle_set_sync(struct wl_client *client,
- struct wl_resource *resource)
-{
- struct ds_subsurface *subsurface;
-
- subsurface = wl_resource_get_user_data(resource);
- if (!subsurface)
- return;
-
- subsurface->synchronized = true;
-}
-
-static void
-subsurface_handle_set_desync(struct wl_client *client,
- struct wl_resource *resource)
-{
- struct ds_subsurface *subsurface;
-
- subsurface = wl_resource_get_user_data(resource);
- if (!subsurface)
- return;
-
- if (subsurface->synchronized) {
- subsurface->synchronized = false;
-
- // TODO: flush
- }
-}
-
-static const struct wl_subsurface_interface subsurface_impl =
-{
- .destroy = subsurface_handle_destroy,
- .set_position = subsurface_handle_set_position,
- .place_above = subsurface_handle_place_above,
- .place_below = subsurface_handle_place_below,
- .set_sync = subsurface_handle_set_sync,
- .set_desync = subsurface_handle_set_desync,
-};
-
-static void
-subsurface_destroy(struct ds_subsurface *subsurface)
-{
- wl_signal_emit(&subsurface->events.destroy, subsurface);
-
- if (subsurface->parent)
- subsurface_unlink_parent(subsurface);
-
- if (subsurface->surface)
- subsurface_unlink_surface(subsurface);
-
- wl_resource_set_user_data(subsurface->resource, NULL);
-
- free(subsurface);
-}
-
-static void
-subsurface_handle_resource_destroy(struct wl_resource *resource)
-{
- struct ds_subsurface *subsurface;
-
- subsurface = wl_resource_get_user_data(resource);
- if (!subsurface)
- return;
-
- subsurface_destroy(subsurface);
-}
-
-static
-void subsurface_handle_surface_destroy(struct wl_listener *listener,
- void *data)
-{
- struct ds_subsurface *subsurface;
-
- subsurface = wl_container_of(listener, subsurface,
- listener.surface_destroy);
- subsurface_destroy(subsurface);
-}
-
-static void
-subsurface_handle_parent_destroy(struct wl_listener *listener,
- void *data)
-{
- struct ds_subsurface *subsurface;
-
- subsurface = wl_container_of(listener, subsurface,
- listener.parent_destroy);
- subsurface_unlink_parent(subsurface);
-}
-
-static void
-subsurface_link_surface(struct ds_subsurface *subsurface, struct ds_surface *surface)
-{
- subsurface->surface = surface;
- subsurface->listener.surface_destroy.notify =
- subsurface_handle_surface_destroy;
- ds_surface_add_destroy_listener(surface,
- &subsurface->listener.surface_destroy);
-}
-
-static void
-subsurface_unlink_surface(struct ds_subsurface *subsurface)
-{
- wl_list_remove(&subsurface->listener.surface_destroy.link);
- subsurface->surface->role_data = NULL;
- subsurface->surface = NULL;
-}
-
-static void
-subsurface_link_parent(struct ds_subsurface *subsurface, struct ds_surface *parent)
-{
- subsurface->parent = parent;
- subsurface->listener.parent_destroy.notify =
- subsurface_handle_parent_destroy;
- ds_surface_add_destroy_listener(parent,
- &subsurface->listener.parent_destroy);
- wl_list_insert(parent->current.subsurfaces_above.prev,
- &subsurface->current.link);
- wl_list_insert(parent->pending.subsurfaces_above.prev,
- &subsurface->pending.link);
-}
-
-static void
-subsurface_unlink_parent(struct ds_subsurface *subsurface)
-{
- wl_list_remove(&subsurface->current.link);
- wl_list_remove(&subsurface->pending.link);
- wl_list_remove(&subsurface->listener.parent_destroy.link);
- subsurface->parent = NULL;
-}
-
-static struct ds_subsurface *
-subsurface_find_sibling(struct ds_subsurface *subsurface, struct ds_surface *surface)
-{
- struct ds_surface *parent = subsurface->parent;
- struct ds_subsurface *sibling;
-
- wl_list_for_each(sibling, &parent->pending.subsurfaces_below, pending.link) {
- if (sibling->surface == surface && sibling != subsurface)
- return sibling;
- }
-
- wl_list_for_each(sibling, &parent->pending.subsurfaces_above, pending.link) {
- if (sibling->surface == surface && sibling != subsurface) {
- return sibling;
- }
- }
-
- return NULL;
-}
+++ /dev/null
-#ifndef DS_SURFACE_PRIVATE_H
-#define DS_SURFACE_PRIVATE_H
-
-#include <stdint.h>
-
-#include <pixman.h>
-#include <wayland-server.h>
-
-#include "addon.h"
-#include "buffer.h"
-#include "surface.h"
-
-enum ds_surface_state_field
-{
- DS_SURFACE_STATE_BUFFER = 1 << 0,
- DS_SURFACE_STATE_SURFACE_DAMAGE = 1 << 1,
- DS_SURFACE_STATE_BUFFER_DAMAGE = 1 << 2,
- DS_SURFACE_STATE_OPAQUE_REGION = 1 << 3,
- DS_SURFACE_STATE_INPUT_REGION = 1 << 4,
- DS_SURFACE_STATE_TRANSFORM = 1 << 5,
- DS_SURFACE_STATE_SCALE = 1 << 6,
- DS_SURFACE_STATE_FRAME_CALLBACK_LIST = 1 << 7,
- DS_SURFACE_STATE_VIEWPORT = 1 << 8,
-};
-
-struct ds_surface_state
-{
- enum ds_surface_state_field committed;
-
- struct ds_buffer *buffer;
- int32_t dx, dy;
- pixman_region32_t surface_damage, buffer_damage;
- pixman_region32_t opaque, input;
- enum wl_output_transform transform;
- int32_t scale;
- struct wl_list frame_callback_list;
-
- int width, height;
- int buffer_width, buffer_height;
-
- struct wl_list subsurfaces_below;
- struct wl_list subsurfaces_above;
-
- // TODO viewport
-};
-
-struct ds_surface
-{
- struct wl_resource *resource;
-
- struct ds_buffer *buffer;
-
- pixman_region32_t buffer_damage;
- pixman_region32_t opaque_region;
- pixman_region32_t input_region;
-
- struct ds_surface_state current, pending;
-
- const struct ds_surface_role *role;
- void *role_data;
-
- int sx, sy;
-
- struct {
- struct wl_signal commit;
- struct wl_signal new_subsurface;
- struct wl_signal destroy;
- } events;
-
- struct ds_addon_set addons;
-};
-
-struct ds_subsurface_parent_state
-{
- int32_t x, y;
- struct wl_list link;
-};
-
-struct ds_subsurface
-{
- struct wl_resource *resource;
- struct ds_surface *surface;
- struct ds_surface *parent;
-
- struct ds_subsurface_parent_state current, pending;
-
- struct {
- struct wl_signal destroy;
- } events;
-
- struct {
- struct wl_listener surface_destroy;
- struct wl_listener parent_destroy;
- } listener;
-
- bool synchronized;
- bool reordered;
- bool mapped;
-};
-
-struct ds_surface *
-ds_surface_get_root_surface(struct ds_surface *surface);
-
-struct ds_subsurface *
-ds_subsurface_from_ds_surface(struct ds_surface *surface);
-
-struct ds_surface *
-ds_subsurface_get_parent(struct ds_subsurface *subsurface);
-
-#endif
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-#include "libds/surface.h"
-
-#include "region.h"
-#include "util.h"
-#include "surface-private.h"
-
-#define CALLBACK_VERSION 1
-
-static const struct wl_surface_interface surface_impl;
-
-static void surface_handle_resource_destroy(struct wl_resource *resource);
-static void surface_state_init(struct ds_surface_state *state);
-static void surface_state_finish(struct ds_surface_state *state);
-static void surface_state_move(struct ds_surface_state *state,
- struct ds_surface_state *next);
-static void surface_finalize_pending(struct ds_surface *surface);
-static void surface_commit_state(struct ds_surface *surface,
- struct ds_surface_state *next);
-static bool surface_for_each(struct ds_surface *surface, int x, int y,
- ds_surface_for_each_func_t iterator, void *data);
-
-WL_EXPORT void
-ds_surface_add_destroy_listener(struct ds_surface *surface,
- struct wl_listener *listener)
-{
- wl_signal_add(&surface->events.destroy, listener);
-}
-
-WL_EXPORT void
-ds_surface_add_commit_listener(struct ds_surface *surface,
- struct wl_listener *listener)
-{
- wl_signal_add(&surface->events.commit, listener);
-}
-
-WL_EXPORT void
-ds_surface_add_new_subsurface_listener(struct ds_surface *surface,
- struct wl_listener *listener)
-{
- wl_signal_add(&surface->events.new_subsurface, listener);
-}
-
-WL_EXPORT struct ds_buffer *
-ds_surface_get_buffer(struct ds_surface *surface)
-{
- return surface->buffer;
-}
-
-WL_EXPORT void
-ds_surface_for_each(struct ds_surface *surface,
- ds_surface_for_each_func_t iterator, void *data)
-{
- surface_for_each(surface, 0, 0, iterator, data);
-}
-
-WL_EXPORT void
-ds_surface_send_frame_done(struct ds_surface *surface,
- const struct timespec *when)
-{
- struct wl_resource *resource, *tmp;
-
- wl_resource_for_each_safe(resource, tmp,
- &surface->current.frame_callback_list) {
- wl_callback_send_done(resource, timespec_to_msec(when));
- wl_resource_destroy(resource);
- }
-}
-
-struct ds_surface *
-ds_surface_create(struct wl_client *client, uint32_t version, uint32_t id)
-{
- struct ds_surface *surface;
-
- surface = calloc(1, sizeof *surface);
- if (!surface) {
- wl_client_post_no_memory(client);
- return NULL;
- }
-
- surface->resource =
- wl_resource_create(client, &wl_surface_interface, version, id);
- if (!surface->resource) {
- free(surface);
- wl_client_post_no_memory(client);
- return NULL;
- }
-
- wl_resource_set_implementation(surface->resource, &surface_impl,
- surface, surface_handle_resource_destroy);
-
- surface_state_init(&surface->current);
- surface_state_init(&surface->pending);
-
- wl_signal_init(&surface->events.commit);
- wl_signal_init(&surface->events.destroy);
- wl_signal_init(&surface->events.new_subsurface);
-
- pixman_region32_init(&surface->buffer_damage);
- pixman_region32_init(&surface->opaque_region);
- pixman_region32_init(&surface->input_region);
-
- ds_inf("New ds_surface %p (res %p)", surface, surface->resource);
-
- return surface;
-}
-
-struct ds_surface *
-ds_surface_from_resource(struct wl_resource *resource)
-{
- assert(wl_resource_instance_of(resource, &wl_surface_interface,
- &surface_impl));
- return wl_resource_get_user_data(resource);
-}
-
-bool
-ds_surface_set_role(struct ds_surface *surface,
- const struct ds_surface_role *role, void *role_data,
- struct wl_resource *error_resource, uint32_t error_code)
-{
- assert(role != NULL);
-
- if (surface->role != NULL && surface->role != role) {
- ds_err("Cannot assign role %s to ds_surface(%p) "
- "already has role %s\n",
- role->name, surface, surface->role->name);
- if (error_resource != NULL) {
- wl_resource_post_error(error_resource, error_code,
- "Cannot assign role %s to wl_surface@%d "
- "already has role %s\n",
- role->name, wl_resource_get_id(surface->resource),
- surface->role->name);
- }
- return false;
- }
-
- if (surface->role_data != NULL && surface->role_data != role_data) {
- ds_err("Cannot reassign role %s to ds_surface(%p), "
- "role object still exists", role->name, surface);
- wl_resource_post_error(error_resource, error_code,
- "Cannot reassign role %s to wl_surface@%d, "
- "role object still exists", role->name,
- wl_resource_get_id(surface->resource));
- return false;
- }
-
- surface->role = role;
- surface->role_data = role_data;
-
- ds_inf("Set ds_surface(%p) role: %s", surface, role->name);
-
- return true;
-}
-
-const struct ds_surface_role *
-ds_surface_get_role(struct ds_surface *surface)
-{
- return surface->role;
-}
-
-void *
-ds_surface_get_role_data(struct ds_surface *surface)
-{
- return surface->role_data;
-}
-
-void
-ds_surface_reset_role_data(struct ds_surface *surface)
-{
- surface->role_data = NULL;
-}
-
-bool
-ds_surface_is_ancestor_of(struct ds_surface *surface,
- struct ds_surface *target_surface)
-{
- struct ds_subsurface *target_subsurface;
- struct ds_surface *parent_surface;
-
- while (target_surface &&
- ds_surface_is_subsurface(target_surface)) {
- target_subsurface = ds_subsurface_from_ds_surface(target_surface);
- if (!target_subsurface)
- break;
-
- parent_surface = ds_subsurface_get_parent(target_subsurface);
- if (surface == parent_surface)
- return true;
-
- target_surface = parent_surface;
- }
-
- return false;
-}
-
-struct ds_surface *
-ds_surface_get_root_surface(struct ds_surface *surface)
-{
- struct ds_subsurface *subsurface;
-
- while (ds_surface_is_subsurface(surface)) {
- subsurface = ds_subsurface_from_ds_surface(surface);
- if (!subsurface)
- break;
-
- surface = ds_subsurface_get_parent(subsurface);
- if (!surface)
- return NULL;
- }
-
- return surface;
-}
-
-bool
-ds_surface_has_buffer(struct ds_surface *surface)
-{
- return !!surface->buffer;
-}
-
-struct wl_resource *
-ds_surface_get_wl_resource(struct ds_surface *surface)
-{
- return surface->resource;
-}
-
-static void
-surface_handle_destroy(struct wl_client *client, struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static void
-surface_handle_attach(struct wl_client *client,
- struct wl_resource *resource,
- struct wl_resource *buffer_resource,
- int32_t dx, int32_t dy)
-{
- struct ds_surface *surface;
- struct ds_buffer *buffer = NULL;
-
- if (buffer_resource) {
- buffer = ds_buffer_from_resource(buffer_resource);
- if (!buffer) {
- wl_resource_post_error(buffer_resource, 0, "unknown buffer type");
- return;
- }
- }
-
- surface = wl_resource_get_user_data(resource);
- surface->pending.committed |= DS_SURFACE_STATE_BUFFER;
- surface->pending.dx = dx;
- surface->pending.dy = dy;
-
- if (surface->pending.buffer)
- ds_buffer_unlock(surface->pending.buffer);
-
- surface->pending.buffer = buffer;
-
- ds_dbg("ds_surface(%p) attach buffer(%p)", surface, buffer);
-}
-
-static void
-surface_handle_damage(struct wl_client *client,
- struct wl_resource *resource,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- struct ds_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
-
- ds_dbg("ds_surface(%p) damage: x %d y %d width %d height %d",
- surface, x, y, width, height);
-
- if (width < 0 || height < 0)
- return;
-
- surface->pending.committed |= DS_SURFACE_STATE_SURFACE_DAMAGE;
- pixman_region32_union_rect(&surface->pending.surface_damage,
- &surface->pending.surface_damage,
- x, y, width, height);
-}
-
-static void
-callback_handle_resource_destroy(struct wl_resource *resource)
-{
- wl_list_remove(wl_resource_get_link(resource));
-}
-
-static void
-surface_handle_frame(struct wl_client *client,
- struct wl_resource *resource, uint32_t callback)
-{
- struct ds_surface *surface;
- struct wl_resource *callback_resource;
-
- surface = wl_resource_get_user_data(resource);
-
- ds_dbg("ds_surface(%p) frame", surface);
-
- callback_resource = wl_resource_create(client, &wl_callback_interface,
- CALLBACK_VERSION, callback);
- if (!callback_resource) {
- wl_resource_post_no_memory(resource);
- return;
- }
-
- wl_resource_set_implementation(callback_resource, NULL, NULL,
- callback_handle_resource_destroy);
-
- wl_list_insert(surface->pending.frame_callback_list.prev,
- wl_resource_get_link(callback_resource));
-
- surface->pending.committed |= DS_SURFACE_STATE_FRAME_CALLBACK_LIST;
-}
-
-static void
-surface_handle_set_opaque_region(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *region_resource)
-{
- struct ds_surface *surface;
- pixman_region32_t *region;
-
- surface = wl_resource_get_user_data(resource);
-
- ds_dbg("ds_surface(%p) set opaque region", surface);
-
- surface->pending.committed |= DS_SURFACE_STATE_OPAQUE_REGION;
- if (region_resource) {
- region = ds_region_from_resource(region_resource);
- pixman_region32_copy(&surface->pending.opaque, region);
- }
- else {
- pixman_region32_clear(&surface->pending.opaque);
- }
-}
-
-static void
-surface_handle_set_input_region(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *region_resource)
-{
- struct ds_surface *surface;
- pixman_region32_t *region;
-
- surface = wl_resource_get_user_data(resource);
-
- ds_dbg("ds_surface(%p) set input region", surface);
-
- surface->pending.committed |= DS_SURFACE_STATE_INPUT_REGION;
- if (region_resource) {
- region = ds_region_from_resource(region_resource);
- pixman_region32_copy(&surface->pending.input, region);
- }
- else {
- pixman_region32_fini(&surface->pending.input);
- pixman_region32_init_rect(&surface->pending.input,
- INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX);
- }
-}
-
-static void
-surface_handle_commit(struct wl_client *client, struct wl_resource *resource)
-{
- struct ds_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
-
- ds_dbg("ds_surface(%p) commit", surface);
-
- // TODO handle subsurface
-
- surface_finalize_pending(surface);
-
- surface_commit_state(surface, &surface->pending);
-
- // TODO handle subsurfaces of a given surface
-
- if (surface->role && surface->role->commit)
- surface->role->commit(surface);
-
- wl_signal_emit(&surface->events.commit, surface);
-}
-
-static void
-surface_handle_set_buffer_transform(struct wl_client *client,
- struct wl_resource *resource, int32_t transform)
-{
- struct ds_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
-
- ds_dbg("ds_surface(%p) set buffer transform(%d)", surface, transform);
-
- if (transform < WL_OUTPUT_TRANSFORM_NORMAL ||
- transform > WL_OUTPUT_TRANSFORM_FLIPPED_270) {
- ds_err("Specified transform value(%d) is invalid. ds_surface(%p)",
- transform, surface);
- wl_resource_post_error(resource, WL_SURFACE_ERROR_INVALID_TRANSFORM,
- "Specified transform value(%d) is invalid", transform);
- return;
- }
-
- surface->pending.committed |= DS_SURFACE_STATE_TRANSFORM;
- surface->pending.transform = transform;
-}
-
-static void
-surface_handle_set_buffer_scale(struct wl_client *client,
- struct wl_resource *resource, int32_t scale)
-{
- struct ds_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
-
- ds_dbg("ds_surface(%p) set buffer scale(%d)", surface, scale);
-
- if (scale <= 0) {
- ds_err("Specified scale value(%d) is not positive. ds_surface(%p)",
- scale, surface);
- wl_resource_post_error(resource, WL_SURFACE_ERROR_INVALID_SCALE,
- "Specified scale value(%d) is not positive", scale);
- return;
- }
-
- surface->pending.committed |= DS_SURFACE_STATE_SCALE;
- surface->pending.scale = scale;
-}
-
-static void
-surface_handle_damage_buffer(struct wl_client *client,
- struct wl_resource *resource,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- struct ds_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
-
- ds_dbg("ds_surface(%p) damage: x %d y %d width %d height %d",
- surface, x, y, width, height);
-
- if (width < 0 || height < 0) {
- ds_err("Size cannot be less than zero. ds_surface(%p) "
- "width %d height %d", surface, width, height);
- return;
- }
-
- surface->pending.committed |= DS_SURFACE_STATE_BUFFER_DAMAGE;
- pixman_region32_union_rect(&surface->pending.buffer_damage,
- &surface->pending.buffer_damage,
- x, y, width, height);
-}
-
-static const struct wl_surface_interface surface_impl =
-{
- .destroy = surface_handle_destroy,
- .attach = surface_handle_attach,
- .damage = surface_handle_damage,
- .frame = surface_handle_frame,
- .set_opaque_region = surface_handle_set_opaque_region,
- .set_input_region = surface_handle_set_input_region,
- .commit = surface_handle_commit,
- .set_buffer_transform = surface_handle_set_buffer_transform,
- .set_buffer_scale = surface_handle_set_buffer_scale,
- .damage_buffer = surface_handle_damage_buffer,
-};
-
-static void
-surface_handle_resource_destroy(struct wl_resource *resource)
-{
- struct ds_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
-
- ds_inf("Destroy ds_surface %p (res %p)", surface, surface->resource);
-
- wl_signal_emit(&surface->events.destroy, surface);
-
- if (surface->buffer)
- ds_buffer_unlock(surface->buffer);
-
- surface_state_finish(&surface->pending);
- surface_state_finish(&surface->current);
-
- pixman_region32_fini(&surface->buffer_damage);
- pixman_region32_fini(&surface->opaque_region);
- pixman_region32_fini(&surface->input_region);
-
- free(surface);
-}
-
-static void
-surface_state_init(struct ds_surface_state *state)
-{
- state->scale = 1;
- state->transform = WL_OUTPUT_TRANSFORM_NORMAL;
-
- wl_list_init(&state->subsurfaces_above);
- wl_list_init(&state->subsurfaces_below);
-
- wl_list_init(&state->frame_callback_list);
-
- pixman_region32_init(&state->surface_damage);
- pixman_region32_init(&state->buffer_damage);
- pixman_region32_init(&state->opaque);
- pixman_region32_init_rect(&state->input,
- INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX);
-}
-
-static void
-surface_state_finish(struct ds_surface_state *state)
-{
- struct wl_resource *resource, *tmp;
-
- if (state->buffer)
- ds_buffer_unlock(state->buffer);
-
- wl_resource_for_each_safe(resource, tmp, &state->frame_callback_list)
- wl_resource_destroy(resource);
-
- pixman_region32_fini(&state->surface_damage);
- pixman_region32_fini(&state->buffer_damage);
- pixman_region32_fini(&state->opaque);
- pixman_region32_fini(&state->input);
-}
-
-static void
-surface_state_move(struct ds_surface_state *state, struct ds_surface_state *next)
-{
- state->width = next->width;
- state->height = next->height;
- state->buffer_width = next->buffer_width;
- state->buffer_height = next->buffer_height;
-
- if (next->committed & DS_SURFACE_STATE_SCALE)
- state->scale = next->scale;
-
- if (next->committed & DS_SURFACE_STATE_TRANSFORM)
- state->transform = next->transform;
-
- if (next->committed & DS_SURFACE_STATE_BUFFER) {
- state->dx = next->dx;
- state->dy = next->dy;
- next->dx = next->dy = 0;
-
- if (state->buffer) {
- ds_buffer_unlock(state->buffer);
- state->buffer = NULL;
- }
-
- if (next->buffer) {
- state->buffer = ds_buffer_lock(next->buffer);
- ds_buffer_unlock(next->buffer);
- next->buffer = NULL;
- }
- }
- else {
- state->dx = state->dy = 0;
- }
-
- if (next->committed & DS_SURFACE_STATE_SURFACE_DAMAGE) {
- pixman_region32_copy(&state->surface_damage, &next->surface_damage);
- pixman_region32_clear(&next->surface_damage);
- }
- else
- pixman_region32_clear(&state->surface_damage);
-
- if (next->committed & DS_SURFACE_STATE_BUFFER_DAMAGE) {
- pixman_region32_copy(&state->buffer_damage, &next->buffer_damage);
- pixman_region32_clear(&next->buffer_damage);
- }
- else
- pixman_region32_clear(&state->buffer_damage);
-
- if (next->committed & DS_SURFACE_STATE_OPAQUE_REGION)
- pixman_region32_copy(&state->opaque, &next->opaque);
-
- if (next->committed & DS_SURFACE_STATE_INPUT_REGION)
- pixman_region32_copy(&state->input, &next->input);
-
- if (next->committed & DS_SURFACE_STATE_FRAME_CALLBACK_LIST) {
- wl_list_insert_list(&state->frame_callback_list,
- &next->frame_callback_list);
- wl_list_init(&next->frame_callback_list);
- }
-
- // FIXME
- // state->committed |= next->committed; ??
- state->committed = next->committed;
- next->committed = 0;
-}
-
-static void
-surface_state_viewport_src_size(struct ds_surface_state *state,
- int *out_width, int *out_height)
-{
- int width, height, tmp;
-
- if (state->buffer_width == 0 && state->buffer_height == 0) {
- *out_width = 0;
- *out_height = 0;
- return;
- }
-
- width = state->buffer_width / state->scale;
- height = state->buffer_height / state->scale;
- if ((state->transform & WL_OUTPUT_TRANSFORM_90) != 0) {
- tmp = width;
- width = height;
- height = tmp;
- }
-
- *out_width = width;
- *out_height = height;
-}
-
-static void
-surface_finalize_pending(struct ds_surface *surface)
-{
- struct ds_surface_state *pending = &surface->pending;
-
- if ((pending->committed & DS_SURFACE_STATE_BUFFER)) {
- if (pending->buffer) {
- ds_buffer_get_size(pending->buffer,
- &pending->buffer_width, &pending->buffer_height);
- }
- else {
- pending->buffer_width = 0;
- pending->buffer_height = 0;
- }
- }
-
- surface_state_viewport_src_size(pending,
- &pending->width, &pending->height);
-
- pixman_region32_intersect_rect(&pending->surface_damage,
- &pending->surface_damage,
- 0, 0, pending->width, pending->height);
-
- pixman_region32_intersect_rect(&pending->buffer_damage,
- &pending->buffer_damage,
- 0, 0, pending->buffer_width, pending->buffer_height);
-}
-
-// FIXME
-static enum wl_output_transform
-ds_output_transform_invert(enum wl_output_transform tr)
-{
- if ((tr & WL_OUTPUT_TRANSFORM_90) && !(tr & WL_OUTPUT_TRANSFORM_FLIPPED)) {
- tr ^= WL_OUTPUT_TRANSFORM_180;
- }
- return tr;
-}
-
-static void
-surface_update_damage(pixman_region32_t *buffer_damage,
- struct ds_surface_state *current, struct ds_surface_state *pending)
-{
- pixman_region32_clear(buffer_damage);
-
- if (pending->width != current->width ||
- pending->height != current->height) {
- pixman_region32_union_rect(buffer_damage, buffer_damage,
- 0, 0, pending->buffer_width, pending->buffer_height);
- }
- else {
- pixman_region32_t surface_damage;
-
- pixman_region32_init(&surface_damage);
- pixman_region32_copy(&surface_damage, &pending->surface_damage);
-
- // TODO viewport
-
- ds_region_transform(&surface_damage, &surface_damage,
- ds_output_transform_invert(pending->transform),
- pending->width, pending->height);
- ds_region_scale(&surface_damage, &surface_damage, pending->scale);
-
- pixman_region32_union(buffer_damage,
- &pending->buffer_damage, &surface_damage);
-
- pixman_region32_fini(&surface_damage);
- }
-}
-
-static void
-surface_update_buffer(struct ds_surface *surface)
-{
- if (!surface->current.buffer) {
- if (surface->buffer) {
- ds_buffer_unlock(surface->buffer);
- surface->buffer = NULL;
- }
- return;
- }
-
- if (surface->buffer) {
- ds_buffer_unlock(surface->buffer);
- surface->buffer = NULL;
- }
-
- if (surface->current.buffer) {
- surface->buffer = ds_buffer_lock(surface->current.buffer);
- ds_buffer_unlock(surface->current.buffer);
- surface->current.buffer = NULL;
- }
-}
-
-static void
-surface_commit_state(struct ds_surface *surface, struct ds_surface_state *next)
-{
- surface->sx += next->dx;
- surface->sy += next->dy;
- surface_update_damage(&surface->buffer_damage, &surface->current, next);
-
- surface_state_move(&surface->current, next);
-
- // FIXME no need?
- if (surface->current.committed & DS_SURFACE_STATE_BUFFER)
- surface_update_buffer(surface);
-
- wl_signal_emit(&surface->events.commit, surface);
-}
-
-static bool
-surface_for_each(struct ds_surface *surface, int x, int y,
- ds_surface_for_each_func_t iterator, void *data)
-{
- struct ds_subsurface *subsurface;
- struct ds_subsurface_parent_state *state;
- bool stop = false;
-
- wl_list_for_each(subsurface,
- &surface->current.subsurfaces_below, current.link) {
- state = &subsurface->current;
- stop = surface_for_each(subsurface->surface,
- x + state->x, y + state->y, iterator, data);
- if (stop)
- return true;
- }
-
- stop = iterator(surface, x, y, data);
- if (stop)
- return true;
-
- wl_list_for_each(subsurface,
- &surface->current.subsurfaces_above, current.link) {
- state = &subsurface->current;
- stop = surface_for_each(subsurface->surface,
- x + state->x, y + state->y, iterator, data);
- if (stop)
- return true;
- }
-
- return false;
-}
+++ /dev/null
-#include <assert.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-#include "libds/allocator.h"
-
-#define DS_SWAPCHAIN_CAP 4
-
-struct ds_swapchain_slot
-{
- struct ds_buffer *buffer;
-
- struct wl_listener buffer_release;
-
- int age;
- bool acquired;
-};
-
-struct ds_swapchain
-{
- struct ds_allocator *allocator;
-
- struct ds_swapchain_slot slots[DS_SWAPCHAIN_CAP];
-
- struct wl_listener allocator_destroy;
-
- int width, height;
- uint32_t format;
-};
-
-static void swapchain_handle_allocator_destroy(struct wl_listener *listener,
- void *data);
-static bool swapchain_has_buffer(struct ds_swapchain *swapchain,
- struct ds_buffer *buffer);
-static struct ds_buffer *swapchain_slot_acquire(struct ds_swapchain *swapchain,
- struct ds_swapchain_slot *slot, int *age);
-static void swapchain_slot_reset(struct ds_swapchain_slot *slot);
-
-struct ds_swapchain *
-ds_swapchain_create(struct ds_allocator *alloc, int width, int height,
- uint32_t format)
-{
- struct ds_swapchain *swapchain;
-
- swapchain = calloc(1, sizeof *swapchain);
- if (!swapchain)
- return NULL;
-
- swapchain->allocator = alloc;
- swapchain->width = width;
- swapchain->height = height;
- swapchain->format = format;
-
- swapchain->allocator_destroy.notify =
- swapchain_handle_allocator_destroy;
- ds_allocator_add_destroy_listener(alloc,
- &swapchain->allocator_destroy);
-
- ds_inf("Swapchain(%p) created", swapchain);
-
- return swapchain;
-}
-
-void
-ds_swapchain_destroy(struct ds_swapchain *swapchain)
-{
- size_t i;
-
- ds_dbg("Destroy swapchain(%p)", swapchain);
-
- for (i = 0; i < DS_SWAPCHAIN_CAP; i++)
- swapchain_slot_reset(&swapchain->slots[i]);
-
- wl_list_remove(&swapchain->allocator_destroy.link);
- free(swapchain);
-}
-
-struct ds_buffer *
-ds_swapchain_acquire(struct ds_swapchain *swapchain, int *age)
-{
- struct ds_swapchain_slot *slot, *free_slot = NULL;
- size_t i;
-
- for (i = 0; i < DS_SWAPCHAIN_CAP; i++) {
- slot = &swapchain->slots[i];
- if (slot->acquired)
- continue;
-
- if (slot->buffer != NULL)
- return swapchain_slot_acquire(swapchain, slot, age);
-
- free_slot = slot;
- }
-
- if (free_slot == NULL) {
- ds_err("No free output buffer slot");
- return NULL;
- }
-
- if (!swapchain->allocator)
- return NULL;
-
- free_slot->buffer = ds_allocator_create_buffer(swapchain->allocator,
- swapchain->width, swapchain->height, swapchain->format);
- if (!free_slot->buffer) {
- ds_err("Failed to allocate buffer");
- return NULL;
- }
-
- ds_dbg("Allocating new swapchain buffer(%p)", free_slot->buffer);
-
- return swapchain_slot_acquire(swapchain, free_slot, age);
-}
-
-void
-ds_swapchain_set_buffer_submitted(struct ds_swapchain *swapchain,
- struct ds_buffer *buffer)
-{
- struct ds_swapchain_slot *slot;
- size_t i;
-
- assert(buffer);
-
- if (!swapchain_has_buffer(swapchain, buffer))
- return;
-
- for (i = 0; i < DS_SWAPCHAIN_CAP; i++) {
- slot = &swapchain->slots[i];
- if (slot->buffer == buffer)
- slot->age = 1;
- else if (slot->age > 0)
- slot->age++;
- }
-}
-
-static void
-swapchain_handle_allocator_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_swapchain *swapchain;
-
- swapchain = wl_container_of(listener, swapchain, allocator_destroy);
- swapchain->allocator = NULL;
-}
-
-static bool swapchain_has_buffer(struct ds_swapchain *swapchain,
- struct ds_buffer *buffer)
-{
- struct ds_swapchain_slot *slot;
- size_t i;
-
- for (i = 0; i < DS_SWAPCHAIN_CAP; i++) {
- slot = &swapchain->slots[i];
- if (slot->buffer == buffer)
- return true;
- }
-
- return false;
-}
-
-static void
-swapchain_slot_handle_buffer_release(struct wl_listener *listener, void *data)
-{
- struct ds_swapchain_slot *slot;
-
- slot = wl_container_of(listener, slot, buffer_release);
-
- ds_dbg("Buffer(%p) released.", slot->buffer);
-
- wl_list_remove(&slot->buffer_release.link);
- slot->acquired = false;
-}
-
-static struct ds_buffer *
-swapchain_slot_acquire(struct ds_swapchain *swapchain, struct ds_swapchain_slot *slot,
- int *age)
-{
- assert(!slot->acquired);
- assert(slot->buffer);
-
- slot->acquired = true;
-
- slot->buffer_release.notify = swapchain_slot_handle_buffer_release;
- ds_buffer_add_release_listener(slot->buffer, &slot->buffer_release);
-
- if (age != NULL)
- *age = slot->age;
-
- return ds_buffer_lock(slot->buffer);
-}
-
-static void
-swapchain_slot_reset(struct ds_swapchain_slot *slot)
-{
- if (slot->acquired)
- wl_list_remove(&slot->buffer_release.link);
-
- if (slot->buffer)
- ds_buffer_drop(slot->buffer);
-
- memset(slot, 0, sizeof *slot);
-}
+++ /dev/null
-#include <stdlib.h>
-#include <wayland-server.h>
-#include "libds/interfaces/touch.h"
-
-void
-ds_touch_init(struct ds_touch *touch,
- const struct ds_touch_interface *iface)
-{
- touch->iface = iface;
-
- wl_signal_init(&touch->events.down);
- wl_signal_init(&touch->events.up);
- wl_signal_init(&touch->events.motion);
- wl_signal_init(&touch->events.frame);
-}
-
-void
-ds_touch_destroy(struct ds_touch *touch)
-{
- if (!touch)
- return;
-
- if (touch->iface && touch->iface->destroy)
- touch->iface->destroy(touch);
- else
- free(touch);
-}
-
-WL_EXPORT void
-ds_touch_add_down_listener(struct ds_touch *touch,
- struct wl_listener *listener)
-{
- wl_signal_add(&touch->events.down, listener);
-}
-
-WL_EXPORT void
-ds_touch_add_up_listener(struct ds_touch *touch,
- struct wl_listener *listener)
-{
- wl_signal_add(&touch->events.up, listener);
-}
-
-WL_EXPORT void
-ds_touch_add_motion_listener(struct ds_touch *touch,
- struct wl_listener *listener)
-{
- wl_signal_add(&touch->events.motion, listener);
-}
-
-WL_EXPORT void
-ds_touch_add_frame_listener(struct ds_touch *touch,
- struct wl_listener *listener)
-{
- wl_signal_add(&touch->events.frame, listener);
-}
+++ /dev/null
-#ifndef DS_UTIL_H
-#define DS_UTIL_H
-
-#include <stdint.h>
-#include <time.h>
-
-int64_t
-timespec_to_msec(const struct timespec *a);
-
-uint32_t
-get_current_time_msec(void);
-
-int
-allocate_shm_file(size_t size);
-
-bool
-allocate_shm_file_pair(size_t size, int *rw_fd_ptr, int *ro_fd_ptr);
-
-#endif
+++ /dev/null
-/*
- * Copyright © 2012 Collabora, Ltd.
- *
- * 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 200809L
-#include <stdbool.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#define RANDNAME_PATTERN "/libds-XXXXXX"
-
-int
-os_fd_set_cloexec(int fd)
-{
- long flags;
-
- if (fd == -1)
- return -1;
-
- flags = fcntl(fd, F_GETFD);
- if (flags == -1)
- return -1;
-
- if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
- return -1;
-
- return 0;
-}
-
-static int
-set_cloexec_or_close(int fd)
-{
- if (os_fd_set_cloexec(fd) != 0) {
- close(fd);
- return -1;
- }
- return fd;
-}
-
-static int
-create_tmpfile_cloexec(char *tmpname)
-{
- int fd;
-
-#ifdef HAVE_MKOSTEMP
- fd = mkostemp(tmpname, O_CLOEXEC);
- if (fd >= 0)
- unlink(tmpname);
-#else
- fd = mkstemp(tmpname);
- if (fd >= 0) {
- fd = set_cloexec_or_close(fd);
- unlink(tmpname);
- }
-#endif
-
- return fd;
-}
-
-/*
- * Create a new, unique, anonymous file of the given size, and
- * return the file descriptor for it. The file descriptor is set
- * CLOEXEC. The file is immediately suitable for mmap()'ing
- * the given size at offset zero.
- *
- * The file should not have a permanent backing store like a disk,
- * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
- *
- * The file name is deleted from the file system.
- *
- * The file is suitable for buffer sharing between processes by
- * transmitting the file descriptor over Unix sockets using the
- * SCM_RIGHTS methods.
- *
- * If the C library implements posix_fallocate(), it is used to
- * guarantee that disk space is available for the file at the
- * given size. If disk space is insufficient, errno is set to ENOSPC.
- * If posix_fallocate() is not supported, program may receive
- * SIGBUS on accessing mmap()'ed file contents instead.
- *
- * If the C library implements memfd_create(), it is used to create the
- * file purely in memory, without any backing file name on the file
- * system, and then sealing off the possibility of shrinking it. This
- * can then be checked before accessing mmap()'ed file contents, to
- * make sure SIGBUS can't happen. It also avoids requiring
- * XDG_RUNTIME_DIR.
- */
-int
-allocate_shm_file(off_t size)
-{
- static const char template[] = "/weston-shared-XXXXXX";
- const char *path;
- char *name;
- int fd;
- int ret;
-
-#ifdef HAVE_MEMFD_CREATE
- fd = memfd_create("weston-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
- if (fd >= 0) {
- /* We can add this seal before calling posix_fallocate(), as
- * the file is currently zero-sized anyway.
- *
- * There is also no need to check for the return value, we
- * couldn't do anything with it anyway.
- */
- fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK);
- } else
-#endif
- {
- path = getenv("XDG_RUNTIME_DIR");
- if (!path) {
- errno = ENOENT;
- return -1;
- }
-
- name = malloc(strlen(path) + sizeof(template));
- if (!name)
- return -1;
-
- strcpy(name, path);
- strcat(name, template);
-
- fd = create_tmpfile_cloexec(name);
-
- free(name);
-
- if (fd < 0)
- return -1;
- }
-
-#ifdef HAVE_POSIX_FALLOCATE
- do {
- ret = posix_fallocate(fd, 0, size);
- } while (ret == EINTR);
- if (ret != 0) {
- close(fd);
- errno = ret;
- return -1;
- }
-#else
- do {
- ret = ftruncate(fd, size);
- } while (ret < 0 && errno == EINTR);
- if (ret < 0) {
- close(fd);
- return -1;
- }
-#endif
-
- return fd;
-}
-
-static void
-randname(char *buf)
-{
- struct timespec ts;
- long r;
-
- clock_gettime(CLOCK_REALTIME, &ts);
- r = ts.tv_nsec;
- for (int i = 0; i < 6; i++) {
- buf[i] = 'A' + (r & 15) + (r & 16) * 2;
- r >>= 5;
- }
-}
-
-static int
-excl_shm_open(char *name)
-{
- int retries = 100;
- int fd;
-
- do {
- randname(name + strlen(RANDNAME_PATTERN) - 6);
-
- --retries;
-
- fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
- if (fd >= 0)
- return fd;
- } while (retries > 0 && errno == EEXIST);
-
- return -1;
-}
-
-bool
-allocate_shm_file_pair(size_t size, int *rw_fd_ptr, int *ro_fd_ptr)
-{
- char name[] = RANDNAME_PATTERN;
- int rw_fd, ro_fd;
- int ret;
-
- rw_fd = excl_shm_open(name);
- if (rw_fd < 0)
- return false;
-
- ro_fd = shm_open(name, O_RDONLY, 0);
- if (ro_fd < 0) {
- shm_unlink(name);
- close(rw_fd);
- return false;
- }
-
- shm_unlink(name);
-
- do {
- ret = ftruncate(rw_fd, size);
- } while (ret < 0 && errno == EINTR);
-
- if (ret < 0) {
- close(rw_fd);
- close(ro_fd);
- return false;
- }
-
- *rw_fd_ptr = rw_fd;
- *ro_fd_ptr = ro_fd;
-
- return true;
-}
+++ /dev/null
-#define _POSIX_C_SOURCE 200809L
-
-#include <stdint.h>
-#include <time.h>
-
-int64_t
-timespec_to_msec(const struct timespec *a)
-{
- return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
-}
-
-uint32_t
-get_current_time_msec(void)
-{
- struct timespec now;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
- return timespec_to_msec(&now);
-}
+++ /dev/null
-#include <assert.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-#include "libds/xdg_shell.h"
-
-#include "xdg_shell.h"
-
-#define XDG_WM_BASE_VERSION 2
-#define XDG_SHELL_PING_TIMEOUT 10000
-
-static void xdg_shell_handle_display_destroy(struct wl_listener *listener,
- void *data);
-static void xdg_shell_bind(struct wl_client *wl_client, void *data,
- uint32_t verison, uint32_t id);
-
-WL_EXPORT struct ds_xdg_shell *
-ds_xdg_shell_create(struct wl_display *display)
-{
- struct ds_xdg_shell *shell;
-
- shell = calloc(1, sizeof *shell);
- if (!shell) {
- return NULL;
- }
-
- shell->ping_timeout = XDG_SHELL_PING_TIMEOUT;
-
- wl_list_init(&shell->clients);
-
- shell->global = wl_global_create(display, &xdg_wm_base_interface,
- XDG_WM_BASE_VERSION, shell, xdg_shell_bind);
- if (!shell->global) {
- free(shell);
- return NULL;
- }
-
- wl_signal_init(&shell->events.destroy);
- wl_signal_init(&shell->events.new_surface);
-
- shell->display_destroy.notify = xdg_shell_handle_display_destroy;
- wl_display_add_destroy_listener(display, &shell->display_destroy);
-
- ds_inf("Global created: xdg_wm_base shell(%p)", shell);
-
- return shell;
-}
-
-WL_EXPORT void
-ds_xdg_shell_add_destroy_listener(struct ds_xdg_shell *shell,
- struct wl_listener *listener)
-{
- wl_signal_add(&shell->events.destroy, listener);
-}
-
-void
-ds_xdg_shell_add_new_surface_listener(struct ds_xdg_shell *shell,
- struct wl_listener *listener)
-{
- wl_signal_add(&shell->events.new_surface, listener);
-}
-
-static void
-xdg_shell_handle_display_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_xdg_shell *shell;
-
- shell = wl_container_of(listener, shell, display_destroy);
-
- ds_inf("Global destroy: xdg_wm_base shell(%p)", shell);
-
- wl_signal_emit(&shell->events.destroy, shell);
- wl_list_remove(&shell->display_destroy.link);
- wl_global_destroy(shell->global);
- free(shell);
-}
-
-static void
-xdg_shell_handle_destroy(struct wl_client *wl_client,
- struct wl_resource *resource)
-{
- struct ds_xdg_client *client;
-
- client = wl_resource_get_user_data(resource);
-
- if (!wl_list_empty(&client->surfaces)) {
- wl_resource_post_error(client->resource,
- XDG_WM_BASE_ERROR_DEFUNCT_SURFACES,
- "xdg_wm_base was destroyed before children");
- return;
- }
-
- wl_resource_destroy(resource);
-}
-
-static void
-xdg_shell_handle_create_positioner(struct wl_client *wl_client,
- struct wl_resource *resource, uint32_t id)
-{
- // TODO
-}
-
-static void
-xdg_shell_handle_get_xdg_surface(struct wl_client *wl_client,
- struct wl_resource *resource, uint32_t id,
- struct wl_resource *surface_resource)
-{
- struct ds_xdg_client *client;
- struct ds_surface *surface;
-
- client = wl_resource_get_user_data(resource);
- surface = ds_surface_from_resource(surface_resource);
- create_xdg_surface(client, surface, id);
-}
-
-static void
-xdg_shell_handle_pong(struct wl_client *wl_client,
- struct wl_resource *resource, uint32_t serial)
-{
- struct ds_xdg_client *client;
-
- client = wl_resource_get_user_data(resource);
- if (client->ping_serial != serial)
- return;
-
- wl_event_source_timer_update(client->ping_timer, 0);
- client->ping_serial = 0;
-}
-
-static const struct xdg_wm_base_interface xdg_shell_impl =
-{
- .destroy = xdg_shell_handle_destroy,
- .create_positioner = xdg_shell_handle_create_positioner,
- .get_xdg_surface = xdg_shell_handle_get_xdg_surface,
- .pong = xdg_shell_handle_pong,
-};
-
-static void
-xdg_client_handle_resource_destroy(struct wl_resource *resource)
-{
- struct ds_xdg_client *client;
- struct ds_xdg_surface *surface, *tmp;
-
- client = wl_resource_get_user_data(resource);
-
- wl_list_for_each_safe(surface, tmp, &client->surfaces, link)
- destroy_xdg_surface(surface);
-
- if (client->ping_timer != NULL)
- wl_event_source_remove(client->ping_timer);
-
- wl_list_remove(&client->link);
- free(client);
-}
-
-static int
-xdg_client_handle_ping_timeout(void *user_data)
-{
- struct ds_xdg_client *client = user_data;
- struct ds_xdg_surface *surface;
-
- wl_list_for_each(surface, &client->surfaces, link)
- wl_signal_emit(&surface->events.ping_timeout, surface);
-
- client->ping_serial = 0;
-
- return 1;
-}
-
-static void
-xdg_client_init_ping_timer(struct ds_xdg_client *client)
-{
- struct wl_display *display;
- struct wl_event_loop *loop;
-
- display = wl_client_get_display(client->wl_client);
- loop = wl_display_get_event_loop(display);
- client->ping_timer = wl_event_loop_add_timer(loop,
- xdg_client_handle_ping_timeout, client);
- if (client->ping_timer == NULL)
- wl_client_post_no_memory(client->wl_client);
-}
-
-static void
-xdg_shell_bind(struct wl_client *wl_client, void *data, uint32_t version,
- uint32_t id)
-{
- struct ds_xdg_shell *shell = data;
- struct ds_xdg_client *client;
-
- client = calloc(1, sizeof *client);
- if (client == NULL) {
- wl_client_post_no_memory(wl_client);
- return;
- }
-
- client->wl_client = wl_client;
- client->shell = shell;
-
- wl_list_init(&client->surfaces);
-
- client->resource =
- wl_resource_create(wl_client, &xdg_wm_base_interface, version, id);
- if (client->resource == NULL) {
- free(client);
- wl_client_post_no_memory(wl_client);
- return;
- }
-
- wl_resource_set_implementation(client->resource, &xdg_shell_impl, client,
- xdg_client_handle_resource_destroy);
-
- wl_list_insert(&shell->clients, &client->link);
-
- xdg_client_init_ping_timer(client);
-}
+++ /dev/null
-#ifndef DS_XDG_SHELL_H
-#define DS_XDG_SHELL_H
-
-#include <wayland-server.h>
-
-#include "libds/output.h"
-#include "xdg-shell-server-protocol.h"
-
-#include "surface.h"
-
-enum ds_xdg_surface_role
-{
- DS_XDG_SURFACE_ROLE_NONE,
- DS_XDG_SURFACE_ROLE_TOPLEVEL,
- DS_XDG_SURFACE_ROLE_POPUP,
-};
-
-struct ds_xdg_shell
-{
- struct wl_global *global;
-
- struct wl_list clients;
-
- struct wl_listener display_destroy;
-
- struct {
- struct wl_signal destroy;
- struct wl_signal new_surface;
- } events;
-
- uint32_t ping_timeout;
-};
-
-struct ds_xdg_client
-{
- struct ds_xdg_shell *shell;
-
- struct wl_resource *resource;
- struct wl_client *wl_client;
- struct wl_event_source *ping_timer;
-
- struct wl_list surfaces;
-
- struct wl_list link; // ds_xdg_shell::clients
-
- uint32_t ping_serial;
-};
-
-struct ds_xdg_toplevel_state
-{
- bool maximized, fullscreen, resizing, activated;
- uint32_t tiled;
- uint32_t width, height;
- uint32_t max_width, max_height;
- uint32_t min_width, min_height;
-};
-
-struct ds_xdg_toplevel_configure
-{
- bool maximized, fullscreen, resizing, activated;
- uint32_t tiled;
- uint32_t width, height;
-};
-
-struct ds_xdg_toplevel_requested
-{
- bool maximized, minimized, fullscreen;
- struct ds_output *fullscreen_output;
- struct wl_listener fullscreen_output_destroy;
-};
-
-struct ds_xdg_toplevel
-{
- struct wl_resource *resource;
- struct ds_xdg_surface *base;
- bool added;
-
- struct ds_xdg_surface *parent;
- struct wl_listener parent_unmap;
-
- struct ds_xdg_toplevel_state current, pending;
- struct ds_xdg_toplevel_configure scheduled;
- struct ds_xdg_toplevel_requested requested;
-
- char *title;
- char *app_id;
-
- struct {
- struct wl_signal request_maximize;
- struct wl_signal request_fullscreen;
- struct wl_signal request_minimize;
- struct wl_signal request_move;
- struct wl_signal request_resize;
- struct wl_signal request_show_window_menu;
- struct wl_signal set_parent;
- struct wl_signal set_title;
- struct wl_signal set_app_id;
- } events;
-};
-
-struct ds_xdg_popup
-{
-
-};
-
-struct ds_xdg_surface_state
-{
- uint32_t configure_serial;
- struct {
- int x, y;
- int width, height;
- } geometry;
-};
-
-struct ds_xdg_surface
-{
- struct ds_xdg_client *client;
- struct ds_surface *ds_surface;
-
- enum ds_xdg_surface_role role;
-
- union {
- struct ds_xdg_toplevel *toplevel;
- struct ds_xdg_popup *popup;
- };
-
- struct wl_resource *resource;
-
- struct wl_event_source *configure_idle;
- uint32_t scheduled_serial;
- struct wl_list configure_list;
-
- struct ds_xdg_surface_state current, pending;
-
- struct wl_list link; // ds_xdg_client::surfaces
-
- struct {
- struct wl_listener surface_destroy;
- struct wl_listener surface_commit;
- } listener;
-
- struct {
- struct wl_signal destroy;
- struct wl_signal ping_timeout;
- struct wl_signal new_popup;
- struct wl_signal map;
- struct wl_signal unmap;
- struct wl_signal configure;
- struct wl_signal ack_configure;
- } events;
-
- bool added, configured, mapped;
-};
-
-struct ds_xdg_surface_configure
-{
- struct ds_xdg_surface *surface;
- struct wl_list link;
- uint32_t serial;
-
- struct ds_xdg_toplevel_configure *toplevel_configure;
-};
-
-uint32_t
-ds_xdg_surface_schedule_configure(struct ds_xdg_surface *surface);
-
-struct ds_xdg_surface *
-create_xdg_surface(struct ds_xdg_client *client, struct ds_surface *surface,
- uint32_t id);
-
-void destroy_xdg_surface(struct ds_xdg_surface *surface);
-
-void
-reset_xdg_surface(struct ds_xdg_surface *surface);
-
-void
-create_xdg_toplevel(struct ds_xdg_surface *surface, uint32_t id);
-
-void
-handle_xdg_surface_commit(struct ds_surface *ds_surface);
-
-void
-handle_xdg_surface_toplevel_committed(struct ds_xdg_surface *surface);
-
-void
-send_xdg_toplevel_configure(struct ds_xdg_surface *surface,
- struct ds_xdg_surface_configure *configure);
-
-#endif
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-
-#include "xdg_shell.h"
-
-static const struct xdg_surface_interface xdg_surface_impl;
-
-static void xdg_surface_handle_surface_destroy(struct wl_listener *listener,
- void *data);
-static void xdg_surface_handle_surface_commit(struct wl_listener *listener,
- void *data);
-static void xdg_surface_handle_resource_destroy(struct wl_resource *resource);
-static void xdg_surface_configure_destroy(struct ds_xdg_surface_configure *configure);
-static void surface_send_configure(void *user_data);
-
-void
-ds_xdg_surface_add_destroy_listener(struct ds_xdg_surface *surface,
- struct wl_listener *listener)
-{
- wl_signal_add(&surface->events.destroy, listener);
-}
-
-WL_EXPORT void
-ds_xdg_surface_add_map_listener(struct ds_xdg_surface *surface,
- struct wl_listener *listener)
-{
- wl_signal_add(&surface->events.map, listener);
-}
-
-WL_EXPORT void
-ds_xdg_surface_add_unmap_listener(struct ds_xdg_surface *surface,
- struct wl_listener *listener)
-{
- wl_signal_add(&surface->events.unmap, listener);
-}
-
-struct ds_surface *
-ds_xdg_surface_get_surface(struct ds_xdg_surface *surface)
-{
- return surface->ds_surface;
-}
-
-struct ds_xdg_surface *
-create_xdg_surface(struct ds_xdg_client *client, struct ds_surface *ds_surface,
- uint32_t id)
-{
- struct ds_xdg_surface *surface;
-
- surface = calloc(1, sizeof *surface);
- if (!surface) {
- wl_client_post_no_memory(client->wl_client);
- return NULL;
- }
-
- surface->client = client;
- surface->role = DS_XDG_SURFACE_ROLE_NONE;
- surface->ds_surface = ds_surface;
- surface->resource = wl_resource_create(client->wl_client,
- &xdg_surface_interface, wl_resource_get_version(client->resource),
- id);
- if (!surface->resource) {
- free(surface);
- wl_client_post_no_memory(client->wl_client);
- return NULL;
- }
-
- if (ds_surface_has_buffer(surface->ds_surface)) {
- wl_resource_destroy(surface->resource);
- free(surface);
- wl_resource_post_error(client->resource,
- XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER,
- "xdg_surface must not have a buffer at creation");
- return NULL;
- }
-
- wl_list_init(&surface->configure_list);
-
- wl_signal_init(&surface->events.destroy);
- wl_signal_init(&surface->events.ping_timeout);
- wl_signal_init(&surface->events.new_popup);
- wl_signal_init(&surface->events.map);
- wl_signal_init(&surface->events.unmap);
- wl_signal_init(&surface->events.configure);
- wl_signal_init(&surface->events.ack_configure);
-
- surface->listener.surface_destroy.notify =
- xdg_surface_handle_surface_destroy;
- ds_surface_add_destroy_listener(ds_surface,
- &surface->listener.surface_destroy);
-
- surface->listener.surface_commit.notify =
- xdg_surface_handle_surface_commit;
- ds_surface_add_commit_listener(ds_surface,
- &surface->listener.surface_commit);
-
- wl_resource_set_implementation(surface->resource, &xdg_surface_impl,
- surface, xdg_surface_handle_resource_destroy);
-
- wl_list_insert(&client->surfaces, &surface->link);
-
- ds_inf("New xdg_surface %p (res %p)", surface, surface->resource);
-
- return surface;
-}
-
-void
-unmap_xdg_surface(struct ds_xdg_surface *surface)
-{
- struct ds_xdg_surface_configure *configure, *tmp;
-
- // TODO handle popup
-
- if (surface->mapped)
- wl_signal_emit(&surface->events.unmap, surface);
-
- switch (surface->role) {
- case DS_XDG_SURFACE_ROLE_TOPLEVEL:
- if (surface->toplevel->parent) {
- wl_list_remove(&surface->toplevel->parent_unmap.link);
- surface->toplevel->parent = NULL;
- }
- free(surface->toplevel->title);
- surface->toplevel->title = NULL;
- free(surface->toplevel->app_id);
- surface->toplevel->app_id = NULL;
- break;
- case DS_XDG_SURFACE_ROLE_POPUP:
- // TODO
- break;
- case DS_XDG_SURFACE_ROLE_NONE:
- assert(false && "not reached");
- }
-
- wl_list_for_each_safe(configure, tmp, &surface->configure_list, link)
- xdg_surface_configure_destroy(configure);
-
- if (surface->configure_idle) {
- wl_event_source_remove(surface->configure_idle);
- surface->configure_idle = NULL;
- }
-
- surface->configured = false;
- surface->mapped = false;
-}
-
-void
-reset_xdg_surface(struct ds_xdg_surface *surface)
-{
- struct ds_xdg_toplevel_requested *req;
-
- if (surface->role != DS_XDG_SURFACE_ROLE_NONE)
- unmap_xdg_surface(surface);
-
- if (surface->added) {
- wl_signal_emit(&surface->events.destroy, surface);
- surface->added = false;
- }
-
- switch (surface->role) {
- case DS_XDG_SURFACE_ROLE_TOPLEVEL:
- wl_resource_set_user_data(surface->toplevel->resource, NULL);
- surface->toplevel->resource = NULL;
- req = &surface->toplevel->requested;
- if (req->fullscreen_output)
- wl_list_remove(&req->fullscreen_output_destroy.link);
- free(surface->toplevel);
- surface->toplevel = NULL;
- break;
- case DS_XDG_SURFACE_ROLE_POPUP:
- // TODO
- break;
- case DS_XDG_SURFACE_ROLE_NONE:
- // This space is intentionally left blank
- break;
- }
-
- surface->role = DS_XDG_SURFACE_ROLE_NONE;
-}
-
-void
-destroy_xdg_surface(struct ds_xdg_surface *surface)
-{
- reset_xdg_surface(surface);
-
- wl_resource_set_user_data(surface->resource, NULL);
-
- ds_surface_reset_role_data(surface->ds_surface);
-
- wl_list_remove(&surface->link);
- wl_list_remove(&surface->listener.surface_destroy.link);
- wl_list_remove(&surface->listener.surface_commit.link);
-
- free(surface);
-}
-
-void
-handle_xdg_surface_commit(struct ds_surface *ds_surface)
-{
- struct ds_xdg_surface *surface;
-
- surface = ds_surface_get_role_data(ds_surface);
- surface->current = surface->pending;
-
- switch (surface->role) {
- case DS_XDG_SURFACE_ROLE_NONE:
- // inert toplevel or popup
- break;
- case DS_XDG_SURFACE_ROLE_TOPLEVEL:
- handle_xdg_surface_toplevel_committed(surface);
- // TODO
- break;
- case DS_XDG_SURFACE_ROLE_POPUP:
- // TODO
- break;
- }
-
- if (!surface->added) {
- surface->added = true;
- wl_signal_emit(&surface->client->shell->events.new_surface, surface);
- }
-
- if (surface->configured &&
- ds_surface_has_buffer(surface->ds_surface) &&
- !surface->mapped) {
- surface->mapped = true;
- wl_signal_emit(&surface->events.map, surface);
- }
-}
-
-void handle_xdg_surface_precommit(struct ds_surface *ds_surface)
-{
- struct ds_xdg_surface *surface;
-
- surface = ds_surface_get_role_data(ds_surface);
-
- // TODO
- (void)surface;
-}
-
-uint32_t
-ds_xdg_surface_schedule_configure(struct ds_xdg_surface *surface)
-{
- struct wl_display *display;
- struct wl_event_loop *loop;
-
- display = wl_client_get_display(surface->client->wl_client);
- loop = wl_display_get_event_loop(display);
-
- if (!surface->configure_idle) {
- surface->scheduled_serial = wl_display_next_serial(display);
- surface->configure_idle = wl_event_loop_add_idle(loop,
- surface_send_configure, surface);
- if (!surface->configure_idle)
- wl_client_post_no_memory(surface->client->wl_client);
- }
-
- return surface->scheduled_serial;
-}
-
-void
-ds_xdg_surface_ping(struct ds_xdg_surface *surface)
-{
-}
-
-static void
-xdg_surface_handle_surface_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_container_of(listener, surface, listener.surface_destroy);
- destroy_xdg_surface(surface);
-}
-
-static void
-xdg_surface_handle_surface_commit(struct wl_listener *listener, void *data)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_container_of(listener, surface, listener.surface_commit);
-
- if (ds_surface_has_buffer(surface->ds_surface) &&
- !surface->configured) {
- wl_resource_post_error(surface->resource,
- XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER,
- "xdg_surface has never been configured");
- return;
- }
-
- if (!ds_surface_get_role(surface->ds_surface)) {
- wl_resource_post_error(surface->resource,
- XDG_SURFACE_ERROR_NOT_CONSTRUCTED,
- "xdg_surface must have a role");
- return;
- }
-}
-
-static void
-xdg_surface_handle_resource_destroy(struct wl_resource *resource)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
- if (!surface)
- return;
-
- destroy_xdg_surface(surface);
-}
-
-static void
-xdg_surface_configure_destroy(struct ds_xdg_surface_configure *configure)
-{
- wl_list_remove(&configure->link);
- free(configure->toplevel_configure);
- free(configure);
-}
-
-static void
-xdg_surface_handle_destroy(struct wl_client *client,
- struct wl_resource *resource)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
-
- if (surface->role != DS_XDG_SURFACE_ROLE_NONE) {
- ds_err("Tried to destroy an xdg_surface before its role object");
- return;
- }
-
- wl_resource_destroy(resource);
-}
-
-static void
-xdg_surface_handle_get_toplevel(struct wl_client *client,
- struct wl_resource *resource, uint32_t id)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
- create_xdg_toplevel(surface, id);
-}
-
-static void
-xdg_surface_handle_get_popup(struct wl_client *client,
- struct wl_resource *resource, uint32_t id,
- struct wl_resource *parent_resource,
- struct wl_resource *positioner_resource)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
-
- // TODO
- (void)surface;
-}
-
-static void
-xdg_surface_handle_ack_configure(struct wl_client *client,
- struct wl_resource *resource, uint32_t serial)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
-
- if (surface->role == DS_XDG_SURFACE_ROLE_NONE) {
- wl_resource_post_error(surface->resource,
- XDG_SURFACE_ERROR_NOT_CONSTRUCTED,
- "xdg_surface must have a role");
- return;
- }
-
- bool found = false;
- struct ds_xdg_surface_configure *configure, *tmp;
- wl_list_for_each(configure, &surface->configure_list, link) {
- if (configure->serial == serial) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- wl_resource_post_error(surface->client->resource,
- XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
- "wrong configure serial: %u", serial);
- return;
- }
-
- wl_list_for_each_safe(configure, tmp, &surface->configure_list, link) {
- if (configure->serial == serial)
- break;
-
- wl_signal_emit(&surface->events.ack_configure, configure);
- xdg_surface_configure_destroy(configure);
- }
-
- switch (surface->role) {
- case DS_XDG_SURFACE_ROLE_NONE:
- assert(0 && "not reached");
- break;
- case DS_XDG_SURFACE_ROLE_TOPLEVEL:
- // TODO
- break;
- case DS_XDG_SURFACE_ROLE_POPUP:
- break;
- }
-
- surface->configured = true;
- surface->pending.configure_serial = serial;
-
- wl_signal_emit(&surface->events.ack_configure, configure);
- xdg_surface_configure_destroy(configure);
-}
-
-static void
-xdg_surface_handle_set_window_geometry(struct wl_client *client,
- struct wl_resource *resource,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
-
- if (surface->role == DS_XDG_SURFACE_ROLE_NONE) {
- wl_resource_post_error(surface->resource,
- XDG_SURFACE_ERROR_NOT_CONSTRUCTED,
- "xdg_surface must have a role");
- return;
- }
-
- if (width <= 0 || height <= 0) {
- ds_err("Client tried to set invalid geometry");
- wl_resource_post_error(resource, -1,
- "Tried to set invalid xdg_surface geometry");
- return;
- }
-
- surface->pending.geometry.x = x;
- surface->pending.geometry.y = y;
- surface->pending.geometry.width = width;
- surface->pending.geometry.height = height;
-}
-
-static const struct xdg_surface_interface xdg_surface_impl =
-{
- .destroy = xdg_surface_handle_destroy,
- .get_toplevel = xdg_surface_handle_get_toplevel,
- .get_popup = xdg_surface_handle_get_popup,
- .ack_configure = xdg_surface_handle_ack_configure,
- .set_window_geometry = xdg_surface_handle_set_window_geometry,
-};
-
-static void
-surface_send_configure(void *user_data)
-{
- struct ds_xdg_surface *surface;
- struct ds_xdg_surface_configure *configure;
-
- surface = user_data;
- surface->configure_idle = NULL;
-
- configure = calloc(1, sizeof *configure);
- if (!configure) {
- wl_client_post_no_memory(surface->client->wl_client);
- return;
- }
-
- wl_list_insert(surface->configure_list.prev, &configure->link);
- configure->serial = surface->scheduled_serial;
- configure->surface = surface;
-
- switch (surface->role) {
- case DS_XDG_SURFACE_ROLE_NONE:
- assert(0 && "not reached");
- break;
- case DS_XDG_SURFACE_ROLE_TOPLEVEL:
- send_xdg_toplevel_configure(surface, configure);
- break;
- case DS_XDG_SURFACE_ROLE_POPUP:
- break;
- }
-
- wl_signal_emit(&surface->events.configure, configure);
-
- xdg_surface_send_configure(surface->resource, configure->serial);
-}
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "xdg_shell.h"
-
-static const struct ds_surface_role xdg_toplevel_surface_role =
-{
- .name = "xdg_toplevel",
- .commit = handle_xdg_surface_commit,
-};
-
-static const struct xdg_toplevel_interface xdg_toplevel_impl;
-
-static void xdg_toplevel_handle_resource_destroy(struct wl_resource *resource);
-
-void
-create_xdg_toplevel(struct ds_xdg_surface *surface, uint32_t id)
-{
- if (!ds_surface_set_role(surface->ds_surface, &xdg_toplevel_surface_role,
- surface, surface->resource, XDG_WM_BASE_ERROR_ROLE))
- return;
-
- if (surface->role != DS_XDG_SURFACE_ROLE_NONE) {
- wl_resource_post_error(surface->resource,
- XDG_SURFACE_ERROR_ALREADY_CONSTRUCTED,
- "xdg_surface has already been constructed");
- return;
- }
-
- assert(surface->toplevel == NULL);
-
- surface->toplevel = calloc(1, sizeof *surface->toplevel);
- if (!surface->toplevel) {
- wl_resource_post_no_memory(surface->resource);
- return;
- }
-
- surface->toplevel->base = surface;
-
- wl_signal_init(&surface->toplevel->events.request_maximize);
- wl_signal_init(&surface->toplevel->events.request_fullscreen);
- wl_signal_init(&surface->toplevel->events.request_minimize);
- wl_signal_init(&surface->toplevel->events.request_move);
- wl_signal_init(&surface->toplevel->events.request_resize);
- wl_signal_init(&surface->toplevel->events.request_show_window_menu);
- wl_signal_init(&surface->toplevel->events.set_parent);
- wl_signal_init(&surface->toplevel->events.set_title);
- wl_signal_init(&surface->toplevel->events.set_app_id);
-
- surface->toplevel->resource = wl_resource_create(
- surface->client->wl_client, &xdg_toplevel_interface,
- wl_resource_get_version(surface->resource), id);
- if (!surface->toplevel->resource) {
- free(surface->toplevel);
- wl_resource_post_no_memory(surface->resource);
- return;
- }
-
- wl_resource_set_implementation(surface->toplevel->resource,
- &xdg_toplevel_impl, surface,
- xdg_toplevel_handle_resource_destroy);
-
- surface->role = DS_XDG_SURFACE_ROLE_TOPLEVEL;
-}
-
-void
-handle_xdg_surface_toplevel_committed(struct ds_xdg_surface *surface)
-{
- if (!surface->toplevel->added) {
- ds_xdg_surface_schedule_configure(surface);
- surface->toplevel->added = true;
- return;
- }
-
- surface->toplevel->current = surface->toplevel->pending;
-}
-
-void
-send_xdg_toplevel_configure(struct ds_xdg_surface *surface,
- struct ds_xdg_surface_configure *configure)
-{
- struct wl_array states;
- uint32_t width, height;
-
- configure->toplevel_configure =
- malloc(sizeof *configure->toplevel_configure);
- if (!configure->toplevel_configure) {
- wl_resource_post_no_memory(surface->toplevel->resource);
- return;
- }
-
- *configure->toplevel_configure = surface->toplevel->scheduled;
-
- wl_array_init(&states);
- if (surface->toplevel->scheduled.maximized) {
- uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
- if (!s)
- goto error_out;
- *s = XDG_TOPLEVEL_STATE_MAXIMIZED;
- }
-
- if (surface->toplevel->scheduled.fullscreen) {
- uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
- if (!s)
- goto error_out;
- *s = XDG_TOPLEVEL_STATE_FULLSCREEN;
- }
-
- if (surface->toplevel->scheduled.resizing) {
- uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
- if (!s)
- goto error_out;
- *s = XDG_TOPLEVEL_STATE_RESIZING;
- }
-
- if (surface->toplevel->scheduled.activated) {
- uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
- if (!s)
- goto error_out;
- *s = XDG_TOPLEVEL_STATE_ACTIVATED;
- }
-
- if (surface->toplevel->scheduled.tiled) {
- ;;;
- // TODO
- }
-
- width = surface->toplevel->scheduled.width;
- height = surface->toplevel->scheduled.height;
-
- xdg_toplevel_send_configure(surface->toplevel->resource, width, height,
- &states);
- wl_array_release(&states);
-
- return;
-
-error_out:
- wl_array_release(&states);
- wl_resource_post_no_memory(surface->toplevel->resource);
-}
-
-void
-destroy_xdg_toplevel(struct ds_xdg_surface *xdg_surface)
-{
- reset_xdg_surface(xdg_surface);
-}
-
-static void
-xdg_toplevel_handle_destroy(struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static void
-xdg_toplevel_handle_set_parent(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *parent_resource)
-{
- // TODO
-}
-
-static void
-xdg_toplevel_handle_set_title(struct wl_client *client,
- struct wl_resource *resource, const char *title)
-{
- struct ds_xdg_surface *surface;
- char *tmp;
-
- surface = wl_resource_get_user_data(resource);
- tmp = strdup(title);
- if (!tmp) {
- wl_resource_post_no_memory(resource);
- return;
- }
-
- if (surface->toplevel->title)
- free(surface->toplevel->title);
-
- surface->toplevel->title = tmp;
- wl_signal_emit(&surface->toplevel->events.set_title, surface);
-}
-
-static void
-xdg_toplevel_handle_set_app_id(struct wl_client *client,
- struct wl_resource *resource, const char *app_id)
-{
- struct ds_xdg_surface *surface;
- char *tmp;
-
- surface = wl_resource_get_user_data(resource);
- tmp = strdup(app_id);
- if (!tmp) {
- wl_resource_post_no_memory(resource);
- return;
- }
-
- if (surface->toplevel->app_id)
- free(surface->toplevel->app_id);
-
- surface->toplevel->app_id= tmp;
- wl_signal_emit(&surface->toplevel->events.set_app_id, surface);
-
-}
-
-static void
-xdg_toplevel_handle_show_window_menu(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *seat_resource,
- uint32_t serial, int32_t x, int32_t y)
-{
- // TODO
-}
-
-static void
-xdg_toplevel_handle_move(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *seat_resource,
- uint32_t serial)
-{
- // TODO
-}
-
-static void
-xdg_toplevel_handle_resize(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *seat_resource,
- uint32_t serial, uint32_t edges)
-{
- // TODO
-}
-
-static void
-xdg_toplevel_handle_set_max_size(struct wl_client *client,
- struct wl_resource *resource, int32_t width, int32_t height)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
- surface->toplevel->pending.max_width = width;
- surface->toplevel->pending.max_height = height;
-}
-
-static void
-xdg_toplevel_handle_set_min_size(struct wl_client *client,
- struct wl_resource *resource, int32_t width, int32_t height)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
- surface->toplevel->pending.min_width = width;
- surface->toplevel->pending.min_height = height;
-}
-
-static void
-xdg_toplevel_handle_set_maximized(struct wl_client *client,
- struct wl_resource *resource)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
- surface->toplevel->requested.maximized = true;
- wl_signal_emit(&surface->toplevel->events.request_maximize, surface);
- ds_xdg_surface_schedule_configure(surface);
-}
-
-static void
-xdg_toplevel_handle_unset_maximized(struct wl_client *client,
- struct wl_resource *resource)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
- surface->toplevel->requested.maximized = false;
- wl_signal_emit(&surface->toplevel->events.request_maximize, surface);
- ds_xdg_surface_schedule_configure(surface);
-}
-
-static void
-xdg_toplevel_handle_set_fullscreen(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *output_resource)
-{
- // TODO
-}
-
-static void
-xdg_toplevel_handle_unset_fullscreen(struct wl_client *client,
- struct wl_resource *resource)
-{
- // TODO
-}
-
-static void
-xdg_toplevel_handle_set_minimized(struct wl_client *client,
- struct wl_resource *resource)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
- surface->toplevel->requested.minimized = true;
- wl_signal_emit(&surface->toplevel->events.request_maximize, surface);
-}
-
-static const struct xdg_toplevel_interface xdg_toplevel_impl =
-{
- xdg_toplevel_handle_destroy,
- xdg_toplevel_handle_set_parent,
- xdg_toplevel_handle_set_title,
- xdg_toplevel_handle_set_app_id,
- xdg_toplevel_handle_show_window_menu,
- xdg_toplevel_handle_move,
- xdg_toplevel_handle_resize,
- xdg_toplevel_handle_set_max_size,
- xdg_toplevel_handle_set_min_size,
- xdg_toplevel_handle_set_maximized,
- xdg_toplevel_handle_unset_maximized,
- xdg_toplevel_handle_set_fullscreen,
- xdg_toplevel_handle_unset_fullscreen,
- xdg_toplevel_handle_set_minimized,
-};
-
-static void
-xdg_toplevel_handle_resource_destroy(struct wl_resource *resource)
-{
- struct ds_xdg_surface *surface;
-
- surface = wl_resource_get_user_data(resource);
- if (!surface)
- return;
-
- destroy_xdg_toplevel(surface);
-}
native: true,
)
-subdir('libds')
-if get_option('tizen')
- subdir('libds-tizen')
-endif
-subdir('tests')
+subdir('libds-tizen')
+#subdir('tests')
subdir('examples')
subdir('clients')
tests = [
{ 'name': 'test-compositor' },
{ 'name': 'test-backend' },
- {
+ {
'name': 'test-surface',
'deps': [ dependency('wayland-client') ],
},
]
foreach t : tests
- t_deps = [ dep_libds ]
+ t_deps = [ dep_libds_tizen ]
t_deps += t.get('deps', [])
- test('libds-' + t.get('name'),
- executable('libds-' + t.get('name'), t.get('name') + '.c',
+ test('libds-tizen-' + t.get('name'),
+ executable('libds-tizen-' + t.get('name'), t.get('name') + '.c',
dependencies: t_deps ,
include_directories: common_inc,
install: false