+++ /dev/null
-#ifndef LIBDS_TIZEN_ALLOCATOR_TBM_H
-#define LIBDS_TIZEN_ALLOCATOR_TBM_H
-
-#include <libds/allocator.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_allocator *
-ds_tbm_allocator_create(void);
-
-WL_EXPORT void *
-ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_TIZEN_BACKEND_TDM_H
-#define LIBDS_TIZEN_BACKEND_TDM_H
-
-#include <libds/backend.h>
-#include <libds/buffer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_tdm_output;
-
-struct ds_tdm_buffer_queue;
-
-struct ds_backend *
-ds_tdm_backend_create(struct wl_display *display);
-
-struct ds_tdm_output *
-ds_tdm_output_from_output(struct ds_output *ds_output);
-
-struct ds_tdm_buffer_queue *
-ds_tdm_output_get_buffer_queue(struct ds_tdm_output *output);
-
-void *
-ds_tdm_buffer_queue_get_native_queue(struct ds_tdm_buffer_queue *queue);
-
-struct ds_buffer *
-ds_tdm_buffer_queue_acquire(struct ds_tdm_buffer_queue *queue);
-
-void
-ds_tdm_buffer_queue_add_acquirable_listener(struct ds_tdm_buffer_queue *queue,
- struct wl_listener *listener);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_DPMS_H
-#define LIBDS_DPMS_H
-
-#include <stdint.h>
-#include <wayland-server.h>
-#include <tizen-dpms-server-protocol.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_tizen_dpms;
-
-enum ds_tizen_dpms_mode
-{
- DS_TIZEN_DPMS_MODE_ON = TIZEN_DPMS_MANAGER_MODE_ON,
- DS_TIZEN_DPMS_MODE_STANDBY = TIZEN_DPMS_MANAGER_MODE_STANDBY,
- DS_TIZEN_DPMS_MODE_SUSPEND = TIZEN_DPMS_MANAGER_MODE_SUSPEND,
- DS_TIZEN_DPMS_MODE_OFF = TIZEN_DPMS_MANAGER_MODE_OFF,
-};
-
-enum ds_tizen_dpms_error
-{
- DS_TIZEN_DPMS_ERROR_NONE = TIZEN_DPMS_MANAGER_ERROR_NONE,
- DS_TIZEN_DPMS_ERROR_INVALID_PERMISSION = TIZEN_DPMS_MANAGER_ERROR_INVALID_PERMISSION,
- DS_TIZEN_DPMS_ERROR_INVALID_PARAMETER = TIZEN_DPMS_MANAGER_ERROR_INVALID_PARAMETER,
- DS_TIZEN_DPMS_ERROR_NOT_SUPPORTED = TIZEN_DPMS_MANAGER_ERROR_NOT_SUPPORTED,
- DS_TIZEN_DPMS_ERROR_ALREADY_DONE = TIZEN_DPMS_MANAGER_ERROR_ALREADY_DONE,
-};
-
-struct ds_tizen_dpms_event
-{
- //struct ds_output *output;
- enum ds_tizen_dpms_mode mode;
-};
-
-struct ds_tizen_dpms *
-ds_tizen_dpms_create(struct wl_display *display);
-
-void
-ds_tizen_dpms_add_destroy_listener(struct ds_tizen_dpms *dpms,
- struct wl_listener *listener);
-
-void
-ds_tizen_dpms_add_set_dpms_listener(struct ds_tizen_dpms *dpms,
- struct wl_listener *listener);
-
-void
-ds_tizen_dpms_add_get_dpms_listener(struct ds_tizen_dpms *dpms,
- struct wl_listener *listener);
-
-void
-ds_tizen_dpms_send_set_result(struct ds_tizen_dpms *dpms,
- enum ds_tizen_dpms_mode mode, enum ds_tizen_dpms_error error);
-
-void
-ds_tizen_dpms_send_get_result(struct ds_tizen_dpms *dpms,
- enum ds_tizen_dpms_mode mode, enum ds_tizen_dpms_error error);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_TIZEN_INPUT_DEVICEMGR_H
-#define LIBDS_TIZEN_INPUT_DEVICEMGR_H
-
-#include <wayland-server.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_tizen_input_devicemgr;
-struct ds_backend;
-struct ds_seat;
-
-struct ds_tizen_input_devicemgr_keymap_data
-{
- char *name;
- int keycode;
-
- struct wl_list link;
-};
-
-struct ds_tizen_input_devicemgr *
-ds_tizen_input_devicemgr_create(struct ds_backend *backend,
- struct ds_seat *seat);
-
-void
-ds_tizen_input_devicemgr_add_destroy_listener(
- struct ds_tizen_input_devicemgr *devicemgr,
- struct wl_listener *listener);
-
-bool
-ds_tizen_input_devicemgr_set_keymap_list(
- struct ds_tizen_input_devicemgr *devicemgr,
- struct wl_list *list);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_TIZEN_KEYROUTER_H
-#define LIBDS_TIZEN_KEYROUTER_H
-
-#include <wayland-server.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_tizen_keyrouter;
-
-struct ds_tizen_keyrouter *
-ds_tizen_keyrouter_create(struct wl_display *display);
-
-void
-ds_tizen_keyrouter_add_destroy_listener(struct ds_tizen_keyrouter *keyrouter,
- struct wl_listener *listener);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef LIBDS_TIZEN_TBM_SERVER_H
-#define LIBDS_TIZEN_TBM_SERVER_H
-
-#include <wayland-server.h>
-#include <tbm_surface.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ds_tbm_server;
-
-struct ds_tbm_client_buffer;
-
-struct ds_tbm_server *
-ds_tbm_server_create(struct wl_display *display);
-
-void
-ds_tbm_server_add_destroy_listener(struct ds_tbm_server *tbm,
- struct wl_listener *listener);
-
-struct ds_tbm_client_buffer *
-ds_tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer);
-
-tbm_surface_h
-ds_tbm_client_buffer_get_tbm_surface(struct ds_tbm_client_buffer *buffer);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
install_subdir('libds',
install_dir: get_option('includedir'),
)
-
-if get_option('tizen')
- install_subdir('libds-tizen',
- install_dir: get_option('includedir'),
- )
-endif
-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
BuildRequires: pkgconfig(wayland-server)
BuildRequires: pkgconfig(wayland-client)
BuildRequires: pkgconfig(wayland-protocols)
-BuildRequires: pkgconfig(tizen-extension-server)
-BuildRequires: pkgconfig(tizen-extension-client)
BuildRequires: pkgconfig(pixman-1)
BuildRequires: pkgconfig(libdrm)
BuildRequires: pkgconfig(xkbcommon)
BuildRequires: pkgconfig(libinput)
BuildRequires: pkgconfig(libudev)
-BuildRequires: pkgconfig(libtdm)
-BuildRequires: pkgconfig(libtbm)
-BuildRequires: pkgconfig(wayland-tbm-server)
-BuildRequires: pkgconfig(wayland-tbm-client)
-BuildRequires: pkgconfig(tizen-dpms-server)
-BuildRequires: pkgconfig(tizen-dpms-client)
-BuildRequires: pkgconfig(cynara-client)
-BuildRequires: pkgconfig(cynara-session)
-BuildRequires: pkgconfig(libsmack)
-
%description
Wayland Compositor Library
%description devel
Development package of Wayland Compositor Library
-%package tizen-devel
-Summary: Wayland Compositor development package on Tizen
-
-%description tizen-devel
-Wayland Compositor development library for Tizen platform
-
-%package tizen-keyrouter
-Summary: Wayland Compositor Library for keyrouter
-Group: Development/Libraries
-
-%description tizen-keyrouter
-Wayland Compositor Library for tizen keyrouter
-
-%package tizen-keyrouter-devel
-Summary: Keyrouter Development package for Wayland Compositor Library
-Group: Development/Libraries
-
-%description tizen-keyrouter-devel
-Keyrouter Development package for Wayland Compositor Library
-
-%package tizen-input-devicemgr
-Summary: Library for tizen input devicemgr
-Group: Development/Libraries
-
-%description tizen-input-devicemgr
-Library for tizen input devicemgr
-
-%package tizen-input-devicemgr-devel
-Summary: Development package for tizen input devicemgr
-Group: Development/Libraries
-
-%description tizen-input-devicemgr-devel
-Development package for tizen input devicemgr
-
%prep
%setup -q
cp %{SOURCE1001} .
--prefix /usr \
--libdir %{_libdir} \
--bindir %{_bindir} \
- builddir \
- -Dtizen=true \
- -Dkeylayout_dir="%{TZ_SYS_RO_SHARE}/X11/xkb/tizen_key_layout.txt"
+ builddir
ninja -C builddir all
%install
%defattr(-,root,root,-)
%license LICENSE
%{_libdir}/libds.so.*
-%{_libdir}/libds-tizen.so.*
%files devel
%manifest %{name}.manifest
%{_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}/tdm-backend
-%{_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
-%manifest %{name}.manifest
-%defattr(-,root,root,-)
-%license LICENSE
-%{_libdir}/libds-tizen-keyrouter.so.*
-
-%files tizen-keyrouter-devel
-%manifest %{name}.manifest
-%defattr(-,root,root,-)
-%license LICENSE
-%{_includedir}/libds-tizen/keyrouter.h
-%{_libdir}/pkgconfig/libds-tizen-keyrouter.pc
-%{_libdir}/libds-tizen-keyrouter.so
-
-%files tizen-input-devicemgr
-%manifest %{name}.manifest
-%defattr(-,root,root,-)
-%license LICENSE
-%{_libdir}/libds-tizen-input-devicemgr.so.*
-
-%files tizen-input-devicemgr-devel
-%manifest %{name}.manifest
-%defattr(-,root,root,-)
-%license LICENSE
-%{_includedir}/libds-tizen/input-devicemgr.h
-%{_libdir}/pkgconfig/libds-tizen-input-devicemgr.pc
-%{_libdir}/libds-tizen-input-devicemgr.so
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)
-
-if not wayland_tbm_client.found() or not libtbm.found()
- subdir_done()
-endif
-
-simple_tbm_files = ['simple-tbm.c']
-simple_tbm_deps = [
- dependency('wayland-client', required: true),
- wayland_tbm_client,
- libtbm,
- tizen_extension_client,
-]
-
-protocols = {
- 'xdg-shell': wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml',
-}
-
-protocols_code = {}
-protocols_client_header = {}
-foreach name, path : protocols
- code = custom_target(
- name.underscorify() + '_c',
- input: path,
- output: '@BASENAME@-protocol.c',
- command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'],
- )
- simple_tbm_files += code
-
- 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,
- )
- simple_tbm_files += client_header
-endforeach
-
-executable('ds-simple-tbm',
- simple_tbm_files,
- dependencies: simple_tbm_deps,
- install_dir: libds_bindir,
- install: true,
-)
-
-executable('ds-simple-dpms',
- 'simple-dpms.c',
- dependencies: [
- dependency('wayland-client', required: true),
- dependency('tizen-dpms-client', required: true),
- ],
- install_dir: libds_bindir,
- install: true,
-)
-
-input_generator_files = ['input-generator.c']
-input_generator_deps = [
- dependency('wayland-client', required: true),
- tizen_extension_client,
-]
-
-executable('input-generator',
- input_generator_files,
- dependencies: input_generator_deps,
- install_dir: libds_bindir,
- install: true,
-)
+++ /dev/null
-/*
- * Copyright © 2011 Benjamin Franzke
- * Copyright © 2010 Intel Corporation
- *
- * 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 <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <assert.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <signal.h>
-#include <errno.h>
-
-#include <wayland-client.h>
-#include <wayland-tbm-client.h>
-#include <tbm_surface.h>
-#include <tbm_surface_internal.h>
-#include "xdg-shell-client-protocol.h"
-#include <tizen-extension-client-protocol.h>
-
-static uint64_t buffer_info_key;
-#define BUFFER_INFO_KEY (unsigned long)(&buffer_info_key)
-
-struct display {
- struct wl_display *display;
- struct wl_registry *registry;
- struct wl_compositor *compositor;
- struct xdg_wm_base *wm_base;
- struct wl_shm *shm;
- struct wl_seat *seat;
- struct wayland_tbm_client *wl_tbm;
- bool has_xrgb;
-
- struct tizen_input_device_manager *devicemgr;
- int notified;
- bool blocked;
-};
-
-struct window {
- struct display *display;
- int width, height;
- struct wl_surface *surface;
- struct xdg_surface *xdg_surface;
- struct xdg_toplevel *xdg_toplevel;
- struct wl_callback *callback;
- tbm_surface_queue_h surface_queue;
- bool wait_for_configure;
-};
-
-struct buffer_info {
- struct window *window;
- struct wl_buffer *wl_buffer;
-};
-
-static int running = 1;
-
-static void
-redraw(void *data, struct wl_callback *callback, uint32_t time);
-
-static void
-handle_xdg_surface_configure(void *data, struct xdg_surface *surface,
- uint32_t serial)
-{
- struct window *window = data;
-
- xdg_surface_ack_configure(surface, serial);
-
- if (window->wait_for_configure) {
- redraw(window, NULL, 0);
- window->wait_for_configure = false;
- }
-}
-
-static const struct xdg_surface_listener xdg_surface_listener = {
- handle_xdg_surface_configure,
-};
-
-static void
-handle_xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
- int32_t width, int32_t height,
- struct wl_array *state)
-{
-}
-
-static void
-handle_xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel)
-{
- running = 0;
-}
-
-static const struct xdg_toplevel_listener xdg_toplevel_listener = {
- handle_xdg_toplevel_configure,
- handle_xdg_toplevel_close,
-};
-
-static struct window *
-create_window(struct display *display, int width, int height)
-{
- struct window *window;
-
- window = calloc(1, sizeof *window);
- if (!window)
- return NULL;
-
- window->callback = NULL;
- window->display = display;
- window->width = width;
- window->height = height;
- window->surface = wl_compositor_create_surface(display->compositor);
-
- if (display->wm_base) {
- window->xdg_surface =
- xdg_wm_base_get_xdg_surface(display->wm_base,
- window->surface);
- assert(window->xdg_surface);
- xdg_surface_add_listener(window->xdg_surface,
- &xdg_surface_listener, window);
-
- window->xdg_toplevel =
- xdg_surface_get_toplevel(window->xdg_surface);
- assert(window->xdg_toplevel);
- xdg_toplevel_add_listener(window->xdg_toplevel,
- &xdg_toplevel_listener, window);
-
- xdg_toplevel_set_title(window->xdg_toplevel, "simple-tbm");
- wl_surface_commit(window->surface);
- window->wait_for_configure = true;
- } else {
- assert(0);
- }
-
- window->surface_queue =
- wayland_tbm_client_create_surface_queue(display->wl_tbm,
- window->surface,
- 3,
- width,
- height,
- TBM_FORMAT_XRGB8888);
- assert(window->surface_queue);
-
- return window;
-}
-
-static void
-destroy_window(struct window *window)
-{
- tbm_surface_queue_destroy(window->surface_queue);
-
- if (window->callback)
- wl_callback_destroy(window->callback);
-
- if (window->xdg_toplevel)
- xdg_toplevel_destroy(window->xdg_toplevel);
- if (window->xdg_surface)
- xdg_surface_destroy(window->xdg_surface);
- wl_surface_destroy(window->surface);
- free(window);
-}
-
-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 void
-buffer_info_free_cb(void *data)
-{
- struct buffer_info *buffer_info = data;
-
- if (!buffer_info)
- return;
-
- wayland_tbm_client_destroy_buffer(buffer_info->window->display->wl_tbm,
- buffer_info->wl_buffer);
- free(buffer_info);
-}
-
-static void
-buffer_handle_release(void *data, struct wl_buffer *wl_buffer)
-{
- tbm_surface_h surface = data;
- struct buffer_info *buffer_info;
-
- tbm_surface_internal_get_user_data(surface, BUFFER_INFO_KEY,
- (void **)&buffer_info);
- if (buffer_info)
- tbm_surface_queue_release(buffer_info->window->surface_queue, surface);
-}
-
-static const struct wl_buffer_listener buffer_listener = {
- .release = buffer_handle_release,
-};
-
-static const struct wl_callback_listener frame_listener;
-
-static void
-redraw(void *data, struct wl_callback *callback, uint32_t time)
-{
- struct window *window = data;
- struct buffer_info *buffer_info = NULL;
- tbm_surface_h surface = NULL;
- tbm_surface_info_s surface_info;
-
- if (!tbm_surface_queue_can_dequeue(window->surface_queue, 0))
- return;
-
- tbm_surface_queue_dequeue(window->surface_queue, &surface);
- assert(surface);
-
- tbm_surface_internal_get_user_data(surface, BUFFER_INFO_KEY,
- (void **)&buffer_info);
- if (!buffer_info) {
- buffer_info = calloc(1, sizeof *buffer_info);
- assert(buffer_info);
-
- tbm_surface_internal_add_user_data(surface, BUFFER_INFO_KEY, buffer_info_free_cb);
- tbm_surface_internal_set_user_data(surface, BUFFER_INFO_KEY, buffer_info);
-
- buffer_info->wl_buffer =
- wayland_tbm_client_create_buffer(window->display->wl_tbm, surface);
- assert(buffer_info->wl_buffer);
-
- wl_buffer_add_listener(buffer_info->wl_buffer, &buffer_listener,
- surface);
-
- buffer_info->window = window;
- }
-
- tbm_surface_map(surface, TBM_SURF_OPTION_WRITE, &surface_info);
-
- paint_pixels(surface_info.planes[0].ptr, 20,
- (surface_info.planes[0].stride/4), surface_info.height, time);
-
- tbm_surface_unmap(surface);
-
- wl_surface_attach(window->surface, buffer_info->wl_buffer, 0, 0);
- wl_surface_damage(window->surface,
- 20, 20, window->width - 40, window->height - 40);
-
- if (callback)
- wl_callback_destroy(callback);
-
- window->callback = wl_surface_frame(window->surface);
- wl_callback_add_listener(window->callback, &frame_listener, window);
- wl_surface_commit(window->surface);
-}
-
-static const struct wl_callback_listener frame_listener = {
- redraw
-};
-
-static void
-shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
-{
- struct display *d = data;
-
- if (format == WL_SHM_FORMAT_XRGB8888)
- d->has_xrgb = true;
-}
-
-struct wl_shm_listener shm_listener = {
- shm_format
-};
-
-static void
-xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial)
-{
- xdg_wm_base_pong(shell, serial);
-}
-
-static const struct xdg_wm_base_listener xdg_wm_base_listener = {
- xdg_wm_base_ping,
-};
-
-static void pointer_handle_button(void *data, struct wl_pointer *pointer,
- uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
-{
- if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
- fprintf(stderr, "pointer_handle_button: PRESSED\n");
- }
- else {
- fprintf(stderr, "pointer_handle_button: RELEASED\n");
- }
-}
-
-static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
- uint32_t serial, struct wl_surface *surface,
- wl_fixed_t surface_x, wl_fixed_t surface_y)
-{
- fprintf(stderr, "pointer_handle_enter surface_x:%d, surface_y:%d\n",
- wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y));
-}
-
-static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer,
- uint32_t serial, struct wl_surface *surface)
-{
- fprintf(stderr, "pointer_handle_leave\n");
-}
-
-static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
- uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y)
-{
- fprintf(stderr, "pointer_handle_motion surface_x:%d, surface_y:%d\n",
- wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y));
-}
-
-static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer)
-{
- fprintf(stderr, "pointer_handle_frame\n");
-}
-
-static struct wl_pointer_listener pointer_listener = {
- .enter = pointer_handle_enter,
- .leave = pointer_handle_leave,
- .motion = pointer_handle_motion,
- .button = pointer_handle_button,
- .axis = NULL,
- .frame = pointer_handle_frame,
- .axis_source = NULL,
- .axis_stop = NULL,
- .axis_discrete = NULL,
-};
-
-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 x, wl_fixed_t y)
-{
- fprintf(stderr, "touch_handle_down id:%d, x:%d, y:%d\n",
- id, wl_fixed_to_int(x), wl_fixed_to_int(y));
-
- struct display *d = data;
-
- tizen_input_device_manager_block_events(d->devicemgr, 0, TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD, 50000);
-
- while (d->notified == -1)
- wl_display_roundtrip(d->display);
-
- if (d->notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
- printf("Success to block keyboard events\n");
- } else {
- printf("Failed to block keyboard events: %d\n", d->notified);
- }
- d->notified = -1;
- d->blocked = true;
-}
-
-static void touch_handle_up(void *data, struct wl_touch *wl_touch,
- uint32_t serial, uint32_t time, int32_t id)
-{
- fprintf(stderr, "touch_handle_up id:%d\n", id);
-
- struct display *d = data;
-
- if (!d->blocked) return;
- tizen_input_device_manager_unblock_events(d->devicemgr, 0);
-
- while (d->notified == -1)
- wl_display_roundtrip(d->display);
-
- if (d->notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
- printf("Success to unblock keyboard events\n");
- } else {
- printf("Failed to unblock keyboard events: %d\n", d->notified);
- }
- d->notified = -1;
- d->blocked = false;
-}
-
-static void touch_handle_motion(void *data, struct wl_touch *wl_touch,
- uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y)
-{
- fprintf(stderr, "touch_handle_motion id:%d, x:%d, y:%d\n",
- id, wl_fixed_to_int(x), wl_fixed_to_int(y));
-}
-
-static void touch_handle_frame(void *data, struct wl_touch *wl_touch)
-{
- fprintf(stderr, "touch_handle_frame\n");
-}
-
-static struct wl_touch_listener touch_listener = {
- .down = touch_handle_down,
- .up = touch_handle_up,
- .motion = touch_handle_motion,
- .frame = touch_handle_frame,
- .cancel = NULL,
- .shape = NULL,
- .orientation = NULL,
-};
-
-static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
- uint32_t format, int32_t fd, uint32_t size)
-{
- fprintf(stderr, "keyboard_handle_keymap\n");
-}
-static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard,
- uint32_t serial, struct wl_surface *surface, struct wl_array *keys)
-{
- fprintf(stderr, "keyboard_handle_enter\n");
-}
-static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
- uint32_t serial, struct wl_surface *surface)
-{
- fprintf(stderr, "keyboard_handle_leave\n");
-}
-static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
- uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
- uint32_t mods_locked, uint32_t group)
-{
- fprintf(stderr, "keyboard_handle_modifiers\n");
-}
-static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard,
- int32_t rate, int32_t delay)
-{
- fprintf(stderr, "keyboard_handle_repeat_info\n");
-}
-
-static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
- uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
-{
- if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
- fprintf(stderr, "keyboard_handle_key: key:%d, PRESSED\n", key);
- } else {
- fprintf(stderr, "keyboard_handle_key: key:%d, RELEASED\n", key);
- }
-}
-
-static struct wl_keyboard_listener 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 void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
- enum wl_seat_capability caps)
-{
- struct display *d = data;
- if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
- struct wl_keyboard *keyboard = wl_seat_get_keyboard(wl_seat);
- wl_keyboard_add_listener(keyboard, &keyboard_listener, NULL);
- fprintf(stderr, "seat_handle_capabilities: keyboard\n");
- }
- if ((caps & WL_SEAT_CAPABILITY_POINTER)) {
- struct wl_pointer *pointer = wl_seat_get_pointer(wl_seat);
- wl_pointer_add_listener(pointer, &pointer_listener, NULL);
- fprintf(stderr, "seat_handle_capabilities: pointer\n");
- }
- if ((caps & WL_SEAT_CAPABILITY_TOUCH)) {
- struct wl_touch *touch = wl_seat_get_touch(wl_seat);
- wl_touch_add_listener(touch, &touch_listener, d);
- fprintf(stderr, "seat_handle_capabilities: touch\n");
- }
-}
-
-static void seat_handle_name(void *data, struct wl_seat *wl_seat,
- const char *name)
-{
- fprintf(stderr, "seat_handle_name name:%s\n", name);
-}
-
-const struct wl_seat_listener seat_listener = {
- .capabilities = seat_handle_capabilities,
- .name = seat_handle_name,
-};
-
-static void
-input_device_manager_handle_error(void *data,
- struct tizen_input_device_manager *tizen_input_device_manager,
- uint32_t errorcode)
-{
- struct display *d = data;
- fprintf(stderr, "errorcode: %d\n", errorcode);
- d->notified = errorcode;
-}
-
-static void
-input_device_manager_handle_block_expired(void *data,
- struct tizen_input_device_manager *tizen_input_device_manager)
-{
- fprintf(stderr, "block expired\n");
-}
-
-static const struct tizen_input_device_manager_listener _input_device_manager_listener =
-{
- .device_add = NULL,
- .device_remove = NULL,
- .error = input_device_manager_handle_error,
- .block_expired = input_device_manager_handle_block_expired,
-};
-
-static void
-registry_handle_global(void *data, struct wl_registry *registry,
- uint32_t id, const char *interface, uint32_t version)
-{
- struct display *d = data;
-
- if (strcmp(interface, "wl_compositor") == 0) {
- d->compositor =
- wl_registry_bind(registry,
- id, &wl_compositor_interface, 1);
- } else if (strcmp(interface, "xdg_wm_base") == 0) {
- d->wm_base = wl_registry_bind(registry,
- id, &xdg_wm_base_interface, 1);
- xdg_wm_base_add_listener(d->wm_base, &xdg_wm_base_listener, d);
- } else if (strcmp(interface, "wl_shm") == 0) {
- d->shm = wl_registry_bind(registry,
- id, &wl_shm_interface, 1);
- wl_shm_add_listener(d->shm, &shm_listener, d);
- } else if (strcmp(interface, "wl_seat") == 0) {
- d->seat = wl_registry_bind(registry,
- id, &wl_seat_interface, 7);
- wl_seat_add_listener(d->seat, &seat_listener, d);
- fprintf(stderr, "wl_seat bound!\n");
- } else if (strcmp(interface, "tizen_input_device_manager") == 0) {
- d->devicemgr = wl_registry_bind(registry,
- id, &tizen_input_device_manager_interface, version);
- tizen_input_device_manager_add_listener(d->devicemgr,
- &_input_device_manager_listener, d);
- fprintf(stderr, "tizen input device manager bound!\n");
- }
-}
-
-static void
-registry_handle_global_remove(void *data, struct wl_registry *registry,
- uint32_t name)
-{
-}
-
-static const struct wl_registry_listener registry_listener = {
- registry_handle_global,
- registry_handle_global_remove
-};
-
-static struct display *
-create_display(void)
-{
- struct display *display;
-
- display = calloc(1, sizeof *display);
- if (display == NULL) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
- display->display = wl_display_connect(NULL);
- assert(display->display);
-
- display->has_xrgb = false;
- display->registry = wl_display_get_registry(display->display);
- wl_registry_add_listener(display->registry,
- ®istry_listener, display);
- wl_display_roundtrip(display->display);
- if (display->shm == NULL) {
- fprintf(stderr, "No wl_shm global\n");
- exit(1);
- }
-
- wl_display_roundtrip(display->display);
-
- /*
- * Why do we need two roundtrips here?
- *
- * wl_display_get_registry() sends a request to the server, to which
- * the server replies by emitting the wl_registry.global events.
- * The first wl_display_roundtrip() sends wl_display.sync. The server
- * first processes the wl_display.get_registry which includes sending
- * the global events, and then processes the sync. Therefore when the
- * sync (roundtrip) returns, we are guaranteed to have received and
- * processed all the global events.
- *
- * While we are inside the first wl_display_roundtrip(), incoming
- * events are dispatched, which causes registry_handle_global() to
- * be called for each global. One of these globals is wl_shm.
- * registry_handle_global() sends wl_registry.bind request for the
- * wl_shm global. However, wl_registry.bind request is sent after
- * the first wl_display.sync, so the reply to the sync comes before
- * the initial events of the wl_shm object.
- *
- * The initial events that get sent as a reply to binding to wl_shm
- * include wl_shm.format. These tell us which pixel formats are
- * supported, and we need them before we can create buffers. They
- * don't change at runtime, so we receive them as part of init.
- *
- * When the reply to the first sync comes, the server may or may not
- * have sent the initial wl_shm events. Therefore we need the second
- * wl_display_roundtrip() call here.
- *
- * The server processes the wl_registry.bind for wl_shm first, and
- * the second wl_display.sync next. During our second call to
- * wl_display_roundtrip() the initial wl_shm events are received and
- * processed. Finally, when the reply to the second wl_display.sync
- * arrives, it guarantees we have processed all wl_shm initial events.
- *
- * This sequence contains two examples on how wl_display_roundtrip()
- * can be used to guarantee, that all reply events to a request
- * have been received and processed. This is a general Wayland
- * technique.
- */
-
- if (!display->has_xrgb) {
- fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n");
- exit(1);
- }
-
- display->wl_tbm = wayland_tbm_client_init(display->display);
- if (!display->wl_tbm) {
- fprintf(stderr, "failed wayland_tbm_client_init()\n");
- exit(1);
- }
-
- display->notified = -1;
-
- return display;
-}
-
-static void
-destroy_display(struct display *display)
-{
- if (display->seat)
- wl_seat_destroy(display->seat);
-
- if (display->devicemgr)
- tizen_input_device_manager_destroy(display->devicemgr);
-
- if (display->shm)
- wl_shm_destroy(display->shm);
-
- if (display->wm_base)
- xdg_wm_base_destroy(display->wm_base);
-
- if (display->compositor)
- wl_compositor_destroy(display->compositor);
-
- wayland_tbm_client_deinit(display->wl_tbm);
- wl_registry_destroy(display->registry);
- wl_display_flush(display->display);
- wl_display_disconnect(display->display);
- free(display);
-}
-
-static void
-signal_int(int signum)
-{
- running = 0;
-}
-
-int
-main(int argc, char **argv)
-{
- struct sigaction sigint;
- struct display *display;
- struct window *window;
- int ret = 0;
-
- display = create_display();
- window = create_window(display, 250, 250);
- if (!window)
- return 1;
-
- sigint.sa_handler = signal_int;
- sigemptyset(&sigint.sa_mask);
- sigint.sa_flags = SA_RESETHAND;
- sigaction(SIGINT, &sigint, NULL);
-
- /* Initialise damage to full surface, so the padding gets painted */
- wl_surface_damage(window->surface, 0, 0,
- window->width, window->height);
-
- if (!window->wait_for_configure)
- redraw(window, NULL, 0);
-
- while (running && ret != -1)
- ret = wl_display_dispatch(display->display);
-
- fprintf(stderr, "simple-shm exiting\n");
-
- destroy_window(window);
- destroy_display(display);
-
- return 0;
-}
]
executable('wl-backend',
- 'wl-backend.c',
- dependencies: common_deps,
- install_dir: libds_bindir,
- install : true)
+ 'wl-backend.c',
+ dependencies: common_deps,
+ install_dir: libds_bindir,
+ install : true
+)
executable('tinyds',
[
],
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
- )
+ 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
+executable('libinput-backend',
+ 'libinput-backend.c',
+ dependencies: common_deps,
+ install_dir: libds_bindir,
+ install : true
+)
+++ /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/output.h>
-#include <libds/swapchain.h>
-#include <libds/compositor.h>
-#include <libds-tizen/allocator/tbm.h>
-#include <libds-tizen/backend/tdm.h>
-
-#define WIDTH 1280
-#define HEIGHT 720
-
-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 wl_event_source *stdin_source;
-
- struct wl_listener new_output;
- struct wl_listener output_destroy;
- struct wl_listener output_frame;
-
- 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);
-static int stdin_dispatch(int fd, uint32_t mask, void *data);
-
-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);
-
- ds_backend_start(server->backend);
-
- draw_output(server);
-
- struct wl_event_loop *loop = wl_display_get_event_loop(display);
- server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO,
- WL_EVENT_READABLE, stdin_dispatch, server);
-
- wl_display_run(display);
-
- fini_server(server);
- wl_display_destroy(display);
- return 0;
-}
-
-static void
-backend_handle_new_output(struct wl_listener *listener, void *data)
-{
- struct server *server;
- struct ds_output *output;
-
- server = wl_container_of(listener, server, new_output);
- output = data;
- ds_inf("New output(%p)", output);
-
-
- if (server->output)
- return;
-
- server->output = output;
-
- server->output_destroy.notify = output_handle_destroy;
- ds_output_add_destroy_listener(server->output,
- &server->output_destroy);
-
- server->output_frame.notify = output_handle_frame;
- ds_output_add_frame_listener(server->output,
- &server->output_frame);
-}
-
-static void
-init_server(struct server *server, struct wl_display *display)
-{
- server->display = display;
- server->front_buffer = NULL;
-
- server->backend = ds_tdm_backend_create(display);
- assert(server->backend);
-
- server->new_output.notify = backend_handle_new_output;
- ds_backend_add_new_output_listener(server->backend,
- &server->new_output);
-
- server->allocator = ds_tbm_allocator_create();
- assert(server->allocator);
-
- server->swapchain = ds_swapchain_create(server->allocator,
- server->width, server->height, WL_SHM_FORMAT_XRGB8888);
- assert(server->swapchain);
-}
-
-static void
-fini_server(struct server *server)
-{
- wl_list_remove(&server->new_output.link);
- wl_list_remove(&server->output_destroy.link);
- wl_list_remove(&server->output_frame.link);
- if (server->front_buffer)
- ds_buffer_unlock(server->front_buffer);
- ds_swapchain_destroy(server->swapchain);
- ds_allocator_destroy(server->allocator);
-}
-
-static void
-output_handle_destroy(struct wl_listener *listener,
- void *data __attribute__((unused)))
-{
- struct server *server =
- wl_container_of(listener, server, output_destroy);
- wl_display_terminate(server->display);
-}
-
-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_frame(struct wl_listener *listener,
- void *data __attribute__((unused)))
-{
- struct server *server =
- wl_container_of(listener, server, 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;
-}
-
-static int
-stdin_dispatch(int fd, uint32_t mask, void *data)
-{
- struct server *server = data;
-
- wl_display_terminate(server->display);
-
- return 1;
-}
+++ /dev/null
-#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/output.h>
-#include <libds/compositor.h>
-#include <libds/xdg_shell.h>
-#include <libds-tizen/allocator/tbm.h>
-#include <libds-tizen/backend/tdm.h>
-#include <libds/backend/libinput.h>
-#include <libds-tizen/tbm_server.h>
-
-#include <libds/input_device.h>
-#include <libds/keyboard.h>
-#include <libds/touch.h>
-#include <libds/pointer.h>
-#include <libds/seat.h>
-#include <libds-tizen/input-devicemgr.h>
-#include <xkbcommon/xkbcommon.h>
-#include <libds/interfaces/keyboard.h>
-
-#define USE_TDM_BUFFER_QUEUE
-
-#ifdef USE_TDM_BUFFER_QUEUE
-#include "pixman-tbm-helper.h"
-#include "tinyds-tdm-renderer.h"
-#else
-#include <libds/swapchain.h>
-#endif
-
-#include "pixman-helper.h"
-
-#define TINYDS_UNUSED __attribute__((unused))
-struct tinyds_keyboard;
-
-struct tinyds_output
-{
- struct tinyds_server *server;
- struct ds_output *ds_output;
- struct ds_allocator *allocator;
-#ifdef USE_TDM_BUFFER_QUEUE
- struct tinyds_renderer renderer;
- struct ds_tdm_buffer_queue *buffer_queue;
- struct wl_listener buffer_queue_acquirable;
-#else
- struct ds_swapchain *swapchain;
-#endif
- struct ds_buffer *front_buffer;
-
- struct wl_listener output_destroy;
- struct wl_listener output_frame;
-
- int width, height;
-
- bool drawable;
- bool damaged;
-};
-
-struct tinyds_server
-{
- struct ds_tbm_server *tbm_server;
-
- struct wl_display *display;
-
- struct ds_backend *backend;
- struct ds_backend *input_backend;
- struct ds_compositor *compositor;
- struct ds_xdg_shell *xdg_shell;
- struct ds_seat *seat;
- uint32_t seat_caps;
- double output_x, output_y;
- struct ds_tizen_input_devicemgr *devicemgr;
-
- struct tinyds_output *output;
- struct wl_event_source *stdin_source;
-
- struct wl_list views;
-
- struct wl_listener new_output;
- struct wl_listener new_input;
- struct wl_listener new_xdg_surface;
-
- struct tinyds_keyboard *keyboard;
-};
-
-struct tinyds_view
-{
- struct tinyds_server *server;
-
- struct tinyds_texture *texture;
- 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;
-};
-
-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; //relative
- 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_server tinyds;
-
-static bool init_server(struct tinyds_server *server, struct wl_display *display);
-static int server_dispatch_stdin(int fd, uint32_t mask, void *data);
-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_server_with_damage(struct tinyds_server *server);
-static void draw_output(struct tinyds_output *output);
-static void output_swap_buffer(struct tinyds_output *output,
- struct ds_buffer *buffer);
-static void view_send_frame_done(struct tinyds_view *view);
-#ifdef USE_TDM_BUFFER_QUEUE
-static void output_buffer_queue_init(struct tinyds_output *output);
-static void output_renderer_init(struct tinyds_output *output);
-static void output_draw_with_renderer(struct tinyds_output *output);
-#else
-static void output_swapchain_init(struct tinyds_output *output,
- int width, int height, uint32_t format);
-static void output_draw_with_swapchain(struct tinyds_output *output);
-static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image);
-#endif
-static void server_add_keyboard(struct tinyds_server *server,
- struct ds_input_device *dev);
-static void server_add_pointer(struct tinyds_server *server,
- struct ds_input_device *dev);
-static void server_add_touch(struct tinyds_server *server,
- struct ds_input_device *dev);
-
-int
-main(void)
-{
- struct tinyds_server *server = &tinyds;
- struct wl_display *display;
- struct wl_event_loop *loop;
- const char *socket;
- bool res;
-
- ds_log_init(DS_INF, NULL);
-
- display = wl_display_create();
- assert(display);
-
- res = init_server(server, display);
- assert(res);
-
- socket = wl_display_add_socket_auto(display);
- assert(socket);
-
- ds_backend_start(server->backend);
- ds_backend_start(server->input_backend);
-
- setenv("WAYLAND_DISPLAY", socket, true);
-
- ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
-
- loop = wl_display_get_event_loop(display);
- server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO,
- WL_EVENT_READABLE, server_dispatch_stdin, server);
-
- wl_display_run(display);
-
- wl_display_destroy_clients(display);
- wl_display_destroy(display);
-
- return 0;
-}
-
-static void
-view_handle_xdg_surface_map(struct wl_listener *listener,
- void *data TINYDS_UNUSED)
-{
- struct tinyds_view *view;
- struct ds_keyboard *keyboard;
- view = wl_container_of(listener, view, xdg_surface_map);
- view->mapped = true;
-
- if (!view->server->keyboard) return;
- keyboard = ds_input_device_get_keyboard(view->server->keyboard->dev);
- if (keyboard != NULL) {
- ds_seat_keyboard_notify_enter(view->server->seat,
- ds_xdg_surface_get_surface(view->xdg_surface),
- keyboard->keycodes, keyboard->num_keycodes,
- &keyboard->modifiers);
- }
-}
-
-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;
- struct tinyds_server *server;
-
- view = wl_container_of(listener, view, xdg_surface_destroy);
- server = view->server;
-
- 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);
-
- draw_server_with_damage(server);
-}
-
-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);
- draw_server_with_damage(view->server);
-}
-
-static void
-server_new_xdg_surface(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
- struct tinyds_view *view;
- struct ds_xdg_surface *xdg_surface;
-
- server = wl_container_of(listener, server, new_xdg_surface);
- xdg_surface = data;
-
- ds_inf("New xdg_surface(%p)", (void *)xdg_surface);
-
- view = calloc(1, sizeof *view);
- assert(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);
-
- view->x = rand() % 1000;
- view->y = rand() % 500;
-}
-
-static void
-backend_handle_new_output(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
- struct tinyds_output *output;
- struct ds_output *ds_output;
- const struct ds_output_mode *mode;
-
- server = wl_container_of(listener, server, new_output);
- ds_output = data;
-
- ds_inf("New output(%p)", ds_output);
-
- if (server->output)
- return;
-
- mode = ds_output_get_preferred_mode(ds_output);
- ds_output_set_mode(ds_output, mode);
-
- output = calloc(1, sizeof *output);
- if (!output)
- return;
-
- output->server = server;
- output->ds_output = ds_output;
- output->width = mode->width;
- output->height = mode->height;
- output->drawable = true;
- output->damaged = true;
-
-#ifdef USE_TDM_BUFFER_QUEUE
- output_buffer_queue_init(output);
- output_renderer_init(output);
-#else
- output_swapchain_init(output, mode->width, mode->height,
- DRM_FORMAT_XRGB8888);
-#endif
-
- output->output_destroy.notify = output_handle_destroy;
- ds_output_add_destroy_listener(ds_output, &output->output_destroy);
-
- output->output_frame.notify = output_handle_frame;
- ds_output_add_frame_listener(ds_output, &output->output_frame);
-
- server->output = output;
-
- draw_output(output);
-}
-
-static void
-backend_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);
- server->seat_caps |= WL_SEAT_CAPABILITY_KEYBOARD;
- break;
- case DS_INPUT_DEVICE_TOUCH:
- server_add_touch(server, dev);
- server->seat_caps |= WL_SEAT_CAPABILITY_TOUCH;
- break;
- case DS_INPUT_DEVICE_POINTER:
- server_add_pointer(server, dev);
- server->seat_caps |= WL_SEAT_CAPABILITY_POINTER;
- break;
- default:
- ds_err("Unknown type(%d) of ds_input_device", dev_type);
- break;
- }
-
- ds_seat_set_capabilities(server->seat, server->seat_caps);
-}
-
-static void
-devicemgr_add_keymap_data(struct wl_list *list, const char *name, int keycode)
-{
- struct ds_tizen_input_devicemgr_keymap_data *data;
-
- data = calloc(1, sizeof *data);
- if (!data) {
- ds_err("Failed to alloc memory\n");
- return;
- }
-
- data->name = strdup(name);
- data->keycode = keycode;
-
- wl_list_insert(list, &data->link);
-}
-
-static void
-devicemgr_remove_keymap_data(struct wl_list *list, int keycode)
-{
- struct ds_tizen_input_devicemgr_keymap_data *data, *tmp;
-
- wl_list_for_each_safe(data, tmp, list, link) {
- if (data->keycode == keycode) {
- wl_list_remove(&data->link);
- free(data);
- }
- }
-}
-
-static void
-devicemgr_set_keymap(struct ds_tizen_input_devicemgr *devicemgr)
-{
- struct wl_list keymap_list;
- bool res;
-
- wl_list_init(&keymap_list);
-
- devicemgr_add_keymap_data(&keymap_list, "XF86VolumeRaise", 455);
- devicemgr_add_keymap_data(&keymap_list, "XF86VolumeLower", 456);
- devicemgr_add_keymap_data(&keymap_list, "XF86LightOn", 457);
- devicemgr_add_keymap_data(&keymap_list, "XF86LightOff", 458);
-
- res = ds_tizen_input_devicemgr_set_keymap_list(devicemgr, &keymap_list);
- if (!res)
- ds_inf("Failed to set keymap");
-
- devicemgr_remove_keymap_data(&keymap_list, 455);
- devicemgr_remove_keymap_data(&keymap_list, 456);
- devicemgr_remove_keymap_data(&keymap_list, 457);
- devicemgr_remove_keymap_data(&keymap_list, 458);
-}
-
-static bool
-init_server(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 = ds_tdm_backend_create(display);
- if (!server->backend)
- return false;
-
- server->input_backend = ds_libinput_backend_create(display);
- if (!server->input_backend) {
- ds_backend_destroy(server->backend);
- return false;
- }
-
- server->new_output.notify = backend_handle_new_output;
- ds_backend_add_new_output_listener(server->backend,
- &server->new_output);
-
- server->new_input.notify = backend_handle_new_input;
- ds_backend_add_new_input_listener(server->input_backend, &server->new_input);
-
- server->compositor = ds_compositor_create(display);
- if (!server->compositor)
- goto err;
-
- server->tbm_server = ds_tbm_server_create(display);
- if (!server->tbm_server)
- 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;
- server->seat_caps = 0;
-
- server->devicemgr = ds_tizen_input_devicemgr_create(
- server->input_backend, server->seat);
- if (!server->devicemgr) {
- goto err;
- }
-
- devicemgr_set_keymap(server->devicemgr);
- return true;
-
-err:
- ds_backend_destroy(server->backend);
- ds_backend_destroy(server->input_backend);
-
- return false;
-}
-
-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);
-
- if (output->front_buffer)
- ds_buffer_unlock(output->front_buffer);
-
-#ifdef USE_TDM_BUFFER_QUEUE
- fini_renderer(&output->renderer);
-#else
- if (output->swapchain)
- ds_swapchain_destroy(output->swapchain);
-
- if (output->allocator)
- ds_allocator_destroy(output->allocator);
-#endif
-
- wl_display_terminate(output->server->display);
-
- output->server->output = NULL;
-
- free(output);
-}
-
-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;
- draw_output(output);
-}
-
-static void
-draw_server_with_damage(struct tinyds_server *server)
-{
- server->output->damaged = true;
- draw_output(server->output);
-}
-
-#ifdef USE_TDM_BUFFER_QUEUE
-static void
-output_handle_buffer_queue_acquirable(struct wl_listener *listener,
- void *data TINYDS_UNUSED)
-{
- struct tinyds_output *output;
- struct ds_buffer *buffer;
-
- output = wl_container_of(listener, output, buffer_queue_acquirable);
-
- buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue);
- assert(buffer);
-
- output_swap_buffer(output, buffer);
-}
-
-static void
-output_buffer_queue_init(struct tinyds_output *output)
-{
- struct ds_tdm_output *tdm_output;
-
- tdm_output = ds_tdm_output_from_output(output->ds_output);
- assert(tdm_output);
-
- output->buffer_queue = ds_tdm_output_get_buffer_queue(tdm_output);
- assert(output->buffer_queue);
-
- output->buffer_queue_acquirable.notify =
- output_handle_buffer_queue_acquirable;
- ds_tdm_buffer_queue_add_acquirable_listener(output->buffer_queue,
- &output->buffer_queue_acquirable);
-}
-
-static void
-output_renderer_init(struct tinyds_output *output)
-{
- init_renderer(&output->renderer);
-
- renderer_set_surface_queue(&output->renderer,
- ds_tdm_buffer_queue_get_native_queue(output->buffer_queue));
-
- renderer_set_bg_color(&output->renderer, 80, 80, 80);
-}
-
-static void
-output_draw_with_renderer(struct tinyds_output *output)
-{
- struct tinyds_view *view;
-
- ds_dbg(">> BEGIN UPDATE TEXTURES");
-
- wl_list_for_each(view, &output->server->views, link) {
- struct ds_buffer *ds_buffer;
- struct ds_tbm_client_buffer *tbm_buffer;
- tbm_surface_h surface;
-
- if (!view->mapped)
- continue;
-
- ds_buffer = ds_surface_get_buffer(
- ds_xdg_surface_get_surface(view->xdg_surface));
- assert(ds_buffer);
-
- tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer);
- assert(tbm_buffer);
-
- surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer);
-
- renderer_add_texture(&output->renderer, surface, view->x, view->y);
-
- view_send_frame_done(view);
- }
-
- ds_dbg("<< END UPDATE TEXTURES");
-
- renderer_draw(&output->renderer);
-
-}
-#else
-static void
-output_swapchain_init(struct tinyds_output *output,
- int width, int height, uint32_t format);
-
-{
- output->allocator = ds_tbm_allocator_create();
- assert(output->allocator);
-
- output->swapchain = ds_swapchain_create(output->allocator,
- width, height, format);
- assert(output->swapchain);
-}
-
-static void
-output_draw_with_swapchain(struct tinyds_output *output)
-{
- struct tinyds_view *view;
- struct ds_buffer *output_buffer;
- pixman_image_t *output_image;
-
- 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) {
- ds_buffer_unlock(output_buffer);
- return;
- }
-
- pixman_image_fill_color(output_image, 80, 80, 80);
-
- wl_list_for_each(view, &output->server->views, link) {
- if (!view->mapped)
- continue;
- draw_view(view, output_image);
- }
- pixman_image_unref(output_image);
-
- output_swap_buffer(output, output_buffer);
-}
-
-static void
-draw_view(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,
- view->x, view->y,
- pixman_image_get_width(src_image),
- pixman_image_get_height(src_image));
- pixman_image_unref(src_image);
-
- view_send_frame_done(view);
-}
-#endif
-
-static void
-draw_output(struct tinyds_output *output)
-{
-
- if (!output->drawable || !output->damaged)
- return;
-
-#ifdef USE_TDM_BUFFER_QUEUE
- output_draw_with_renderer(output);
-#else
- output_draw_with_swapchain(output);
-#endif
-
- output->drawable = false;
- output->damaged = false;
-}
-
-static void
-output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer)
-{
- 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;
-}
-
-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 int
-server_dispatch_stdin(int fd, uint32_t mask, void *data)
-{
- struct tinyds_server *server = data;
-
- wl_display_terminate(server->display);
-
- return 1;
-}
-
-
-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);
-
- kbd->server->keyboard = NULL;
-
- 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;
- int nsyms;
- bool handled = false;
-
- kbd = wl_container_of(listener, kbd, key);
-
- ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), "
- "update_state(%d)", kbd->dev,
- event->keycode, event->state, event->time_msec,
- event->update_state);
-
- ds_keyboard = ds_input_device_get_keyboard(kbd->dev);
-
- if (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++) {
- handled = server_handle_keybinding(kbd->server, syms[i]);
- }
- }
- }
-
- if (!handled) {
- ds_seat_keyboard_notify_key(kbd->server->seat, event->time_msec,
- event->keycode, event->state);
- }
-}
-
-static void
-server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev)
-{
- struct tinyds_keyboard *kbd;
- struct xkb_context *context;
- struct xkb_keymap *keymap;
-
- kbd = calloc(1, sizeof *kbd);
- assert(kbd);
-
- kbd->dev = dev;
- kbd->server = server;
-
- context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
- keymap = xkb_keymap_new_from_names(context, NULL,
- XKB_KEYMAP_COMPILE_NO_FLAGS);
-
- if (!keymap) {
- ds_err("Failed to compile keymap");
- xkb_context_unref(context);
- }
-
- ds_keyboard_set_keymap(ds_input_device_get_keyboard(dev), keymap);
-
- xkb_keymap_unref(keymap);
- xkb_context_unref(context);
-
- 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);
-
- server->keyboard = kbd;
-
- ds_inf("Keyboard(%p) added", kbd);
-}
-
-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 <= x + w && ly >= y && ly <= y + h) {
- *sx = lx - x;
- *sy = ly - y;
-
- return view;
- }
- }
-
- return NULL;
-}
-
-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)
-{
- struct ds_event_touch_down *event = data;
- struct tinyds_touch *touch;
- struct tinyds_view *view;
- struct tinyds_server *server;
- double sx = 0.f, sy = 0.f;
-
- touch = wl_container_of(listener, touch, down);
-
- server = touch->server;
- server->output_x = event->x * server->output->width;
- server->output_y = event->y * server->output->height;
-
- ds_inf("Touch(%p) event down: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
- touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
-
- view = server_view_at(server, server->output_x, server->output_y, &sx, &sy);
-
- if (view) {
- ds_seat_touch_notify_down(touch->server->seat, ds_xdg_surface_get_surface(view->xdg_surface),
- event->time_msec, event->id, sx, sy);
- }
-}
-
-static void
-touch_handle_up(struct wl_listener *listener, void *data)
-{
- struct ds_event_touch_up *event = data;
- struct tinyds_touch *touch;
-
- touch = wl_container_of(listener, touch, up);
-
- ds_inf("Touch(%p) event up: id(%d) time_msec(%d)",
- touch->dev, event->id, event->time_msec);
-
- ds_seat_touch_notify_up(touch->server->seat, event->time_msec, event->id);
-}
-
-static void
-touch_handle_motion(struct wl_listener *listener, void *data)
-{
- struct ds_event_touch_motion *event = data;
- struct tinyds_touch *touch;
- struct tinyds_view *view;
- struct tinyds_server *server;
- double sx = 0.f, sy = 0.f;
-
- touch = wl_container_of(listener, touch, motion);
-
- server = touch->server;
- server->output_x = event->x * server->output->width;
- server->output_y = event->y * server->output->height;
-
- ds_inf("Touch(%p) event motion: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
- touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
-
- view = server_view_at(server, server->output_x, server->output_y, &sx, &sy);
-
- if (view) {
- ds_seat_touch_notify_motion(server->seat, event->time_msec,
- event->id, sx, sy);
- }
-}
-
-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->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;
- struct ds_event_pointer_motion *event = data;
- struct tinyds_view *view;
- struct tinyds_server *server;
- int ow = 0, oh = 0;
- double sx, sy;
-
- pointer = wl_container_of(listener, pointer, motion);
-
- server = pointer->server;
- if (server->output) {
- ow = server->output->width;
- oh = server->output->height;
- }
-
- if (server->output_x + event->delta_x >= ow)
- server->output_x = ow;
- else if(server->output_x + event->delta_x <= 0.f)
- server->output_x = 0.f;
- else
- server->output_x = server->output_x + event->delta_x ;
- if (server->output_y + event->delta_y >= oh)
- server->output_y = oh;
- else if(server->output_y + event->delta_y <= 0.f)
- server->output_y = 0.f;
- else
- server->output_y = server->output_y + event->delta_y ;
-
- ds_inf("Pointer(%p) motion: (delta_x %.1f delta_y %.1f) output_x %.1f output_y %.1f",
- pointer, event->delta_x, event->delta_y, server->output_x, server->output_y);
-
- view = server_view_at(pointer->server, server->output_x, server->output_y, &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);
-
- ds_seat_pointer_notify_button(pointer->server->seat, event->time_msec, event->button, event->state);
-}
-
-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;
- server->output_x = 200;
- server->output_y = 200;
-
- 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->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);
-}
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#include <libds/log.h>
-
-#include "pixman-helper.h"
-#include "pixman-tbm-helper.h"
-#include "tinyds-tdm-renderer.h"
-
-static void renderer_setup_thread(struct tinyds_renderer *renderer);
-static void *renderer_thread_func(void *data);
-static void texture_destroy(struct tinyds_texture *texture);
-
-bool
-init_renderer(struct tinyds_renderer *renderer)
-{
- renderer->damaged = false;
-
- wl_list_init(&renderer->textures);
-
- renderer_setup_thread(renderer);
-
- return true;
-}
-
-void
-fini_renderer(struct tinyds_renderer *renderer)
-{
- pthread_mutex_lock(&renderer->mutex);
-
- renderer->destroying = true;
- pthread_cond_signal(&renderer->cond);
-
- pthread_mutex_unlock(&renderer->mutex);
-
- pthread_join(renderer->worker_thread, NULL);
-
- pthread_mutex_destroy(&renderer->mutex);
- pthread_cond_destroy(&renderer->cond);
-}
-
-void
-renderer_set_surface_queue(struct tinyds_renderer *renderer,
- void *surface_queue)
-{
- pthread_mutex_lock(&renderer->mutex);
-
- renderer->surface_queue = (tbm_surface_queue_h)surface_queue;
-
- pthread_mutex_unlock(&renderer->mutex);
-}
-
-void
-renderer_set_bg_color(struct tinyds_renderer *renderer,
- uint8_t r, uint8_t g, uint8_t b)
-{
- pixman_color_t color;
-
- pthread_mutex_lock(&renderer->mutex);
-
- color_rgb888(&color, r, g, b);
-
- renderer->bg_image = pixman_image_create_solid_fill(&color);
- assert(renderer->bg_image);
-
- renderer->damaged = true;
-
- pthread_mutex_unlock(&renderer->mutex);
-}
-
-void
-renderer_add_texture(struct tinyds_renderer *renderer,
- tbm_surface_h tbm_surface, int x, int y)
-{
- struct tinyds_texture *texture;
-
- pthread_mutex_lock(&renderer->mutex);
-
- texture = calloc(1, sizeof *texture);
-
- texture->x = x;
- texture->y = y;
- texture->renderer = renderer;
- texture->surface = tbm_surface;
- texture->image = pixman_image_from_tbm_surface(tbm_surface,
- DS_BUFFER_DATA_PTR_ACCESS_READ);
-
- wl_list_insert(renderer->textures.prev, &texture->link);
-
- ds_dbg("Add texture(%p)", texture);
-
- pthread_mutex_unlock(&renderer->mutex);
-}
-
-void
-renderer_draw(struct tinyds_renderer *renderer)
-{
- pthread_mutex_lock(&renderer->mutex);
-
- renderer->damaged = true;
- pthread_cond_signal(&renderer->cond);
-
- pthread_mutex_unlock(&renderer->mutex);
-}
-
-static void
-renderer_setup_thread(struct tinyds_renderer *renderer)
-{
- pthread_mutex_init(&renderer->mutex, NULL);
- pthread_cond_init(&renderer->cond, NULL);
- pthread_create(&renderer->worker_thread, NULL,
- renderer_thread_func, renderer);
-}
-
-static void *
-renderer_thread_func(void *data)
-{
- struct tinyds_renderer *renderer = data;
- struct tinyds_texture *texture, *texture_tmp;
- pixman_image_t *dst_image;
- tbm_surface_h surface;
- tbm_surface_queue_error_e err;
-
- pthread_mutex_lock(&renderer->mutex);
-
- while (!renderer->destroying) {
- if (!renderer->damaged)
- pthread_cond_wait(&renderer->cond, &renderer->mutex);
-
- if (!renderer->damaged)
- continue;
-
- if (!tbm_surface_queue_can_dequeue(renderer->surface_queue, 0))
- continue;
-
- ds_dbg(">> BEGIN DRAW");
-
- err = tbm_surface_queue_dequeue(renderer->surface_queue, &surface);
- assert(err == TBM_SURFACE_QUEUE_ERROR_NONE);
-
- dst_image = pixman_image_from_tbm_surface(surface,
- DS_BUFFER_DATA_PTR_ACCESS_WRITE);
-
- if (renderer->bg_image) {
- pixman_image_composite32(PIXMAN_OP_SRC,
- renderer->bg_image,
- NULL,
- dst_image,
- 0, 0, 0, 0, 0, 0,
- pixman_image_get_width(dst_image),
- pixman_image_get_height(dst_image));
- }
-
- wl_list_for_each_safe(texture, texture_tmp, &renderer->textures, link) {
- ds_dbg("Draw texture(%p)", texture);
- pixman_image_composite32(PIXMAN_OP_OVER,
- texture->image,
- NULL,
- dst_image,
- 0, 0, 0, 0,
- texture->x, texture->y,
- pixman_image_get_width(texture->image),
- pixman_image_get_height(texture->image));
- texture_destroy(texture);
- }
- pixman_image_unref(dst_image);
-
- err = tbm_surface_queue_enqueue(renderer->surface_queue, surface);
- assert(err == TBM_SURFACE_QUEUE_ERROR_NONE);
-
- renderer->damaged = false;
-
- ds_dbg("<< END DRAW");
- }
-
- pthread_mutex_unlock(&renderer->mutex);
-
- return NULL;
-}
-
-static void
-texture_destroy(struct tinyds_texture *texture)
-{
- pixman_image_unref(texture->image);
- wl_list_remove(&texture->link);
- free(texture);
-}
+++ /dev/null
-#ifndef EXAMPLES_TINYDS_TDM_RENDERER_H
-#define EXAMPLES_TINYDS_TDM_RENDERER_H
-
-#include <pthread.h>
-#include <pixman.h>
-#include <tbm_surface_queue.h>
-#include <tbm_surface.h>
-#include <wayland-server.h>
-
-struct tinyds_renderer
-{
- tbm_surface_queue_h surface_queue;
-
- struct wl_list textures;
-
- pthread_t worker_thread;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-
- pixman_image_t *bg_image;
-
- bool damaged;
- bool destroying;
-};
-
-struct tinyds_texture
-{
- struct tinyds_renderer *renderer;
- pixman_image_t *image;
- tbm_surface_h surface;
-
- struct wl_list link;
- struct wl_listener buffer_destroy;
-
- int x, y;
-};
-
-bool init_renderer(struct tinyds_renderer *renderer);
-void fini_renderer(struct tinyds_renderer *renderer);
-void renderer_set_surface_queue(struct tinyds_renderer *renderer,
- void *surface_queue);
-void renderer_set_bg_color(struct tinyds_renderer *renderer,
- uint8_t r, uint8_t g, uint8_t b);
-void renderer_add_texture(struct tinyds_renderer *renderer,
- tbm_surface_h tbm_surface, int x, int y);
-void renderer_draw(struct tinyds_renderer *renderer);
-
-#endif
+++ /dev/null
-#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/output.h>
-#include <libds/compositor.h>
-#include <libds/xdg_shell.h>
-#include <libds-tizen/allocator/tbm.h>
-#include <libds-tizen/backend/tdm.h>
-#include <libds-tizen/tbm_server.h>
-
-#define USE_TDM_BUFFER_QUEUE
-
-#ifdef USE_TDM_BUFFER_QUEUE
-#include "pixman-tbm-helper.h"
-#include "tinyds-tdm-renderer.h"
-#else
-#include <libds/swapchain.h>
-#endif
-
-#include "pixman-helper.h"
-
-#define TINYDS_UNUSED __attribute__((unused))
-
-struct tinyds_output
-{
- struct tinyds_server *server;
- struct ds_output *ds_output;
- struct ds_allocator *allocator;
-#ifdef USE_TDM_BUFFER_QUEUE
- struct tinyds_renderer renderer;
- struct ds_tdm_buffer_queue *buffer_queue;
- struct wl_listener buffer_queue_acquirable;
-#else
- struct ds_swapchain *swapchain;
-#endif
- struct ds_buffer *front_buffer;
-
- struct wl_listener output_destroy;
- struct wl_listener output_frame;
-
- int width, height;
-
- bool drawable;
- bool damaged;
-};
-
-struct tinyds_server
-{
- struct ds_tbm_server *tbm_server;
-
- struct wl_display *display;
-
- struct ds_backend *backend;
- struct ds_compositor *compositor;
- struct ds_xdg_shell *xdg_shell;
-
- struct tinyds_output *output;
- struct wl_event_source *stdin_source;
-
- struct wl_list views;
-
- struct wl_listener new_output;
- struct wl_listener new_xdg_surface;
-};
-
-struct tinyds_view
-{
- struct tinyds_server *server;
-
- struct tinyds_texture *texture;
- 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;
-};
-
-struct tinyds_server tinyds;
-
-static bool init_server(struct tinyds_server *server, struct wl_display *display);
-static int server_dispatch_stdin(int fd, uint32_t mask, void *data);
-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_server_with_damage(struct tinyds_server *server);
-static void draw_output(struct tinyds_output *output);
-static void output_swap_buffer(struct tinyds_output *output,
- struct ds_buffer *buffer);
-static void view_send_frame_done(struct tinyds_view *view);
-#ifdef USE_TDM_BUFFER_QUEUE
-static void output_buffer_queue_init(struct tinyds_output *output);
-static void output_renderer_init(struct tinyds_output *output);
-static void output_draw_with_renderer(struct tinyds_output *output);
-#else
-static void output_swapchain_init(struct tinyds_output *output,
- int width, int height, uint32_t format);
-static void output_draw_with_swapchain(struct tinyds_output *output);
-static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image);
-#endif
-
-int
-main(void)
-{
- struct tinyds_server *server = &tinyds;
- struct wl_display *display;
- struct wl_event_loop *loop;
- const char *socket;
- bool res;
-
- ds_log_init(DS_INF, NULL);
-
- display = wl_display_create();
- assert(display);
-
- res = init_server(server, display);
- assert(res);
-
- socket = wl_display_add_socket_auto(display);
- assert(socket);
-
- ds_backend_start(server->backend);
-
- setenv("WAYLAND_DISPLAY", socket, true);
-
- ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
-
- loop = wl_display_get_event_loop(display);
- server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO,
- WL_EVENT_READABLE, server_dispatch_stdin, server);
-
- wl_display_run(display);
-
- wl_display_destroy_clients(display);
- wl_display_destroy(display);
-
- return 0;
-}
-
-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;
- struct tinyds_server *server;
-
- view = wl_container_of(listener, view, xdg_surface_destroy);
- server = view->server;
-
- 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);
-
- draw_server_with_damage(server);
-}
-
-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);
- draw_server_with_damage(view->server);
-}
-
-static void
-server_new_xdg_surface(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
- struct tinyds_view *view;
- struct ds_xdg_surface *xdg_surface;
-
- server = wl_container_of(listener, server, new_xdg_surface);
- xdg_surface = data;
-
- ds_inf("New xdg_surface(%p)", (void *)xdg_surface);
-
- view = calloc(1, sizeof *view);
- assert(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);
-
- view->x = rand() % 1000;
- view->y = rand() % 500;
-}
-
-static void
-backend_handle_new_output(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
- struct tinyds_output *output;
- struct ds_output *ds_output;
- const struct ds_output_mode *mode;
-
- server = wl_container_of(listener, server, new_output);
- ds_output = data;
-
- ds_inf("New output(%p)", ds_output);
-
- if (server->output)
- return;
-
- mode = ds_output_get_preferred_mode(ds_output);
- ds_output_set_mode(ds_output, mode);
-
- output = calloc(1, sizeof *output);
- if (!output)
- return;
-
- output->server = server;
- output->ds_output = ds_output;
- output->width = mode->width;
- output->height = mode->height;
- output->drawable = true;
- output->damaged = true;
-
-#ifdef USE_TDM_BUFFER_QUEUE
- output_buffer_queue_init(output);
- output_renderer_init(output);
-#else
- output_swapchain_init(output, mode->width, mode->height,
- DRM_FORMAT_XRGB8888);
-#endif
-
- output->output_destroy.notify = output_handle_destroy;
- ds_output_add_destroy_listener(ds_output, &output->output_destroy);
-
- output->output_frame.notify = output_handle_frame;
- ds_output_add_frame_listener(ds_output, &output->output_frame);
-
- server->output = output;
-
- draw_output(output);
-}
-
-static bool
-init_server(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 = ds_tdm_backend_create(display);
- if (!server->backend)
- return false;
-
- server->new_output.notify = backend_handle_new_output;
- ds_backend_add_new_output_listener(server->backend,
- &server->new_output);
-
- server->compositor = ds_compositor_create(display);
- if (!server->compositor) {
- ds_backend_destroy(server->backend);
- return false;
- }
-
- server->tbm_server = ds_tbm_server_create(display);
- if (!server->tbm_server) {
- ds_backend_destroy(server->backend);
- return false;
- }
-
- server->xdg_shell = ds_xdg_shell_create(display);
- if (!server->xdg_shell) {
- ds_backend_destroy(server->backend);
- return false;
- }
-
- server->new_xdg_surface.notify = server_new_xdg_surface;
- ds_xdg_shell_add_new_surface_listener(server->xdg_shell,
- &server->new_xdg_surface);
-
- return true;
-}
-
-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);
-
- if (output->front_buffer)
- ds_buffer_unlock(output->front_buffer);
-
-#ifdef USE_TDM_BUFFER_QUEUE
- fini_renderer(&output->renderer);
-#else
- if (output->swapchain)
- ds_swapchain_destroy(output->swapchain);
-
- if (output->allocator)
- ds_allocator_destroy(output->allocator);
-#endif
-
- wl_display_terminate(output->server->display);
-
- output->server->output = NULL;
-
- free(output);
-}
-
-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;
- draw_output(output);
-}
-
-static void
-draw_server_with_damage(struct tinyds_server *server)
-{
- server->output->damaged = true;
- draw_output(server->output);
-}
-
-#ifdef USE_TDM_BUFFER_QUEUE
-static void
-output_handle_buffer_queue_acquirable(struct wl_listener *listener,
- void *data TINYDS_UNUSED)
-{
- struct tinyds_output *output;
- struct ds_buffer *buffer;
-
- output = wl_container_of(listener, output, buffer_queue_acquirable);
-
- buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue);
- assert(buffer);
-
- output_swap_buffer(output, buffer);
-}
-
-static void
-output_buffer_queue_init(struct tinyds_output *output)
-{
- struct ds_tdm_output *tdm_output;
-
- tdm_output = ds_tdm_output_from_output(output->ds_output);
- assert(tdm_output);
-
- output->buffer_queue = ds_tdm_output_get_buffer_queue(tdm_output);
- assert(output->buffer_queue);
-
- output->buffer_queue_acquirable.notify =
- output_handle_buffer_queue_acquirable;
- ds_tdm_buffer_queue_add_acquirable_listener(output->buffer_queue,
- &output->buffer_queue_acquirable);
-}
-
-static void
-output_renderer_init(struct tinyds_output *output)
-{
- init_renderer(&output->renderer);
-
- renderer_set_surface_queue(&output->renderer,
- ds_tdm_buffer_queue_get_native_queue(output->buffer_queue));
-
- renderer_set_bg_color(&output->renderer, 80, 80, 80);
-}
-
-static void
-output_draw_with_renderer(struct tinyds_output *output)
-{
- struct tinyds_view *view;
-
- ds_dbg(">> BEGIN UPDATE TEXTURES");
-
- wl_list_for_each(view, &output->server->views, link) {
- struct ds_buffer *ds_buffer;
- struct ds_tbm_client_buffer *tbm_buffer;
- tbm_surface_h surface;
-
- if (!view->mapped)
- continue;
-
- ds_buffer = ds_surface_get_buffer(
- ds_xdg_surface_get_surface(view->xdg_surface));
- assert(ds_buffer);
-
- tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer);
- assert(tbm_buffer);
-
- surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer);
-
- renderer_add_texture(&output->renderer, surface, view->x, view->y);
-
- view_send_frame_done(view);
- }
-
- ds_dbg("<< END UPDATE TEXTURES");
-
- renderer_draw(&output->renderer);
-
-}
-#else
-static void
-output_swapchain_init(struct tinyds_output *output,
- int width, int height, uint32_t format);
-
-{
- output->allocator = ds_tbm_allocator_create();
- assert(output->allocator);
-
- output->swapchain = ds_swapchain_create(output->allocator,
- width, height, format);
- assert(output->swapchain);
-}
-
-static void
-output_draw_with_swapchain(struct tinyds_output *output)
-{
- struct tinyds_view *view;
- struct ds_buffer *output_buffer;
- pixman_image_t *output_image;
-
- 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) {
- ds_buffer_unlock(output_buffer);
- return;
- }
-
- pixman_image_fill_color(output_image, 80, 80, 80);
-
- wl_list_for_each(view, &output->server->views, link) {
- if (!view->mapped)
- continue;
- draw_view(view, output_image);
- }
- pixman_image_unref(output_image);
-
- output_swap_buffer(output, output_buffer);
-}
-
-static void
-draw_view(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,
- view->x, view->y,
- pixman_image_get_width(src_image),
- pixman_image_get_height(src_image));
- pixman_image_unref(src_image);
-
- view_send_frame_done(view);
-}
-#endif
-
-static void
-draw_output(struct tinyds_output *output)
-{
-
- if (!output->drawable || !output->damaged)
- return;
-
-#ifdef USE_TDM_BUFFER_QUEUE
- output_draw_with_renderer(output);
-#else
- output_draw_with_swapchain(output);
-#endif
-
- output->drawable = false;
- output->damaged = false;
-}
-
-static void
-output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer)
-{
- 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;
-}
-
-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 int
-server_dispatch_stdin(int fd, uint32_t mask, void *data)
-{
- struct tinyds_server *server = data;
-
- wl_display_terminate(server->display);
-
- return 1;
-}
+++ /dev/null
-libds_tizen_files += files('tbm.c')
-libds_tizen_deps += dependency('libtbm', required: true)
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#include <drm_fourcc.h>
-#include <wayland-server.h>
-#include <tbm_bufmgr.h>
-#include <tbm_surface.h>
-
-#include "libds/interfaces/allocator.h"
-#include "libds/interfaces/buffer.h"
-#include "libds/log.h"
-
-struct ds_tbm_allocator
-{
- struct ds_allocator base;
- tbm_bufmgr bufmgr;
-};
-
-struct ds_tbm_buffer
-{
- struct ds_buffer base;
- tbm_surface_h surface;
-};
-
-static const struct ds_allocator_interface tbm_allocator_iface;
-static struct ds_tbm_buffer *tbm_buffer_from_buffer(struct ds_buffer *buffer);
-
-WL_EXPORT struct ds_allocator *
-ds_tbm_allocator_create(void)
-{
- struct ds_tbm_allocator *alloc;
-
- alloc = calloc(1, sizeof *alloc);
- if (!alloc)
- return NULL;
-
- alloc->bufmgr = tbm_bufmgr_init(-1);
- if (!alloc->bufmgr) {
- ds_err("Could not initialize tbm_bufmgr");
- free(alloc);
- return NULL;
- }
-
- ds_allocator_init(&alloc->base, &tbm_allocator_iface,
- DS_BUFFER_CAP_DATA_PTR);
-
- ds_inf("TBM allocator(%p) created", alloc);
-
- return &alloc->base;
-}
-
-WL_EXPORT void *
-ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer)
-{
- struct ds_tbm_buffer *buffer;
-
- buffer = tbm_buffer_from_buffer(ds_buffer);
- if (!buffer)
- return NULL;
-
- return buffer->surface;
-}
-
-static struct ds_tbm_allocator *
-tbm_allocator_from_allocator(struct ds_allocator *ds_allocator)
-{
- assert(ds_allocator->iface == &tbm_allocator_iface);
- return (struct ds_tbm_allocator *)ds_allocator;
-}
-
-static const struct ds_buffer_interface tbm_buffer_iface;
-
-static struct ds_tbm_buffer *
-tbm_buffer_from_buffer(struct ds_buffer *buffer)
-{
- assert(buffer->iface == &tbm_buffer_iface);
- return (struct ds_tbm_buffer *)buffer;
-}
-
-static void
-tbm_buffer_destroy(struct ds_buffer *ds_buffer)
-{
- struct ds_tbm_buffer *buffer;
-
- buffer = tbm_buffer_from_buffer(ds_buffer);
-
- ds_dbg("Destroy tbm buffer(%p)", buffer);
-
- tbm_surface_destroy(buffer->surface);
- free(buffer);
-}
-
-static bool
-tbm_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, uint32_t flags,
- void **data, uint32_t *format, size_t *stride)
-{
- struct ds_tbm_buffer *buffer;
- tbm_surface_info_s info;
- int tbm_access_flags = 0;
- int ret;
-
- buffer = tbm_buffer_from_buffer(ds_buffer);
-
- if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ)
- tbm_access_flags |= TBM_OPTION_READ;
- else if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE)
- tbm_access_flags |= TBM_OPTION_WRITE;
-
- ret = tbm_surface_map(buffer->surface, tbm_access_flags, &info);
- if (ret != TBM_SURFACE_ERROR_NONE) {
- ds_err("Could not map tbm_surface of buffer(%p)", buffer);
- return false;
- }
-
- *data = info.planes[0].ptr;
- *format = info.format;
- *stride = info.planes[0].stride;
-
- return true;
-}
-
-static void
-tbm_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer)
-{
- struct ds_tbm_buffer *buffer;
-
- buffer = tbm_buffer_from_buffer(ds_buffer);
-
- tbm_surface_unmap(buffer->surface);
-}
-
-static const struct ds_buffer_interface tbm_buffer_iface =
-{
- .destroy = tbm_buffer_destroy,
- .begin_data_ptr_access = tbm_buffer_begin_data_ptr_access,
- .end_data_ptr_access = tbm_buffer_end_data_ptr_access,
-};
-
-static void
-tbm_allocator_destroy(struct ds_allocator *ds_allocator)
-{
- struct ds_tbm_allocator *alloc;
-
- alloc = tbm_allocator_from_allocator(ds_allocator);
-
- ds_inf("Destroy TBM allocator(%p)", alloc);
-
- tbm_bufmgr_deinit(alloc->bufmgr);
- free(alloc);
-}
-
-static struct ds_buffer *
-tbm_allocator_create_buffer(struct ds_allocator *ds_allocator,
- int width, int height, uint32_t format)
-{
- static int num_buffers = 0;
- struct ds_tbm_buffer *buffer;
-
- buffer = calloc(1, sizeof *buffer);
- if (!buffer)
- return NULL;
-
- ds_buffer_init(&buffer->base, &tbm_buffer_iface, width, height);
-
- buffer->surface = tbm_surface_create(width, height, TBM_FORMAT_XRGB8888);
-
- ds_dbg("tbm buffer(%p) created: size(%dx%d) number of buffers: %d",
- buffer, width, height, ++num_buffers);
-
- return &buffer->base;
-}
-
-static const struct ds_allocator_interface tbm_allocator_iface =
-{
- .destroy = tbm_allocator_destroy,
- .create_buffer = tbm_allocator_create_buffer,
-};
+++ /dev/null
-subdir('tdm')
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-
-#include "tdm.h"
-
-static const struct ds_backend_interface tdm_backend_iface;
-
-static void tdm_backend_handle_display_destroy(struct wl_listener *listener,
- void *data);
-static void tdm_backend_destroy(struct ds_tdm_backend *tdm);
-static int tdm_backend_handle_tdm_event(int fd, uint32_t mask, void *data);
-
-WL_EXPORT struct ds_backend *
-ds_tdm_backend_create(struct wl_display *display)
-{
- struct ds_tdm_backend *tdm;
- struct wl_event_loop *loop;
- tdm_error err;
-
- ds_inf("Initializing TDM backend");
-
- tdm = calloc(1, sizeof *tdm);
- if (!tdm)
- return NULL;
-
- ds_backend_init(&tdm->base, display, &tdm_backend_iface);
-
- tdm->wl_display = display;
- tdm->clock = CLOCK_MONOTONIC; // FIXME
-
- wl_list_init(&tdm->outputs);
- wl_list_init(&tdm->buffers);
-
- tdm->tdm_display = tdm_display_init(&err);
- if (err != TDM_ERROR_NONE) {
- ds_err("Could not initialize tdm_display");
- goto err_display;
- }
-
- err = tdm_display_get_fd(tdm->tdm_display, &tdm->fd);
- if (err != TDM_ERROR_NONE || tdm->fd < 0) {
- ds_err("Could not get fd from tdm_display: err(%d)", err);
- goto err_fd;
- }
-
- loop = wl_display_get_event_loop(display);
- tdm->tdm_event = wl_event_loop_add_fd(loop, tdm->fd, WL_EVENT_READABLE,
- tdm_backend_handle_tdm_event, tdm);
- if (!tdm->tdm_event) {
- ds_err("could not add fd event handler for tdm event");
- goto err_event;
- }
-
- tdm->display_destroy.notify = tdm_backend_handle_display_destroy;
- wl_display_add_destroy_listener(display, &tdm->display_destroy);
-
- return &tdm->base;
-
-err_event:
- close(tdm->fd);
-err_fd:
- tdm_display_deinit(tdm->tdm_display);
-err_display:
- free(tdm);
-
- return NULL;
-}
-
-struct ds_tdm_backend *
-tdm_backend_from_backend(struct ds_backend *backend)
-{
- assert(backend->iface == &tdm_backend_iface);
- return (struct ds_tdm_backend *)backend;
-}
-
-static void
-tdm_backend_destroy(struct ds_tdm_backend *tdm)
-{
- struct ds_tdm_output *output, *tmp_output;
- struct ds_tdm_buffer *buffer, *tmp_buffer;
-
- wl_list_for_each_safe(output, tmp_output, &tdm->outputs, link)
- ds_output_destroy(&output->base);
-
- wl_list_for_each_safe(buffer, tmp_buffer, &tdm->buffers, link)
- destroy_tdm_buffer(buffer);
-
- wl_list_remove(&tdm->display_destroy.link);
- wl_event_source_remove(tdm->tdm_event);
- close(tdm->fd);
- tdm_display_deinit(tdm->tdm_display);
- ds_backend_finish(&tdm->base);
- free(tdm);
-}
-
-static bool
-tdm_backend_scan_outputs(struct ds_tdm_backend *tdm)
-{
- struct ds_tdm_output *output;
- tdm_output *tdm_output;
- tdm_error err;
- int num_outputs, i;
-
- err = tdm_display_get_output_count(tdm->tdm_display, &num_outputs);
- if (err != TDM_ERROR_NONE) {
- ds_err("Could not get number of outputs: err(%d)", err);
- return false;
- }
-
- for (i = 0; i < num_outputs; i++) {
- tdm_output = tdm_display_get_output(tdm->tdm_display, i, &err);
- if (err != TDM_ERROR_NONE || !tdm_output) {
- ds_err("Could not get output from tdm_display: index(%d) err(%d)",
- i, err);
- continue;
- }
-
- output = create_tdm_output(tdm, tdm_output);
- if (!output) {
- ds_err("Could not create output: index(%d)", i);
- continue;
- }
-
- wl_list_insert(&tdm->outputs, &output->link);
-
- wl_signal_emit(&tdm->base.events.new_output, &output->base);
- }
-
- return true;
-}
-
-static bool
-tdm_backend_iface_start(struct ds_backend *backend)
-{
- struct ds_tdm_backend *tdm;
-
- tdm = tdm_backend_from_backend(backend);
- return tdm_backend_scan_outputs(tdm);
-}
-
-static void
-tdm_backend_iface_destroy(struct ds_backend *backend)
-{
- struct ds_tdm_backend *tdm;
-
- tdm = tdm_backend_from_backend(backend);
- tdm_backend_destroy(tdm);
-}
-
-static const struct ds_backend_interface tdm_backend_iface =
-{
- .start = tdm_backend_iface_start,
- .destroy = tdm_backend_iface_destroy,
- .get_drm_fd = NULL,
-};
-
-static void
-tdm_backend_handle_display_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_tdm_backend *tdm;
-
- tdm = wl_container_of(listener, tdm, display_destroy);
- tdm_backend_destroy(tdm);
-}
-
-static int
-tdm_backend_handle_tdm_event(int fd, uint32_t mask, void *data)
-{
- struct ds_tdm_backend *tdm = data;
-
- tdm_display_handle_events(tdm->tdm_display);
-
- return 0;
-}
+++ /dev/null
-libds_tizen_files += files(
- 'backend.c',
- 'output.c',
- 'tdm_buffer_queue.c',
-)
-
-libtdm = dependency('libtdm', required: true)
-libtbm = dependency('libtbm', required: true)
-
-libds_tizen_deps += [
- libtdm,
- libtbm
-]
+++ /dev/null
-#include <assert.h>
-#include <stdlib.h>
-
-#include <tbm_surface.h>
-
-#include "libds/log.h"
-#include "libds-tizen/allocator/tbm.h"
-
-#include "tdm.h"
-#include "tdm_buffer_queue.h"
-
-static const struct ds_output_interface tdm_output_iface;
-static bool output_init_modes(struct ds_tdm_output *output);
-static void output_destroy(struct ds_tdm_output *output);
-static void output_init_hwc(struct ds_tdm_output *output);
-static bool output_update_mode(struct ds_tdm_output *output);
-static bool output_set_pending_fb(struct ds_tdm_output *output,
- struct ds_buffer *ds_buffer);
-static bool output_hwc_commit(struct ds_tdm_output *output);
-
-WL_EXPORT struct ds_tdm_output *
-ds_tdm_output_from_output(struct ds_output *ds_output)
-{
- if (ds_output->iface != &tdm_output_iface) {
- ds_err("Given ds_output is not for ds_tdm_output");
- return NULL;
- }
-
- return (struct ds_tdm_output *)ds_output;
-}
-
-WL_EXPORT struct ds_tdm_buffer_queue *
-ds_tdm_output_get_buffer_queue(struct ds_tdm_output *output)
-{
- if (output->queue)
- return output->queue;
-
- output->queue = create_buffer_queue(output);
- if (!output->queue) {
- ds_err("Could not create tbm_queue with output(%p)", output);
- return NULL;
- }
-
- return output->queue;
-}
-
-struct ds_tdm_output *
-create_tdm_output(struct ds_tdm_backend *tdm, tdm_output *tdm_output)
-{
- struct ds_tdm_output *output;
- tdm_output_conn_status conn;
- tdm_error err;
-
- output = calloc(1, sizeof *output);
- if (!output)
- return NULL;
-
- ds_output_init(&output->base, &tdm->base, &tdm_output_iface,
- tdm->wl_display);
-
- output->backend = tdm;
- output->tdm.output = tdm_output;
-
- err = tdm_output_get_conn_status(tdm_output, &conn);
- if (err != TDM_ERROR_NONE) {
- ds_err("Could not get connection status of tdm output(%p): err(%d)",
- tdm_output, err);
- goto err_status;
- }
-
- if (conn == TDM_OUTPUT_CONN_STATUS_CONNECTED) {
- output->status = DS_TDM_OUTPUT_CONNECTED;
-
- if (!output_init_modes(output)) {
- ds_err("Could not initialize modes of tdm output(%p)",
- tdm_output);
- goto err_status;
- }
- }
- else if (conn == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
- output->status = DS_TDM_OUTPUT_DISCONNECTED;
- }
-
- if (tdm_output_get_hwc(output->tdm.output, NULL) != NULL)
- output_init_hwc(output);
-
- ds_inf("TDM output(%p) created: hwc(%p)", output, output->tdm.hwc);
-
- return output;
-
-err_status:
- free(output);
-
- return NULL;
-}
-
-static struct ds_tdm_output *
-tdm_output_from_output(struct ds_output *ds_output)
-{
- assert(ds_output->iface == &tdm_output_iface);
- return (struct ds_tdm_output *)ds_output;
-}
-
-static void
-output_iface_destroy(struct ds_output *ds_output)
-{
- struct ds_tdm_output *output;
-
- output = tdm_output_from_output(ds_output);
- output_destroy(output);
-}
-
-void
-destroy_tdm_buffer(struct ds_tdm_buffer *buffer)
-{
- if (buffer == NULL)
- return;
-
- if (!buffer->released)
- wl_list_remove(&buffer->buffer_release.link);
-
- wl_list_remove(&buffer->buffer_destroy.link);
- wl_list_remove(&buffer->link);
- free(buffer);
-}
-
-static void
-buffer_handle_buffer_release(struct wl_listener *listener, void *data)
-{
- struct ds_tdm_buffer *buffer;
-
- buffer = wl_container_of(listener, buffer, buffer_release);
- wl_list_remove(&buffer->buffer_release.link);
- buffer->released = true;
-}
-
-static void
-buffer_handle_buffer_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_tdm_buffer *buffer;
-
- buffer = wl_container_of(listener, buffer, buffer_destroy);
- destroy_tdm_buffer(buffer);
-}
-
-static struct ds_tdm_buffer *
-create_tdm_buffer(struct ds_tdm_backend *backend, struct ds_buffer *ds_buffer)
-{
- struct ds_tdm_buffer *buffer;
- tbm_surface_h surface;
-
- surface = ds_tbm_buffer_get_surface(ds_buffer);
- if (!surface) {
- ds_err("Could not get tbm_surface_h");
- return NULL;
- }
-
- buffer = calloc(1, sizeof *buffer);
- if (!buffer)
- return NULL;
-
- buffer->surface = surface;
- buffer->buffer = ds_buffer;
- wl_list_insert(&backend->buffers, &buffer->link);
-
- buffer->buffer_destroy.notify = buffer_handle_buffer_destroy;
- ds_buffer_add_destroy_listener(ds_buffer, &buffer->buffer_destroy);
-
- return buffer;
-}
-
-static struct ds_tdm_buffer *
-get_or_create_tdm_buffer(struct ds_tdm_backend *backend,
- struct ds_buffer *ds_buffer)
-{
- struct ds_tdm_buffer *buffer;
-
- wl_list_for_each(buffer, &backend->buffers, link) {
- if (buffer->buffer == ds_buffer && buffer->released) {
- goto out;
- }
- }
-
- buffer = create_tdm_buffer(backend, ds_buffer);
-
-out:
- buffer->released = false;
-
- buffer->buffer_release.notify = buffer_handle_buffer_release;
- ds_buffer_add_release_listener(ds_buffer, &buffer->buffer_release);
-
- ds_buffer_lock(buffer->buffer);
-
- return buffer;
-}
-
-static void
-output_update_front_buffer(struct ds_tdm_output *output)
-{
- if (output->front_buffer)
- ds_buffer_unlock(output->front_buffer);
- output->front_buffer = output->back_buffer;
- output->back_buffer = NULL;
-}
-
-static void
-output_attach_back_buffer(struct ds_tdm_output *output,
- struct ds_buffer *buffer)
-{
- if (output->back_buffer)
- ds_buffer_unlock(output->back_buffer);
- output->back_buffer = buffer;
-}
-
-static bool
-output_iface_commit(struct ds_output *ds_output)
-{
- struct ds_tdm_output *output;
-
- output = tdm_output_from_output(ds_output);
-
- if (ds_output->pending.committed & DS_OUTPUT_STATE_MODE) {
- if (!output_update_mode(output)) {
- ds_err("Could not update TDM mode");
- return false;
- }
- }
-
- if (ds_output->pending.committed & DS_OUTPUT_STATE_BUFFER) {
- if (!output_set_pending_fb(output, ds_output->pending.buffer))
- ds_err("Could not update buffer");
- }
-
- if (!output_hwc_commit(output)) {
- ds_err("Could not commit tdm output");
- if (output->back_buffer)
- ds_buffer_unlock(output->back_buffer);
- }
-
- return true;
-}
-
-static const struct ds_output_interface tdm_output_iface =
-{
- .destroy = output_iface_destroy,
- .commit = output_iface_commit,
-};
-
-static void
-output_destroy(struct ds_tdm_output *output)
-{
- struct ds_tdm_output_mode *mode, *mode_tmp;
-
- wl_list_for_each_safe(mode, mode_tmp, &output->base.modes, base.link) {
- wl_list_remove(&mode->base.link);
- free(mode);
- }
-
- if (output->back_buffer)
- ds_buffer_unlock(output->back_buffer);
-
- if (output->front_buffer)
- ds_buffer_unlock(output->front_buffer);
-
- if (output->queue)
- buffer_queue_destroy(output->queue);
-
- free(output);
-}
-
-static bool
-output_init_modes(struct ds_tdm_output *output)
-{
- struct ds_tdm_output_mode *mode;
- const tdm_output_mode *tdm_modes, *tdm_mode;
- tdm_error err;
- int num_modes, i;
-
- err = tdm_output_get_available_modes(output->tdm.output, &tdm_modes,
- &num_modes);
- if (err != TDM_ERROR_NONE) {
- ds_err("Could not get available modes: output(%p)", output);
- return false;
- }
-
- ds_dbg("Detected modes:");
-
- for (i = 0; i < num_modes; i++) {
- tdm_mode = &tdm_modes[i];
-
- mode = calloc(1, sizeof *mode);
- if (!mode) {
- ds_err("Could not allocate memory");
- continue;
- }
-
- mode->tdm_mode = tdm_mode;
- mode->base.width = tdm_mode->hdisplay;
- mode->base.height = tdm_mode->vdisplay;
- mode->base.refresh = (int32_t)tdm_mode->vrefresh; // FIXME
-
- if (tdm_mode->type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
- mode->base.preferred = true;
-
- ds_dbg(" %dx%d@%d %s", mode->base.width, mode->base.height,
- mode->base.refresh,
- mode->base.preferred ? "(preferred)" : "");
-
- if (tdm_mode->type & TDM_OUTPUT_MODE_TYPE_DEFAULT)
- wl_list_insert(&output->base.modes, &mode->base.link);
- else
- wl_list_insert(output->base.modes.prev, &mode->base.link);
- }
-
- return true;
-}
-
-static void
-output_init_hwc(struct ds_tdm_output *output)
-{
- tdm_error err;
-
- output->tdm.hwc = tdm_output_get_hwc(output->tdm.output, &err);
- if (err != TDM_ERROR_NONE || !output->tdm.hwc) {
- ds_err("Could not get tdm_hwc: output(%p)", output);
- return;
- }
-}
-
-static bool
-output_update_mode(struct ds_tdm_output *output)
-{
- const struct ds_tdm_output_mode *mode;
- tdm_error err;
-
- mode = (struct ds_tdm_output_mode *)output->base.pending.mode;
-
- ds_inf("TDM output(%p) set mode %dx%d %d mHz", output,
- mode->base.width, mode->base.height, mode->base.refresh);
-
- err = tdm_output_set_mode(output->tdm.output, mode->tdm_mode);
- if (err != TDM_ERROR_NONE)
- return false;
-
- return true;
-}
-
-static bool
-output_set_pending_fb(struct ds_tdm_output *output,
- struct ds_buffer *ds_buffer)
-{
- struct ds_tdm_queue_buffer *queue_buffer;
- struct ds_tdm_buffer *buffer;
- tbm_surface_h surface = NULL;
- tdm_region fb_damage;
- tdm_error err;
-
- if (output->queue) {
- queue_buffer = buffer_queue_find_buffer(output->queue, ds_buffer);
- if (queue_buffer) {
- ds_buffer_lock(ds_buffer);
- surface = queue_buffer->surface;
- }
- }
-
- if (!surface) {
- buffer = get_or_create_tdm_buffer(output->backend, ds_buffer);
- if (!buffer)
- return false;
-
- surface = buffer->surface;
- }
-
- memset(&fb_damage, 0, sizeof(fb_damage));
- err = tdm_hwc_set_client_target_buffer(output->tdm.hwc,
- surface, fb_damage);
- if (err != TDM_ERROR_NONE) {
- ds_err("Could not set hwc client target buffer");
- ds_buffer_unlock(ds_buffer);
- return false;
- }
-
- output_attach_back_buffer(output, ds_buffer);
-
- return true;
-}
-
-static void
-output_hwc_commit_handler(tdm_hwc *hwc, unsigned int sequence,
- unsigned int tv_sec, unsigned int tv_usec, void *user_data)
-{
- struct ds_tdm_output *output = user_data;
-
- output_update_front_buffer(output);
-
- wl_signal_emit(&output->base.events.frame, &output->base);
-}
-
-static bool
-output_hwc_commit(struct ds_tdm_output *output)
-{
- tdm_error err;
- uint32_t num_changes;
-
- err = tdm_hwc_validate(output->tdm.hwc, NULL, 0, &num_changes);
- if (err != TDM_ERROR_NONE) {
- ds_err("Could not hwc validate");
- return false;
- }
-
- err = tdm_hwc_accept_validation(output->tdm.hwc);
- if (err != TDM_ERROR_NONE) {
- ds_err("Could not hwc accept validation");
- return false;
- }
-
- err = tdm_hwc_commit(output->tdm.hwc, 0, output_hwc_commit_handler,
- output);
- if (err != TDM_ERROR_NONE) {
- ds_err("Could not hwc commit");
- return false;
- }
-
- return true;
-}
+++ /dev/null
-#ifndef DS_TIZEN_BACKEND_TDM_H
-#define DS_TIZEN_BACKEND_TDM_H
-
-#include <time.h>
-
-#include <tdm.h>
-
-#include "libds/interfaces/backend.h"
-#include "libds/interfaces/output.h"
-
-enum ds_tdm_output_status {
- DS_TDM_OUTPUT_DISCONNECTED,
- DS_TDM_OUTPUT_CONNECTED,
-};
-
-struct ds_tdm_output_mode {
- struct ds_output_mode base;
- const tdm_output_mode *tdm_mode;
-};
-
-struct ds_tdm_backend
-{
- struct ds_backend base;
-
- tdm_display *tdm_display;
- struct wl_display *wl_display;
- struct wl_event_source *tdm_event;
-
- struct wl_list outputs; // ds_tdm_output.link
- struct wl_list buffers; // ds_tdm_buffer.link
-
- struct wl_listener display_destroy;
-
- clockid_t clock;
- int fd;
-};
-
-struct ds_tdm_output
-{
- struct ds_output base;
-
- struct ds_tdm_backend *backend;
- struct ds_tdm_buffer_queue *queue;
- struct ds_buffer *front_buffer, *back_buffer;
-
- struct {
- tdm_output *output;
- tdm_hwc *hwc;
- } tdm;
-
- struct wl_list link;
-
- enum ds_tdm_output_status status;
-};
-
-struct ds_tdm_buffer
-{
- struct ds_buffer *buffer;
- tbm_surface_h surface;
- struct wl_list link; // ds_wl_backend.buffers
-
- struct wl_listener buffer_release;
- struct wl_listener buffer_destroy;
-
- bool released;
-};
-
-struct ds_tdm_backend *tdm_backend_from_backend(struct ds_backend *backend);
-
-struct ds_tdm_output *create_tdm_output(struct ds_tdm_backend *tdm,
- tdm_output *tdm_output);
-
-void destroy_tdm_buffer(struct ds_tdm_buffer *buffer);
-
-
-#endif
+++ /dev/null
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/eventfd.h>
-
-#include "libds/log.h"
-#include "libds/interfaces/buffer.h"
-
-#include "tdm.h"
-#include "tdm_buffer_queue.h"
-
-static void
-buffer_queue_handle_acquirable(tbm_surface_queue_h surface_queue,
- void *data);
-static struct ds_tdm_queue_buffer *
-create_queue_buffer(struct ds_tdm_buffer_queue *queue,
- tbm_surface_h surface);
-static void queue_buffer_destroy(struct ds_tdm_queue_buffer *buffer);
-static void queue_buffer_drop(struct ds_tdm_queue_buffer *buffer);
-static struct ds_buffer *
-queue_buffer_acquire(struct ds_tdm_queue_buffer *buffer);
-static int buffer_queue_handle_acquirable_efd(int fd, uint32_t mask,
- void *data);
-
-WL_EXPORT void *
-ds_tdm_buffer_queue_get_native_queue(struct ds_tdm_buffer_queue *queue)
-{
- return (void *)queue->tbm_surface_queue;
-}
-
-WL_EXPORT struct ds_buffer *
-ds_tdm_buffer_queue_acquire(struct ds_tdm_buffer_queue *queue)
-{
- struct ds_tdm_queue_buffer *buffer;
- tbm_surface_h surface;
- tbm_surface_queue_error_e err;
-
- if (!tbm_surface_queue_can_acquire(queue->tbm_surface_queue, 0))
- return NULL;
-
- err = tbm_surface_queue_acquire(queue->tbm_surface_queue, &surface);
- if (err != TBM_SURFACE_QUEUE_ERROR_NONE ||
- surface == NULL) {
- ds_err("Could not acquire tbm_surface from queue(%p)", queue);
- return NULL;
- }
-
- wl_list_for_each(buffer, &queue->buffers, link) {
- if (buffer->surface == surface)
- return queue_buffer_acquire(buffer);
- }
-
- buffer = create_queue_buffer(queue, surface);
- if (!buffer) {
- ds_err("Could not create tbm_queue_buffer with queue(%p)", queue);
- return NULL;
- }
-
- wl_list_insert(&queue->buffers, &buffer->link);
-
- return queue_buffer_acquire(buffer);
-}
-
-WL_EXPORT void
-ds_tdm_buffer_queue_add_acquirable_listener(struct ds_tdm_buffer_queue *queue,
- struct wl_listener *listener)
-{
- wl_signal_add(&queue->events.acquirable, listener);
-}
-
-struct ds_tdm_buffer_queue *
-create_buffer_queue(struct ds_tdm_output *output)
-{
- struct ds_tdm_buffer_queue *queue;
- tdm_error err;
-
- queue = calloc(1, sizeof *queue);
- if (!queue)
- return NULL;
-
- wl_list_init(&queue->buffers);
-
- wl_signal_init(&queue->events.acquirable);
-
- queue->tbm_surface_queue =
- tdm_hwc_get_client_target_buffer_queue(output->tdm.hwc, &err);
- if (err != TDM_ERROR_NONE ||
- queue->tbm_surface_queue == NULL) {
- ds_err("Could not get target buffer queue: err(%d)", err);
- free(queue);
- return NULL;
- }
-
- tbm_surface_queue_reset(queue->tbm_surface_queue,
- output->base.pending.mode->width,
- output->base.pending.mode->height,
- tbm_surface_queue_get_format(queue->tbm_surface_queue));
-
- /* The callback function for tbm_surface_queue_add_acquirable_cb() may be
- * called on different thread. This eventfd is to emit a signal of
- * events.acquirable on the thread getting this buffer queue. */
- queue->acquirable_efd = eventfd(0, EFD_NONBLOCK);
- if (queue->acquirable_efd < 0) {
- ds_log_errno(DS_ERR,
- "Could not create eventfd for acquirable callback");
- free(queue);
- return NULL;
- }
-
- queue->acquirable_source = wl_event_loop_add_fd(
- wl_display_get_event_loop(output->backend->wl_display),
- queue->acquirable_efd,
- WL_EVENT_READABLE,
- buffer_queue_handle_acquirable_efd,
- queue);
-
- tbm_surface_queue_add_acquirable_cb(queue->tbm_surface_queue,
- buffer_queue_handle_acquirable, (void *)queue);
-
- return queue;
-}
-
-void
-buffer_queue_destroy(struct ds_tdm_buffer_queue *queue)
-{
- struct ds_tdm_queue_buffer *buffer, *buffer_tmp;
-
- wl_list_for_each_safe(buffer, buffer_tmp, &queue->buffers, link)
- queue_buffer_drop(buffer);
-
- wl_event_source_remove(queue->acquirable_source);
- close(queue->acquirable_efd);
- tbm_surface_queue_destroy(queue->tbm_surface_queue);
- free(queue);
-}
-
-struct ds_tdm_queue_buffer *
-buffer_queue_find_buffer(struct ds_tdm_buffer_queue *queue,
- struct ds_buffer *ds_buffer)
-{
- struct ds_tdm_queue_buffer *buffer;
-
- wl_list_for_each(buffer, &queue->buffers, link) {
- if (&buffer->base == ds_buffer)
- return buffer;
- }
-
- return NULL;
-}
-
-static void
-buffer_queue_handle_acquirable(tbm_surface_queue_h surface_queue, void *data)
-{
- struct ds_tdm_buffer_queue *queue = data;
- uint64_t acquirable = 1;
- int ret;
-
- ret = write(queue->acquirable_efd, &acquirable, sizeof(acquirable));
- if (ret < 0)
- ds_log_errno(DS_ERR, "Could not write eventfd for acquirable buffer");
-}
-
-static const struct ds_buffer_interface queue_buffer_iface;
-
-static struct ds_tdm_queue_buffer *
-create_queue_buffer(struct ds_tdm_buffer_queue *queue, tbm_surface_h surface)
-{
- struct ds_tdm_queue_buffer *buffer;
-
- buffer = calloc(1, sizeof *buffer);
- if (!buffer)
- return NULL;
-
- ds_buffer_init(&buffer->base, &queue_buffer_iface,
- tbm_surface_get_width(surface),
- tbm_surface_get_height(surface));
-
- buffer->queue = queue;
- buffer->surface = surface;
-
- return buffer;
-}
-
-static void
-queue_buffer_destroy(struct ds_tdm_queue_buffer *buffer)
-{
- free(buffer);
-}
-
-static struct ds_tdm_queue_buffer *
-queue_buffer_from_buffer(struct ds_buffer *ds_buffer)
-{
- assert(ds_buffer->iface == &queue_buffer_iface);
- return (struct ds_tdm_queue_buffer *)ds_buffer;
-}
-
-static void
-queue_buffer_iface_destroy(struct ds_buffer *ds_buffer)
-{
- struct ds_tdm_queue_buffer *buffer;
-
- buffer = queue_buffer_from_buffer(ds_buffer);
- queue_buffer_destroy(buffer);
-}
-
-static bool
-queue_buffer_iface_begin_data_ptr_access(struct ds_buffer *ds_buffer,
- uint32_t flags, void **data, uint32_t *format, size_t *stride)
-{
- struct ds_tdm_queue_buffer *buffer;
- tbm_surface_info_s info;
- int tbm_access_flags = 0;
- int ret;
-
- buffer = queue_buffer_from_buffer(ds_buffer);
-
- if (!buffer->surface) {
- ds_err("No tbm_surface. It's a dropped buffer(%p)", buffer);
- return false;
- }
-
- if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ)
- tbm_access_flags |= TBM_OPTION_READ;
- else if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE)
- tbm_access_flags |= TBM_OPTION_WRITE;
-
- ret = tbm_surface_map(buffer->surface, tbm_access_flags, &info);
- if (ret != TBM_SURFACE_ERROR_NONE) {
- ds_err("Could not map tbm_surface of buffer(%p)", buffer);
- return false;
- }
-
- *data = info.planes[0].ptr;
- *format = info.format;
- *stride = info.planes[0].stride;
-
- return true;
-}
-
-static void
-queue_buffer_iface_end_data_ptr_access(struct ds_buffer *ds_buffer)
-{
- struct ds_tdm_queue_buffer *buffer;
-
- buffer = queue_buffer_from_buffer(ds_buffer);
- if (!buffer->surface) {
- ds_err("No tbm_surface. It's a dropped buffer(%p)", buffer);
- return;
- }
-
- tbm_surface_unmap(buffer->surface);
-}
-
-static const struct ds_buffer_interface queue_buffer_iface =
-{
- .destroy = queue_buffer_iface_destroy,
- .begin_data_ptr_access = queue_buffer_iface_begin_data_ptr_access,
- .end_data_ptr_access = queue_buffer_iface_end_data_ptr_access,
-};
-
-static void
-queue_buffer_handle_buffer_release(struct wl_listener *listener, void *data)
-{
- struct ds_tdm_queue_buffer *buffer;
-
- buffer = wl_container_of(listener, buffer, buffer_release);
-
- wl_list_remove(&buffer->buffer_release.link);
- buffer->acquired = false;
-
- tbm_surface_queue_release(buffer->queue->tbm_surface_queue,
- buffer->surface);
-}
-
-static void
-queue_buffer_drop(struct ds_tdm_queue_buffer *buffer)
-{
- if (buffer->acquired)
- wl_list_remove(&buffer->buffer_release.link);
-
- wl_list_remove(&buffer->link);
- ds_buffer_drop(&buffer->base);
- buffer->surface = NULL;
-}
-
-static struct ds_buffer *
-queue_buffer_acquire(struct ds_tdm_queue_buffer *buffer)
-{
- assert(!buffer->acquired);
-
- buffer->acquired = true;
- buffer->buffer_release.notify = queue_buffer_handle_buffer_release;
- ds_buffer_add_release_listener(&buffer->base, &buffer->buffer_release);
-
- return ds_buffer_lock(&buffer->base);
-}
-
-static int
-buffer_queue_handle_acquirable_efd(int fd, uint32_t mask, void *data)
-{
- struct ds_tdm_buffer_queue *queue = data;
- uint64_t acquirable_event;
-
- if (read(fd, &acquirable_event, sizeof(acquirable_event)) < 0 &&
- errno != EAGAIN)
- return -1;
-
- wl_signal_emit(&queue->events.acquirable, queue);
-
- return 0;
-}
+++ /dev/null
-#ifndef DS_TIZEN_BACKEND_TDM_BUFFER_QUEUE_H
-#define DS_TIZEN_BACKEND_TDM_BUFFER_QUEUE_H
-
-#include <tbm_surface_queue.h>
-#include <libds/interfaces/buffer.h>
-
-#include "tdm.h"
-
-struct ds_tdm_buffer_queue
-{
- tbm_surface_queue_h tbm_surface_queue;
- struct wl_event_source *acquirable_source;
-
- struct wl_list buffers; // ds_tdm_queue_buffer.link
-
- struct {
- struct wl_signal acquirable;
- } events;
-
- int acquirable_efd;
-};
-
-struct ds_tdm_queue_buffer
-{
- struct ds_buffer base;
-
- struct ds_tdm_output *output;
- struct ds_tdm_buffer_queue *queue;
- tbm_surface_h surface;
-
- struct wl_list link;
- struct wl_listener buffer_release;
-
- bool acquired;
-};
-
-struct ds_tdm_buffer_queue *create_buffer_queue(struct ds_tdm_output *output);
-
-void buffer_queue_destroy(struct ds_tdm_buffer_queue *queue);
-
-struct ds_tdm_queue_buffer *
-buffer_queue_find_buffer(struct ds_tdm_buffer_queue *queue,
- struct ds_buffer *ds_buffer);
-
-#endif
+++ /dev/null
-#include <assert.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <wayland-server.h>
-#include "libds/log.h"
-#include "libds/output.h"
-#include "libds-tizen/dpms.h"
-#include "tizen-dpms-server-protocol.h"
-#include "util.h"
-
-struct ds_tizen_dpms
-{
- struct wl_global *global;
- struct wl_resource *res;
-
- struct wl_listener destroy;
-
- struct {
- struct wl_signal destroy;
- struct wl_signal set_dpms;
- struct wl_signal get_dpms;
- } events;
-
- bool binded;
-};
-
-#define TIZEN_DPMS_VERSION 1
-
-static void dpms_handle_display_destroy(struct wl_listener *listener,
- void *data);
-static void dpms_bind(struct wl_client *wl_client, void *data,
- uint32_t verison, uint32_t id);
-
-WL_EXPORT struct ds_tizen_dpms *
-ds_tizen_dpms_create(struct wl_display *display)
-{
- struct ds_tizen_dpms *dpms;
-
- dpms = calloc(1, sizeof *dpms);
- if (!dpms) {
- ds_err("dpms create fail : memory alloc failed");
- return NULL;
- }
-
- dpms->global = wl_global_create(display, &tizen_dpms_manager_interface,
- 1, dpms, dpms_bind);
- if (!dpms->global) {
- ds_err("global create fail : tizen_dpms_manager_interface failed");
- free(dpms);
- return NULL;
- }
-
- wl_signal_init(&dpms->events.destroy);
- wl_signal_init(&dpms->events.set_dpms);
- wl_signal_init(&dpms->events.get_dpms);
-
- dpms->destroy.notify = dpms_handle_display_destroy;
- wl_display_add_destroy_listener(display, &dpms->destroy);
-
- ds_inf("global create : tizen_dpms_manager(%p)", dpms);
-
- return dpms;
-}
-
-WL_EXPORT void
-ds_tizen_dpms_add_destroy_listener(struct ds_tizen_dpms *dpms,
- struct wl_listener *listener)
-{
- wl_signal_add(&dpms->events.destroy, listener);
-}
-
-WL_EXPORT void
-ds_tizen_dpms_add_set_dpms_listener(struct ds_tizen_dpms *dpms,
- struct wl_listener *listener)
-{
- wl_signal_add(&dpms->events.set_dpms, listener);
-}
-
-WL_EXPORT void
-ds_tizen_dpms_add_get_dpms_listener(struct ds_tizen_dpms *dpms,
- struct wl_listener *listener)
-{
- wl_signal_add(&dpms->events.get_dpms, listener);
-}
-
-WL_EXPORT void
-ds_tizen_dpms_send_set_result(struct ds_tizen_dpms *dpms,
- enum ds_tizen_dpms_mode mode, enum ds_tizen_dpms_error error)
-{
- ds_dbg("dpms send set result : mode(%d), error(%d)", mode, error);
- tizen_dpms_manager_send_set_state(dpms->res, mode, error);
-}
-
-WL_EXPORT void
-ds_tizen_dpms_send_get_result(struct ds_tizen_dpms *dpms,
- enum ds_tizen_dpms_mode mode, enum ds_tizen_dpms_error error)
-{
- ds_dbg("dpms send get result : mode(%d), error(%d)", mode, error);
- tizen_dpms_manager_send_get_state(dpms->res, mode, error);
-}
-
-static void
-dpms_handle_display_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_tizen_dpms *dpms;
-
- dpms = wl_container_of(listener, dpms, destroy);
-
- ds_inf("global destroy : tizen_dpms_manager(%p)", dpms);
-
- wl_signal_emit(&dpms->events.destroy, dpms);
- wl_list_remove(&dpms->destroy.link);
- wl_resource_set_user_data(dpms->res, NULL);
- wl_global_destroy(dpms->global);
- free(dpms);
-}
-
-static void
-_tizen_dpms_manager_handle_destroy(struct wl_client *client,
- struct wl_resource *resource)
-{
- ds_inf("tizen_dpms_manager cb_destroy (res:%p)", resource);
- wl_resource_destroy(resource);
-}
-
-static void
-_tizen_dpms_manager_handle_set_dpms(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *output, uint32_t mode)
-{
- struct ds_tizen_dpms *dpms;
-
- dpms = wl_resource_get_user_data(resource);
-
- if (mode > DS_TIZEN_DPMS_MODE_OFF) {
- ds_err("set dpms error : not supported mode(%d)", mode);
- tizen_dpms_manager_send_set_state(resource, DS_TIZEN_DPMS_MODE_OFF,
- DS_TIZEN_DPMS_ERROR_INVALID_PARAMETER);
- return;
- }
-
- struct ds_tizen_dpms_event event = {
- .mode = mode,
- };
-
- wl_signal_emit(&dpms->events.set_dpms, &event);
-}
-
-static void
-_tizen_dpms_manager_handle_get_dpms(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *output)
-{
- struct ds_tizen_dpms *dpms;
-
- dpms = wl_resource_get_user_data(resource);
-
- wl_signal_emit(&dpms->events.get_dpms, NULL);
-}
-
-static const struct tizen_dpms_manager_interface dpms_impl =
-{
- _tizen_dpms_manager_handle_destroy,
- _tizen_dpms_manager_handle_set_dpms,
- _tizen_dpms_manager_handle_get_dpms,
-};
-
-static void
-_tizen_dpms_client_cb_destroy(struct wl_resource *resource)
-{
- struct ds_tizen_dpms *dpms;
-
- ds_inf("tizen_dpms_client_cb_destroy (res:%p)", resource);
-
- dpms = wl_resource_get_user_data(resource);
- if (dpms) {
- dpms->binded = false;
- dpms->res = NULL;
- }
-}
-
-static void
-dpms_bind(struct wl_client *client, void *data, uint32_t version,
- uint32_t id)
-{
- struct ds_tizen_dpms *dpms = data;
-
- if (dpms->binded == true) {
- //support only one client.
- ds_err("dpms bind error : already binded.");
- return;
- }
-
- dpms->res = wl_resource_create(client, &tizen_dpms_manager_interface,
- MIN(version, TIZEN_DPMS_VERSION), id);
- if (dpms->res == NULL) {
- ds_err("dpms bind error : wl_resource_create failed.");
- wl_client_post_no_memory(client);
- return;
- }
-
- wl_resource_set_implementation(dpms->res, &dpms_impl, dpms,
- _tizen_dpms_client_cb_destroy);
-
- dpms->binded = true;
-}
+++ /dev/null
-#include <stdlib.h>
-#include <time.h> // gettimeofday()
-#include <libds/backend.h>
-#include <libds/log.h>
-#include <libds-tizen/input-devicemgr.h>
-#include <libds/interfaces/backend.h>
-#include <libds/interfaces/keyboard.h>
-#include <libds/seat.h>
-
-#include "util.h"
-#include "input-devicemgr.h"
-#include "src/libds/seat.h"
-
-#define TIZEN_INPUT_DEVICEMGR_VERSION 4
-#define TIZEN_PRIV_INPUT_GENERATOR "http://tizen.org/privilege/inputgenerator"
-#define TIZEN_PRIV_INPUT_BLOCK "http://tizen.org/privilege/internal/inputdevice.block"
-
-static const struct ds_keyboard_grab_interface devicemgr_keyboard_grab_iface;
-
-//listeners
-static void
-backend_handle_destroy(struct wl_listener *listener, void *data);
-static void
-backend_handle_input_device_add(struct wl_listener *listener, void *data);
-static void
-seat_handle_destroy(struct wl_listener *listener, void *data);
-
-//tizen_input_device_manager bind/unbind
-static void
-device_manager_handle_bind(struct wl_client *client, void *data,
- uint32_t version, uint32_t id);
-static void
-device_manager_client_handle_resource_destroy(struct wl_resource *resource);
-
-//tizen_input_device_manager's handlers for requests
-static void
-device_manager_handle_block_events(struct wl_client *client,
- struct wl_resource *resource, uint32_t serial,
- uint32_t clas, uint32_t duration);
-static void
-device_manager_handle_unblock_events(struct wl_client *client,
- struct wl_resource *resource, uint32_t serial);
-static void
-device_manager_handle_init_generator(struct wl_client *client,
- struct wl_resource *resource, uint32_t clas);
-static void
-device_manager_handle_init_generator_with_name(struct wl_client *client,
- struct wl_resource *resource, uint32_t clas, const char *name);
-static void
-device_manager_handle_deinit_generator(struct wl_client *client,
- struct wl_resource *resource, uint32_t clas);
-static void
-device_manager_handle_generate_key(struct wl_client *client,
- struct wl_resource *resource,
- const char *keyname, uint32_t pressed);
-static void
-device_manager_handle_destroy(struct wl_client *client,
- struct wl_resource *resource);
-
-//
-static void tz_devicemgr_destroy(struct ds_tizen_input_devicemgr *tz_devicemgr);
-static int
-tz_devicemgr_init_generator(struct ds_tizen_input_devicemgr *tz_devicemgr,
- struct wl_resource *resource, const char *name);
-static int
-tz_devicemgr_deinit_generator(struct ds_tizen_input_devicemgr *tz_devicemgr,
- struct wl_resource *resource);
-static bool
-tz_devicemgr_generate_key(struct ds_input_device *device, int keycode,
- int pressed);
-static bool
-tz_devicemgr_pressed_keys_update(struct ds_tizen_input_devicemgr *tz_devicemgr,
- int keycode, bool pressed);
-static void
-tz_devicemgr_pressed_keys_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr);
-static void
-tz_devicemgr_keymap_list_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr);
-static int
-tz_devicemgr_keyname_to_keycode(struct wl_list *list, const char *name);
-
-static bool
-tz_devicemgr_check_privilege(struct ds_tizen_input_devicemgr *tz_devicemgr,
- struct wl_client *client, const char *rule);
-
-static void
-tz_devicemgr_grab_keyboard(struct ds_tizen_input_devicemgr *tz_devicemgr);
-static void
-tz_devicemgr_ungrab_keyboard(struct ds_tizen_input_devicemgr *tz_devicemgr);
-static void
-tz_devicemgr_ungrab_keyboard_check(struct ds_tizen_input_devicemgr *tz_devicemgr);
-static void
-tz_devicemgr_blocked_keys_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr);
-
-WL_EXPORT struct ds_tizen_input_devicemgr *
-ds_tizen_input_devicemgr_create(struct ds_backend *backend,
- struct ds_seat *seat)
-{
- struct ds_tizen_input_devicemgr *tz_devicemgr;
-
- tz_devicemgr = calloc(1, sizeof *tz_devicemgr);
- if (!tz_devicemgr) {
- ds_err("Fail to allocate ds_tizen_input_devicemgr");
- return NULL;
- }
-
- tz_devicemgr->backend = backend;
- tz_devicemgr->backend_destroy.notify = backend_handle_destroy;
- ds_backend_add_destroy_listener(backend, &tz_devicemgr->backend_destroy);
-
- tz_devicemgr->seat = seat;
- tz_devicemgr->seat_destroy.notify = seat_handle_destroy;
- ds_seat_add_destroy_listener(seat, &tz_devicemgr->seat_destroy);
-
- tz_devicemgr->new_input.notify = backend_handle_input_device_add;
- ds_backend_add_new_input_listener(backend, &tz_devicemgr->new_input);
-
- tz_devicemgr->global = wl_global_create(backend->display,
- &tizen_input_device_manager_interface,
- TIZEN_INPUT_DEVICEMGR_VERSION,
- tz_devicemgr, device_manager_handle_bind);
- if (!tz_devicemgr->global) {
- goto err_global;
- }
-
- tz_devicemgr->devices.kbd = calloc(1,
- sizeof(struct ds_tizen_input_devicemgr_device));
- if (!tz_devicemgr->devices.kbd) {
- goto err_kbd;
- }
-
- tz_devicemgr->grab = calloc(1, sizeof(struct ds_seat_keyboard_grab));
- if (!tz_devicemgr->grab)
- {
- goto err_grab;
- }
-
- tz_devicemgr->grab->iface = &devicemgr_keyboard_grab_iface;
- tz_devicemgr->grab->seat = tz_devicemgr->seat;
- tz_devicemgr->grab->data = tz_devicemgr;
-
- wl_signal_init(&tz_devicemgr->events.destroy);
- wl_list_init(&tz_devicemgr->clients);
- wl_list_init(&tz_devicemgr->pressed_keys);
- wl_list_init(&tz_devicemgr->keymap_list);
- wl_list_init(&tz_devicemgr->blocked_keys);
-
- if (!tizen_security_init()) {
- ds_inf("tizen_security_init() is failed. go on without security");
- }
-
- ds_inf("Global created: ds_tizen_input_devicemgr(%p) ", tz_devicemgr);
- return tz_devicemgr;
-err_grab:
- free(tz_devicemgr->devices.kbd);
-err_kbd:
- wl_global_destroy(tz_devicemgr->global);
-err_global:
- wl_list_remove(&tz_devicemgr->backend_destroy.link);
- wl_list_remove(&tz_devicemgr->seat_destroy.link);
- wl_list_remove(&tz_devicemgr->new_input.link);
- free(tz_devicemgr);
- return NULL;
-}
-
-WL_EXPORT void
-ds_tizen_input_devicemgr_add_destroy_listener(
- struct ds_tizen_input_devicemgr *tz_devicemgr,
- struct wl_listener *listener)
-{
- wl_signal_add(&tz_devicemgr->events.destroy, listener);
-}
-
-WL_EXPORT bool
-ds_tizen_input_devicemgr_set_keymap_list(
- struct ds_tizen_input_devicemgr *tz_devicemgr, struct wl_list *list)
-{
- struct ds_tizen_input_devicemgr_keymap_data *data, *new_data;
-
- if (!tz_devicemgr || !list) {
- ds_err("Please insert correct data\n");
- return false;
- }
-
- wl_list_for_each(data, list, link) {
- new_data = calloc(1, sizeof *data);
- if (!new_data) {
- ds_err("Failed to alloc memory");
- return false;
- }
- new_data->name = strdup(data->name);
- new_data->keycode = data->keycode;
- wl_list_insert(&tz_devicemgr->keymap_list, &new_data->link);
- }
- ds_inf("keymap set. length:%d",
- wl_list_length(&tz_devicemgr->keymap_list));
-
- return true;
-}
-
-static void
-tz_devicemgr_destroy(struct ds_tizen_input_devicemgr *tz_devicemgr)
-{
- struct ds_tizen_input_devicemgr_client *client_data, *tmp;
-
- tizen_security_finish();
-
- tz_devicemgr_keymap_list_cleanup(tz_devicemgr);
- tz_devicemgr_blocked_keys_cleanup(tz_devicemgr);
- tz_devicemgr_ungrab_keyboard(tz_devicemgr);
-
- wl_signal_emit(&tz_devicemgr->events.destroy, tz_devicemgr);
- wl_list_remove(&tz_devicemgr->backend_destroy.link);
- wl_list_remove(&tz_devicemgr->seat_destroy.link);
- wl_list_remove(&tz_devicemgr->new_input.link);
-
- wl_global_destroy(tz_devicemgr->global);
-
- wl_list_for_each_safe(client_data, tmp, &tz_devicemgr->clients, link) {
- wl_list_remove(&client_data->link);
- tz_devicemgr_deinit_generator(tz_devicemgr, client_data->resource);
-
- wl_resource_set_user_data(client_data->resource, NULL);
- free(client_data);
- }
-
- free(tz_devicemgr->devices.kbd);
- free(tz_devicemgr->grab);
- free(tz_devicemgr);
-}
-
-static void
-backend_handle_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_tizen_input_devicemgr *tz_devicemgr;
-
- tz_devicemgr = wl_container_of(listener, tz_devicemgr, backend_destroy);
-
- ds_inf("Global destroy: ds_tizen_input_devicemgr(%p)", tz_devicemgr);
-
- tz_devicemgr_destroy(tz_devicemgr);
-}
-
-static void
-seat_handle_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_tizen_input_devicemgr *tz_devicemgr;
-
- tz_devicemgr = wl_container_of(listener, tz_devicemgr, backend_destroy);
-
- wl_list_remove(&tz_devicemgr->seat_destroy.link);
- wl_list_init(&tz_devicemgr->seat_destroy.link);
- tz_devicemgr->seat = NULL;
-}
-
-static void
-backend_handle_input_device_add(struct wl_listener *listener, void *data)
-{
- struct ds_input_device *dev = data;
- struct ds_tizen_input_devicemgr *tz_devicemgr;
- enum ds_input_device_type dev_type;
-
- tz_devicemgr = wl_container_of(listener, tz_devicemgr, new_input);
-
- dev_type = ds_input_device_get_type(dev);
- if (dev_type == DS_INPUT_DEVICE_KEYBOARD) {
- if (tz_devicemgr->devices.kbd->input_device) return;
- ds_inf("devicemgr's kbd device is set");
- tz_devicemgr->devices.kbd->input_device = dev;
- }
- else if (dev_type == DS_INPUT_DEVICE_POINTER) {
- //TODO: assign input_device 'dev' to devices.ptr
- }
- else if (dev_type == DS_INPUT_DEVICE_TOUCH) {
- //TODO: assign input_device 'dev' to devices.ptr
- }
-}
-
-static const struct tizen_input_device_manager_interface _devicemgr_impl = {
- .block_events = device_manager_handle_block_events,
- .unblock_events = device_manager_handle_unblock_events,
- .init_generator = device_manager_handle_init_generator,
- .deinit_generator = device_manager_handle_deinit_generator,
- .generate_key = device_manager_handle_generate_key,
- .generate_pointer = NULL,
- .generate_touch = NULL,
- .pointer_warp = NULL,
- .init_generator_with_name =
- device_manager_handle_init_generator_with_name, // v2
- .destroy = device_manager_handle_destroy, // v3
- .generate_axis = NULL, // v3
- .set_touch_count = NULL, // v4
-};
-
-static void
-device_manager_client_handle_resource_destroy(struct wl_resource *resource)
-{
- struct ds_tizen_input_devicemgr *tz_devicemgr;
- struct ds_tizen_input_devicemgr_client *client_data, *tmp;
-
- tz_devicemgr = wl_resource_get_user_data(resource);
-
- tz_devicemgr_deinit_generator(tz_devicemgr, resource);
-
- if (resource == tz_devicemgr->block_resource) {
- tz_devicemgr_ungrab_keyboard_check(tz_devicemgr);
- if (tz_devicemgr->timer) {
- wl_event_source_remove(tz_devicemgr->timer);
- tz_devicemgr->timer = NULL;
- }
- }
-
- wl_list_for_each_safe(client_data, tmp, &tz_devicemgr->clients, link) {
- if (client_data->resource == resource) {
- wl_list_remove(&client_data->link);
- free(client_data);
- }
- }
-}
-
-static void
-device_manager_handle_bind(struct wl_client *client, void *data,
- uint32_t version, uint32_t id)
-{
- struct ds_tizen_input_devicemgr *tz_devicemgr = data;
- struct ds_tizen_input_devicemgr_client *client_data;
-
- client_data = calloc(1, sizeof *client_data);
- if (!client_data) {
- ds_err("Failed to allocate memory !\n");
- wl_client_post_no_memory(client);
- return;
- }
-
- client_data->resource = wl_resource_create(client,
- &tizen_input_device_manager_interface, MIN(version,4), id);
- if (!client_data->resource) {
- ds_err("Failed to create resource! (ver. :%d, id:%d)", version, id);
- free(client_data);
- wl_client_post_no_memory(client);
- return;
- }
-
- client_data->init = false;
- wl_list_init(&client_data->link);
- wl_list_insert(&tz_devicemgr->clients, &client_data->link);
-
- wl_resource_set_implementation(client_data->resource, &_devicemgr_impl,
- tz_devicemgr, device_manager_client_handle_resource_destroy);
-}
-
-static void
-device_manager_handle_init_generator(struct wl_client *client,
- struct wl_resource *resource, uint32_t clas)
-{
- struct ds_tizen_input_devicemgr *tz_devicemgr;
- int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
-
- tz_devicemgr = wl_resource_get_user_data(resource);
-
- if (!tz_devicemgr_check_privilege(tz_devicemgr, client,
- TIZEN_PRIV_INPUT_GENERATOR)) {
- ds_err("No permission to input generate");
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION;
- goto finish;
- }
-
- if (clas != TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD) {
- ds_err("only support keyboard device. (requested: 0x%x)\n", clas);
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
- goto finish;
- }
-
- ret = tz_devicemgr_init_generator(tz_devicemgr, resource,
- "Input Generator");
- if (ret != TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
- ds_err("Failed to init input generator\n");
- goto finish;
- }
-
-finish:
- tizen_input_device_manager_send_error(resource, ret);
-}
-
-static void
-device_manager_handle_init_generator_with_name(struct wl_client *client,
- struct wl_resource *resource, uint32_t clas, const char *name)
-{
- struct ds_tizen_input_devicemgr *tz_devicemgr;
- int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
-
- tz_devicemgr = wl_resource_get_user_data(resource);
-
- if (!name) {
- ds_err("no name for device");
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
- goto finish;
- }
-
- if (!tz_devicemgr_check_privilege(tz_devicemgr, client,
- TIZEN_PRIV_INPUT_GENERATOR)) {
- ds_err("No permission to input generate");
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION;
- goto finish;
- }
-
- if (clas != TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD) {
- ds_err("only support keyboard device. (requested: 0x%x)\n", clas);
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
- goto finish;
- }
-
- ret = tz_devicemgr_init_generator(tz_devicemgr, resource,
- name);
- if (ret != TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
- ds_err("Failed to init input generator\n");
- goto finish;
- }
-
-finish:
- tizen_input_device_manager_send_error(resource, ret);
-}
-
-static void
-device_manager_handle_deinit_generator(struct wl_client *client,
- struct wl_resource *resource, uint32_t clas)
-{
- struct ds_tizen_input_devicemgr *tz_devicemgr;
- int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
-
- tz_devicemgr = wl_resource_get_user_data(resource);
-
- if (!tz_devicemgr_check_privilege(tz_devicemgr, client,
- TIZEN_PRIV_INPUT_GENERATOR)) {
- ds_err("No permission to input generate");
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION;
- goto finish;
- }
-
- if (clas != TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD) {
- ds_err("only support keyboard device. (requested: 0x%x)\n", clas);
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
- goto finish;
- }
-
- ret = tz_devicemgr_deinit_generator(tz_devicemgr, resource);
- if (ret != TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
- ds_err("Failed to deinit input generator\n");
- goto finish;
- }
-
-finish:
- tizen_input_device_manager_send_error(resource, ret);
-}
-
-struct keycode_map{
- xkb_keysym_t keysym;
- xkb_keycode_t keycode;
-};
-
-static void
-find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
-{
- struct keycode_map *found_keycodes = (struct keycode_map *)data;
- xkb_keysym_t keysym = found_keycodes->keysym;
- int nsyms = 0;
- const xkb_keysym_t *syms_out = NULL;
-
- if (found_keycodes->keycode) return;
-
- nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
- if (nsyms && syms_out) {
- if (*syms_out == keysym) {
- found_keycodes->keycode = key;
- }
- }
-}
-
-static void
-tz_devicemgr_xkb_keycode_from_keysym(struct xkb_keymap *keymap,
- xkb_keysym_t keysym, xkb_keycode_t *keycode)
-{
- struct keycode_map found_keycodes = {0,};
- found_keycodes.keysym = keysym;
- xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
-
- *keycode = found_keycodes.keycode;
-}
-
-static int
-tz_devicemgr_xkb_keyname_to_keycode(struct xkb_keymap *keymap,
- const char *name)
-{
- xkb_keysym_t keysym = 0x0;
- xkb_keycode_t keycode = 0;
-
- if (!strncmp(name, "Keycode-", sizeof("Keycode-")-1)) {
- keycode = atoi(name + 8);
- } else {
- keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
- tz_devicemgr_xkb_keycode_from_keysym(keymap, keysym, &keycode);
- }
-
- return keycode;
-}
-
-static void
-device_manager_handle_generate_key(struct wl_client *client,
- struct wl_resource *resource, const char *keyname, uint32_t pressed)
-{
- struct ds_tizen_input_devicemgr *tz_devicemgr;
- int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
- int keycode = 0;
- bool res;
- struct ds_keyboard *kbd;
-
- tz_devicemgr = wl_resource_get_user_data(resource);
-
- if (!tz_devicemgr->devices.kbd ||
- !tz_devicemgr->devices.kbd->input_device) {
- ds_err("Keyboard device is not initialized\n");
- goto finish;
- }
-
- if (!tz_devicemgr_check_privilege(tz_devicemgr, client,
- TIZEN_PRIV_INPUT_GENERATOR)) {
- ds_err("No permission to input generate");
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION;
- goto finish;
- }
-
- // keyname to keycode using xkb_info
- kbd = ds_input_device_get_keyboard(
- tz_devicemgr->devices.kbd->input_device);
- if (kbd->keymap) {
- keycode = tz_devicemgr_xkb_keyname_to_keycode(kbd->keymap, keyname);
- }
-
- if (keycode <= 0) {
- keycode = tz_devicemgr_keyname_to_keycode(&tz_devicemgr->keymap_list,
- keyname);
- }
- if (keycode <= 0)
- goto finish;
-
- res = tz_devicemgr_generate_key(tz_devicemgr->devices.kbd->input_device,
- keycode, pressed);
- if (!res) {
- ds_err("Generating key is failed. key: %s, pressed: %d",
- keyname, pressed);
- goto finish;
- }
- res = tz_devicemgr_pressed_keys_update(tz_devicemgr, keycode, pressed);
- if (!res) {
- ds_err("Updating pressed keys is failed. key: %s, pressed: %d",
- keyname, pressed);
- goto finish;
- }
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
-
-finish:
- tizen_input_device_manager_send_error(resource, ret);
-}
-
-static void
-device_manager_handle_destroy(struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static bool
-tz_devicemgr_check_privilege(struct ds_tizen_input_devicemgr *tz_devicemgr,
- struct wl_client *client, const char *rule)
-{
- pid_t pid = 0;
- uid_t uid = 0;
- gid_t gid = 0;
-
- if (!client) return false;
-
- wl_client_get_credentials(client, &pid, &uid, &gid);
-
- return tizen_security_check_privilege(pid, uid, rule);
-}
-
-static const struct ds_input_device_interface input_device_iface =
-{
- .destroy = NULL,
-};
-
-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 int
-tz_devicemgr_init_generator(struct ds_tizen_input_devicemgr *tz_devicemgr,
- struct wl_resource *resource, const char *name)
-{
- int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
- struct ds_tizen_input_devicemgr_client *client_data;
- struct ds_tizen_input_devicemgr_device *kbd;
-
- ds_inf("Init generator. name:%s", name);
-
- kbd = tz_devicemgr->devices.kbd;
- if (strlen(kbd->name) > 0) {
- ds_inf("devices.kbd already has name. name:%s", kbd->name);
- return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
- }
-
- if (kbd->input_device) {
- ds_inf("devices.kbd is already set. name:%s",
- ds_input_device_get_name(kbd->input_device));
- return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
- }
-
- //input_device create
- kbd->input_device = calloc(1, sizeof(struct ds_input_device));
- if(!kbd->input_device) {
- ds_err("Failed to create input device !\n");
- return ret;
- }
-
- ds_input_device_init(kbd->input_device, DS_INPUT_DEVICE_KEYBOARD,
- &input_device_iface, name, -1, -1);
- kbd->input_device->keyboard = create_ds_keyboard();
-
- wl_signal_emit(&tz_devicemgr->backend->events.new_input,
- kbd->input_device);
-
- kbd->created = true;
- strncpy(kbd->name, name, UINPUT_MAX_NAME_SIZE);
-
- wl_list_for_each(client_data, &tz_devicemgr->clients, link) {
- if (client_data->resource == resource) {
- if (client_data->init == false) {
- client_data->init = true;
- tz_devicemgr->ref++;
- }
- break;
- }
- }
-
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
-
- return ret;
-}
-
-static int
-tz_devicemgr_keyname_to_keycode(struct wl_list *list, const char *name)
-{
- struct ds_tizen_input_devicemgr_keymap_data *data;
-
- if (!wl_list_empty(list)) {
- wl_list_for_each(data, list, link) {
- if (!strcmp(data->name, name)) {
- return data->keycode;
- }
- }
- }
-
- return 0;
-}
-
-static bool
-tz_devicemgr_generate_key(struct ds_input_device *device, int keycode,
- int pressed)
-{
- struct ds_event_keyboard_key ds_event;
- struct timeval time;
- unsigned int timestamp;
- struct ds_keyboard *kbd;
-
- kbd = ds_input_device_get_keyboard(device);
- if (!kbd) {
- ds_err("No ds_keyboard to notify event");
- return false;
- }
-
- gettimeofday(&time, NULL);
- timestamp = time.tv_sec * 1000 + time.tv_usec / 1000;
-
- ds_event.time_msec = timestamp;
- ds_event.keycode = keycode - 8;
- if (pressed)
- ds_event.state = WL_KEYBOARD_KEY_STATE_PRESSED;
- else
- ds_event.state = WL_KEYBOARD_KEY_STATE_RELEASED;
-
- ds_inf("Generate key. kbd:%p, key:%d, state:%s", kbd, ds_event.keycode,
- (ds_event.state == WL_KEYBOARD_KEY_STATE_PRESSED) ?
- "PRESSED" : "RELEASED");
-
- ds_keyboard_notify_key(kbd, &ds_event);
-
- return true;
-}
-
-static bool
-tz_devicemgr_pressed_keys_update(struct ds_tizen_input_devicemgr *tz_devicemgr,
- int keycode, bool pressed)
-{
- struct ds_tizen_input_devicemgr_key_info *key, *tmp;
-
- if (pressed) {
- key = calloc(1, sizeof(*key));
- if (!key) {
- ds_err("Failed to alloc keydata memory.\n");
- return false;
- }
- key->keycode = keycode;
- wl_list_init(&key->link);
- wl_list_insert(&tz_devicemgr->pressed_keys, &key->link);
- }
- else {
- wl_list_for_each_safe(key, tmp, &tz_devicemgr->pressed_keys, link) {
- if (key->keycode == keycode) {
- wl_list_remove(&key->link);
- free(key);
- break;
- }
- }
- }
-
- ds_inf("Update pressed keys. length: %d, keycode:%d, pressed:%d",
- wl_list_length(&tz_devicemgr->pressed_keys), keycode, pressed);
-
- return true;
-}
-
-static void
-tz_devicemgr_pressed_keys_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr)
-{
- struct ds_tizen_input_devicemgr_key_info *keydata, *tmp;
-
- ds_inf("Clean up the pressed_keys. length: %d",
- wl_list_length(&tz_devicemgr->pressed_keys));
-
- wl_list_for_each_safe(keydata, tmp, &tz_devicemgr->pressed_keys, link) {
- if (tz_devicemgr->devices.kbd)
- tz_devicemgr_generate_key(tz_devicemgr->devices.kbd->input_device,
- keydata->keycode, false);
- wl_list_remove(&keydata->link);
- free(keydata);
- }
-}
-
-static void
-tz_devicemgr_keymap_list_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr)
-{
- struct ds_tizen_input_devicemgr_keymap_data *keymap, *tmp;
-
- ds_inf("Clean up the keymap_list. length: %d",
- wl_list_length(&tz_devicemgr->keymap_list));
-
- wl_list_for_each_safe(keymap, tmp, &tz_devicemgr->keymap_list, link) {
- free(keymap->name);
- wl_list_remove(&keymap->link);
- free(keymap);
- }
-}
-
-static void
-tz_devicemgr_keyboard_close(struct ds_tizen_input_devicemgr *tz_devicemgr)
-{
- if (!tz_devicemgr->devices.kbd->input_device) return;
- ds_input_device_destroy(tz_devicemgr->devices.kbd->input_device);
- tz_devicemgr->devices.kbd->input_device = NULL;
- tz_devicemgr->devices.kbd->created = false;
-}
-
-static int
-tz_devicemgr_deinit_generator(struct ds_tizen_input_devicemgr *tz_devicemgr,
- struct wl_resource *resource)
-{
- int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
- struct ds_tizen_input_devicemgr_client *client_data;
-
- ds_inf("Deinit generator.");
- wl_list_for_each(client_data, &tz_devicemgr->clients, link) {
- if (client_data->resource == resource) {
- if (client_data->init == true) {
- client_data->init = false;
- tz_devicemgr->ref--;
- if (tz_devicemgr->ref < 0) tz_devicemgr->ref = 0;
- break;
- } else {
- return ret;
- }
- }
- }
-
- if (tz_devicemgr->ref <= 0) {
- tz_devicemgr_pressed_keys_cleanup(tz_devicemgr);
-
- if (!tz_devicemgr->devices.kbd)
- return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
-
- if (tz_devicemgr->devices.kbd->created)
- tz_devicemgr_keyboard_close(tz_devicemgr);
- memset(tz_devicemgr->devices.kbd->name, 0, UINPUT_MAX_NAME_SIZE);
- }
-
- return ret;
-}
-
-static void
-devicemgr_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_inf("devicemgr. keyboard_grab_iface_enter");
-}
-
-static void
-devicemgr_keyboard_grab_iface_clear_focus(struct ds_seat_keyboard_grab *grab)
-{
- ds_inf("devicemgr. keyboard_grab_iface_clear_focus");
-}
-
-static void
-tz_devicemgr_blocked_keys_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr)
-{
- struct ds_tizen_input_devicemgr_key_info *keydata, *tmp;
-
- ds_inf("Clean up the blocked keys. length: %d",
- wl_list_length(&tz_devicemgr->blocked_keys));
-
- wl_list_for_each_safe(keydata, tmp, &tz_devicemgr->blocked_keys, link) {
- wl_list_remove(&keydata->link);
- free(keydata);
- }
-}
-
-static void
-devicemgr_keyboard_grab_iface_key(struct ds_seat_keyboard_grab *grab,
- uint32_t time_msec, uint32_t key, uint32_t state)
-{
- struct ds_tizen_input_devicemgr *devicemgr = grab->data;
- struct ds_tizen_input_devicemgr_key_info *keydata, *tmp;
- bool key_blocked = false;
-
- ds_inf("devicemgr. keyboard_grab_iface_key");
-
- if (!devicemgr->block_resource) {
- if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
- goto finish;
- }
- else {
- wl_list_for_each_safe(keydata, tmp, &devicemgr->blocked_keys, link) {
- if (keydata->keycode == (int)key) {
- wl_list_remove(&keydata->link);
- free(keydata);
- key_blocked = true;
- break;
- }
- }
- if (wl_list_empty(&devicemgr->blocked_keys)) {
- tz_devicemgr_ungrab_keyboard(devicemgr);
- }
- if (key_blocked) {
- goto finish;
- }
- }
- }
-
- if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
- keydata = calloc(1, sizeof (*keydata));
- if (!keydata)
- goto finish;
- keydata->keycode = key;
- wl_list_init(&keydata->link);
- wl_list_insert(&devicemgr->blocked_keys, &keydata->link);
- key_blocked = true;
- }
- else {
- if (wl_list_empty(&devicemgr->blocked_keys))
- goto finish;
- wl_list_for_each_safe(keydata, tmp, &devicemgr->blocked_keys, link) {
- if (keydata->keycode == (int)key) {
- wl_list_remove(&keydata->link);
- free(keydata);
- key_blocked = true;
- }
- }
- }
-
-finish:
- if (!key_blocked)
- ds_inf("block key event: (%d %s)\n", key, (state ? "press" : "release"));
-}
-
-static void
-devicemgr_modifiers_grab_iface_key(struct ds_seat_keyboard_grab *grab,
- struct ds_keyboard_modifiers *modifiers)
-{
- ds_inf("devicemgr. modifiers_grab_iface_key");
-}
-
-static void
-devicemgr_cancel_grab_iface_key(struct ds_seat_keyboard_grab *grab)
-{
- ds_inf("devicemgr. cancel_grab_iface_key");
-}
-
-static const struct ds_keyboard_grab_interface devicemgr_keyboard_grab_iface = {
- .enter = devicemgr_keyboard_grab_iface_enter,
- .clear_focus = devicemgr_keyboard_grab_iface_clear_focus,
- .key = devicemgr_keyboard_grab_iface_key,
- .modifiers = devicemgr_modifiers_grab_iface_key,
- .cancel = devicemgr_cancel_grab_iface_key,
-};
-
-static void
-tz_devicemgr_grab_keyboard(struct ds_tizen_input_devicemgr *tz_devicemgr)
-{
- ds_seat_keyboard_start_grab(tz_devicemgr->seat, tz_devicemgr->grab);
-}
-
-static void
-tz_devicemgr_ungrab_keyboard(struct ds_tizen_input_devicemgr *tz_devicemgr)
-{
- ds_seat_keyboard_end_grab(tz_devicemgr->seat);
-}
-
-static void
-tz_devicemgr_ungrab_keyboard_check(struct ds_tizen_input_devicemgr *tz_devicemgr)
-{
- if (wl_list_empty(&tz_devicemgr->blocked_keys))
- tz_devicemgr_ungrab_keyboard(tz_devicemgr);
-
- tz_devicemgr->block_resource = NULL;
-}
-
-static bool
-devicemgr_add_timer(struct ds_tizen_input_devicemgr *tz_devicemgr,
- wl_event_loop_timer_func_t func, int time)
-{
- struct wl_event_loop *event_loop;
-
- event_loop = wl_display_get_event_loop(tz_devicemgr->backend->display);
- if (!event_loop) {
- ds_err("Failed to get event_loop from display: %p",
- tz_devicemgr->backend->display);
- return false;
- }
-
- tz_devicemgr->timer = wl_event_loop_add_timer(event_loop, func,
- tz_devicemgr);
- if (!tz_devicemgr->timer) {
- ds_err("Failed to timer");
- return false;
- }
- wl_event_source_timer_update(tz_devicemgr->timer, time);
-
- return true;
-}
-
-static int
-devicemgr_block_timer(void *data)
-{
- struct ds_tizen_input_devicemgr *devicemgr = data;
-
- tizen_input_device_manager_send_block_expired(devicemgr->block_resource);
-
- tz_devicemgr_ungrab_keyboard_check(devicemgr);
-
- wl_event_source_remove(devicemgr->timer);
- devicemgr->timer = NULL;
-
- return 1;
-}
-
-static void
-device_manager_handle_block_events(struct wl_client *client,
- struct wl_resource *resource, uint32_t serial, uint32_t clas,
- uint32_t duration)
-{
- struct ds_tizen_input_devicemgr *tz_devicemgr;
- int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
- bool res;
-
- tz_devicemgr = wl_resource_get_user_data(resource);
-
- if (!tz_devicemgr_check_privilege(tz_devicemgr, client,
- TIZEN_PRIV_INPUT_BLOCK)) {
- ds_err("No permission to input generate");
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION;
- goto finish;
- }
-
- if (clas != TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD) {
- ds_err("only support keyboard device. (requested: 0x%x)\n", clas);
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
- goto finish;
- }
-
- if(tz_devicemgr->block_resource) {
- ds_err("currently the input system is already blocked\n");
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
- goto finish;
- }
-
- res = devicemgr_add_timer(tz_devicemgr, devicemgr_block_timer, duration);
- if (!res) {
- ds_err("Failed to add a timer\n");
- goto finish;
- }
-
- tz_devicemgr_grab_keyboard(tz_devicemgr);
- tz_devicemgr->block_resource = resource;
- ds_inf("Block events. clas: %d, duration:%d", clas, duration);
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
-
-finish:
- tizen_input_device_manager_send_error(resource, ret);
-}
-
-static void
-device_manager_handle_unblock_events(struct wl_client *client,
- struct wl_resource *resource, uint32_t serial)
-{
- struct ds_tizen_input_devicemgr *tz_devicemgr;
- int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
-
- tz_devicemgr = wl_resource_get_user_data(resource);
-
- if (!tz_devicemgr_check_privilege(tz_devicemgr, client,
- TIZEN_PRIV_INPUT_BLOCK)) {
- ds_err("No permission to input generate");
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION;
- goto finish;
- }
-
- if (tz_devicemgr->block_resource != resource) {
- ds_err("currently the input system is blocked by another resource");
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
- goto finish;
- }
-
- tz_devicemgr_ungrab_keyboard_check(tz_devicemgr);
- tz_devicemgr->block_resource = NULL;
- ds_inf("Unblock events.");
- ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
-
- if (tz_devicemgr->timer) {
- wl_event_source_remove(tz_devicemgr->timer);
- tz_devicemgr->timer = NULL;
- }
-
-finish:
- tizen_input_device_manager_send_error(resource, ret);
-}
\ No newline at end of file
+++ /dev/null
-#ifndef DS_TIZEN_DEVICEMGR_H
-#define DS_TIZEN_DEVICEMGR_H
-
-#include <stdbool.h>
-#include <linux/uinput.h>
-#include <wayland-server.h>
-#include <tizen-extension-server-protocol.h>
-#include "libds/interfaces/input_device.h"
-#include <libds/seat.h>
-
-struct ds_tizen_input_devicemgr_device {
- char name[UINPUT_MAX_NAME_SIZE + 1];
- struct ds_input_device *input_device;
- bool created;
-};
-
-struct ds_tizen_input_devicemgr {
- struct wl_global *global;
- struct wl_display *display;
- struct ds_backend *backend;
- struct ds_seat *seat;
-
- struct {
- struct wl_signal destroy;
- } events;
-
- struct wl_listener new_input;
- struct wl_listener backend_destroy;
- struct wl_listener seat_destroy;
- struct {
- struct ds_tizen_input_devicemgr_device *kbd;
- struct ds_tizen_input_devicemgr_device *ptr;
- struct ds_tizen_input_devicemgr_device *touch;
- } devices;
-
- struct wl_list clients;
- int ref;
-
- struct wl_list pressed_keys;
- struct wl_list keymap_list;
-
- struct wl_list blocked_keys;
- struct wl_resource *block_resource;
- struct wl_event_source *timer;
- struct ds_seat_keyboard_grab *grab;
-};
-
-struct ds_tizen_input_devicemgr_client {
- struct wl_resource *resource;
- bool init;
- struct wl_list link; // ds_tizen_input_devicemgr::clients
-};
-
-struct ds_tizen_input_devicemgr_key_info {
- int keycode;
- struct wl_list link; // ds_tizen_input_devicemgr::pressed_keys;
-};
-
-#endif
+++ /dev/null
-libds_tizen_input_devicemgr_files = [
- 'input-devicemgr.c',
-]
-
-libds_tizen_input_devicemgr_deps = [
- dep_libds,
- dep_libds_tizen,
- dependency('tizen-extension-server', required: true),
-]
-
-lib_libds_tizen_input_devicemgr = shared_library('ds-tizen-input-devicemgr', libds_tizen_input_devicemgr_files,
- dependencies: libds_tizen_input_devicemgr_deps,
- include_directories: [ common_inc, include_directories('.'), include_directories('..') ],
- version: meson.project_version(),
- install: true
-)
-
-dep_libds_tizen_input_devicemgr = declare_dependency(
- link_with: lib_libds_tizen_input_devicemgr,
- dependencies: libds_tizen_input_devicemgr_deps,
- include_directories: [ common_inc, include_directories('.') ],
-)
-
-pkgconfig = import('pkgconfig')
-pkgconfig.generate(lib_libds_tizen_input_devicemgr,
- version: meson.project_version(),
- filebase: 'libds-tizen-input-devicemgr',
- name: 'libds-tizen-input-devicemgr',
- description: 'tizen input devicemgr extension of libds-tizen for tizen platform',
-)
+++ /dev/null
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#include "libds/log.h"
-#include "libds-tizen/keyrouter.h"
-
-#include "util.h"
-#include "keyrouter.h"
-
-static void
-keyrouter_bind(struct wl_client *client, void *data, uint32_t version,
- uint32_t id);
-static bool
-keyrouter_check_privilege(struct ds_tizen_keyrouter_client *keyrouter_client,
- struct wl_client *client, uint32_t mode, uint32_t keycode);
-static void
-keyrouter_options_set(struct ds_tizen_keyrouter *keyrouter);
-
-static void
-keyrouter_handle_display_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_tizen_keyrouter *keyrouter;
-
- keyrouter = wl_container_of(listener, keyrouter, display_destroy);
-
- ds_inf("Global destroy: ds_tizen_keyrouter(%p)", keyrouter);
-
- wl_signal_emit(&keyrouter->events.destroy, keyrouter);
-
- tizen_security_finish();
-
- free(keyrouter->opts);
-
- wl_list_remove(&keyrouter->display_destroy.link);
-
- wl_global_destroy(keyrouter->global);
-
- keyrouter_grab_destroy(keyrouter->keyrouter_grab);
-
- free(keyrouter);
-}
-
-WL_EXPORT struct ds_tizen_keyrouter *
-ds_tizen_keyrouter_create(struct wl_display *display)
-{
- struct ds_tizen_keyrouter *keyrouter;
-
- keyrouter = calloc(1, sizeof *keyrouter);
- if (!keyrouter) {
- return NULL;
- }
-
- keyrouter->keyrouter_grab = keyrouter_grab_create();
- if (keyrouter->keyrouter_grab == NULL) {
- ds_err("Failed to create keyrouter.");
- free(keyrouter);
- return NULL;
- }
-
- keyrouter->global = wl_global_create(display, &tizen_keyrouter_interface,
- 2, keyrouter, keyrouter_bind);
- if (!keyrouter->global) {
- keyrouter_grab_destroy(keyrouter->keyrouter_grab);
- free(keyrouter);
- return NULL;
- }
-
- wl_list_init(&keyrouter->clients);
-
- wl_signal_init(&keyrouter->events.destroy);
-
- keyrouter->display_destroy.notify = keyrouter_handle_display_destroy;
- wl_display_add_destroy_listener(display, &keyrouter->display_destroy);
-
- keyrouter_options_set(keyrouter);
-
- if (!tizen_security_init()) {
- ds_inf("tizen_security_init() is not sucessful. keyrouter works without security.");
- }
-
- ds_inf("Global created: ds_tizen_keyrouter(%p)", keyrouter);
-
- return keyrouter;
-}
-
-WL_EXPORT void
-ds_tizen_keyrouter_add_destroy_listener(struct ds_tizen_keyrouter *keyrouter,
- struct wl_listener *listener)
-{
- wl_signal_add(&keyrouter->events.destroy, listener);
-}
-
-static void
-keyrouter_handle_keygrab_set(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *surface,
- uint32_t key, uint32_t mode)
-{
- struct ds_tizen_keyrouter_client *keyrouter_client;
- struct ds_tizen_keyrouter *keyrouter;
- int res = TIZEN_KEYROUTER_ERROR_NONE;
- bool ret;
-
- keyrouter_client = wl_resource_get_user_data(resource);
- keyrouter = keyrouter_client->keyrouter;
-
- ret = keyrouter_check_privilege(keyrouter_client, client, mode, key);
- if (ret == false) {
- tizen_keyrouter_send_keygrab_notify(resource, surface,
- key, mode, TIZEN_KEYROUTER_ERROR_NO_PERMISSION);
- return;
- }
-
- res = keyrouter_grab_grab_key(keyrouter->keyrouter_grab,
- mode, key, (void *)client);
- if (res == TIZEN_KEYROUTER_ERROR_NONE && keyrouter_client->grabbed != true)
- keyrouter_client->grabbed = true;
-
- tizen_keyrouter_send_keygrab_notify(resource, surface, key, mode, res);
-}
-
-static void
-keyrouter_handle_keygrab_unset(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *surface, uint32_t key)
-{
- struct ds_tizen_keyrouter_client *keyrouter_client;
- struct ds_tizen_keyrouter *keyrouter;
- int res = TIZEN_KEYROUTER_ERROR_NONE;
- bool ret;
-
- keyrouter_client = wl_resource_get_user_data(resource);
- keyrouter = keyrouter_client->keyrouter;
-
- /* ungrab TOP POSITION grab first, this grab mode is not check privilege */
- keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab,
- TIZEN_KEYROUTER_MODE_TOPMOST, key, (void *)client);
-
- ret = keyrouter_check_privilege(keyrouter_client,
- client, TIZEN_KEYROUTER_MODE_NONE, key);
- if (ret == false) {
- tizen_keyrouter_send_keygrab_notify(resource, surface, key,
- TIZEN_KEYROUTER_MODE_NONE, TIZEN_KEYROUTER_ERROR_NO_PERMISSION);
- return;
- }
-
- keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab,
- TIZEN_KEYROUTER_MODE_EXCLUSIVE, key, (void *)client);
- keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab,
- TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE, key, (void *)client);
- keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab,
- TIZEN_KEYROUTER_MODE_TOPMOST, key, (void *)client);
- keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab,
- TIZEN_KEYROUTER_MODE_SHARED, key, (void *)client);
-
- tizen_keyrouter_send_keygrab_notify(resource, surface, key, TIZEN_KEYROUTER_MODE_NONE, res);
-}
-
-static void
-keyrouter_handle_get_keygrab_status(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *surface, uint32_t key)
-{
- tizen_keyrouter_send_keygrab_notify(resource, surface, key,
- TIZEN_KEYROUTER_MODE_NONE, TIZEN_KEYROUTER_ERROR_NO_PERMISSION);
-}
-
-static int
-keyrouter_get_array_length(const struct wl_array *array)
-{
- int *data = NULL;
- int count = 0;
-
- wl_array_for_each(data, array) {
- count++;
- }
-
- return count;
-}
-
-static void
-keyrouter_handle_keygrab_set_list(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *surface, struct wl_array *grab_list)
-{
- struct ds_tizen_keyrouter_client *keyrouter_client;
- struct ds_tizen_keyrouter *keyrouter;
- struct wl_array *return_list;
- struct ds_tizen_grab_data *grab_data = NULL;
- int res = TIZEN_KEYROUTER_ERROR_NONE;
- bool ret;
-
- keyrouter_client = wl_resource_get_user_data(resource);
- keyrouter = keyrouter_client->keyrouter;
-
- if ((keyrouter_get_array_length(grab_list) % 3) != 0) {
- ds_err("Invalid keycode and grab mode pair. Check arguments in a list.");
- tizen_keyrouter_send_keygrab_notify_list(resource, surface, NULL);
- return;
- }
-
- wl_array_for_each(grab_data, grab_list) {
- ret = keyrouter_check_privilege(keyrouter_client, client, grab_data->mode, grab_data->key);
- if (ret == false) {
- grab_data->err = TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
- } else {
- res = keyrouter_grab_grab_key(keyrouter->keyrouter_grab,
- grab_data->mode, grab_data->key, (void *)client);
- if (res == TIZEN_KEYROUTER_ERROR_NONE && keyrouter_client->grabbed != true)
- keyrouter_client->grabbed = true;
-
- grab_data->err = res;
- }
- }
-
- return_list = grab_list;
-
- tizen_keyrouter_send_keygrab_notify_list(resource, surface, return_list);
-}
-
-static void
-keyrouter_handle_keygrab_unset_list(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *surface,
- struct wl_array *ungrab_list)
-{
- struct ds_tizen_keyrouter_client *keyrouter_client;
- struct ds_tizen_keyrouter *keyrouter;
- struct wl_array *return_list = NULL;
- struct ds_tizen_ungrab_data *ungrab_data = NULL;
- bool ret;
-
- keyrouter_client = wl_resource_get_user_data(resource);
- keyrouter = keyrouter_client->keyrouter;
-
- if ((keyrouter_get_array_length(ungrab_list) % 3) != 0) {
- ds_err("Invalid keycode and grab mode pair. Check arguments in a list.");
- tizen_keyrouter_send_keygrab_notify_list(resource, surface, NULL);
- return;
- }
-
- wl_array_for_each(ungrab_data, ungrab_list) {
- keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab,
- TIZEN_KEYROUTER_MODE_TOPMOST, ungrab_data->key, (void *)client);
-
- ret = keyrouter_check_privilege(keyrouter_client, client,
- TIZEN_KEYROUTER_MODE_TOPMOST, ungrab_data->key);
- if (!ret) {
- ungrab_data->err = TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
- } else {
- keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab,
- TIZEN_KEYROUTER_MODE_EXCLUSIVE, ungrab_data->key, (void *)client);
-
- keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab,
- TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE, ungrab_data->key, (void *)client);
-
- keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab,
- TIZEN_KEYROUTER_MODE_TOPMOST, ungrab_data->key, (void *)client);
-
- keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab,
- TIZEN_KEYROUTER_MODE_SHARED, ungrab_data->key, (void *)client);
-
- ungrab_data->err = TIZEN_KEYROUTER_ERROR_NONE;
- }
- }
-
- return_list = ungrab_list;
-
- tizen_keyrouter_send_keygrab_notify_list(resource, surface, return_list);
-}
-
-static void
-keyrouter_handle_get_keygrab_list(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *surface)
-{
- tizen_keyrouter_send_getgrab_notify_list(resource, surface, NULL);
-}
-
-static void
-keyrouter_handle_set_register_none_key(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *surface,
- uint32_t data)
-{
- tizen_keyrouter_send_set_register_none_key_notify(resource, NULL, 0);
-}
-
-static void
-keyrouter_handle_get_keyregister_status(struct wl_client *client,
- struct wl_resource *resource, uint32_t key)
-{
- tizen_keyrouter_send_keyregister_notify(resource, (int)false);
-}
-
-static void
-keyrouter_handle_set_input_config(struct wl_client *client,
- struct wl_resource *resource, struct wl_resource *surface,
- uint32_t config_mode, uint32_t value)
-{
- tizen_keyrouter_send_set_input_config_notify(resource, (int)false);
-}
-
-static void
-keyrouter_handle_destory(struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy(resource);
-}
-
-static const struct tizen_keyrouter_interface tizen_keyrouter_impl = {
- keyrouter_handle_keygrab_set,
- keyrouter_handle_keygrab_unset,
- keyrouter_handle_get_keygrab_status,
- keyrouter_handle_keygrab_set_list,
- keyrouter_handle_keygrab_unset_list,
- keyrouter_handle_get_keygrab_list,
- keyrouter_handle_set_register_none_key,
- keyrouter_handle_get_keyregister_status,
- keyrouter_handle_set_input_config,
- keyrouter_handle_destory
-};
-
-static void
-keyrouter_handle_resource_destory(struct wl_resource *resource)
-{
- struct ds_tizen_keyrouter_client *keyrouter_client = wl_resource_get_user_data(resource);
-
- wl_list_remove(&keyrouter_client->link);
- free(keyrouter_client);
-}
-
-static void
-keyrouter_bind(struct wl_client *client, void *data, uint32_t version,
- uint32_t id)
-{
- struct ds_tizen_keyrouter *keyrouter = data;
- struct ds_tizen_keyrouter_client *keyrouter_client;
-
- keyrouter_client = calloc(1, sizeof *keyrouter_client);
- if (keyrouter_client == NULL) {
- wl_client_post_no_memory(client);
- return;
- }
-
- keyrouter_client->resource =
- wl_resource_create(client, &tizen_keyrouter_interface, MIN(version, 2), id);
- if (keyrouter_client->resource == NULL) {
- ds_err("wl_resource_create() failed.(version :%d, id:%d)", version, id);
- free(keyrouter_client);
- wl_client_post_no_memory(client);
- return;
- }
-
- wl_resource_set_implementation(keyrouter_client->resource, &tizen_keyrouter_impl,
- keyrouter_client, keyrouter_handle_resource_destory);
-
- wl_list_insert(&keyrouter->clients, &keyrouter_client->link);
-}
-
-static bool
-keyrouter_check_privilege(struct ds_tizen_keyrouter_client *keyrouter_client,
- struct wl_client *client, uint32_t mode, uint32_t keycode)
-{
- struct ds_tizen_keyrouter *keyrouter = keyrouter_client->keyrouter;
-
- pid_t pid = 0;
- uid_t uid = 0;
- gid_t gid = 0;
-
- /* Top position grab is always allowed. This mode do not need privilege.*/
- if (mode == TIZEN_KEYROUTER_MODE_TOPMOST)
- return true;
-
- // check no privilege option on the keycode
- if (keyrouter->opts) {
- if (keyrouter->opts[keycode].no_privilege)
- return true;
- }
-
- // grabbed client is already checked the privilege before.
- if (keyrouter_client->grabbed)
- return true;
-
- wl_client_get_credentials(client, &pid, &uid, &gid);
-
- return tizen_security_check_privilege(pid, uid, "http://tizen.org/privilege/keygrab");
-}
-
-static void
-keyrouter_options_set(struct ds_tizen_keyrouter *keyrouter)
-{
- FILE *file;
- int keycode;
- char *ret, *tmp, *buf_ptr, buf[1024] = {0,};
-
- keyrouter->opts = calloc(KEYROUTER_MAX_KEYS,
- sizeof(struct ds_tizen_keyrouter_key_options));
- if (!keyrouter->opts) {
- return;
- }
-
- file = fopen(KEYLAYOUT_DIR, "r");
- if (!file) {
- ds_err("Failed to open key layout file(%s): (err msg: %m)\n", KEYLAYOUT_DIR);
- free(keyrouter->opts);
- keyrouter->opts = NULL;
- return;
- }
-
- while (!feof(file)) {
- ret = fgets(buf, 1024, file);
- if (!ret) continue;
-
- tmp = strtok_r(buf, " ", &buf_ptr);
- tmp = strtok_r(NULL, " ", &buf_ptr);
- if (!tmp) continue;
- keycode = atoi(tmp);
- if ((0 >= keycode) || (keycode >= KEYROUTER_MAX_KEYS)) {
- ds_err("Currently %d key is invalid to support\n", keycode);
- continue;
- }
-
- keyrouter->opts[keycode].enabled = true;
-
- if (strstr(buf_ptr, "no_priv") != NULL) {
- keyrouter->opts[keycode].no_privilege = true;
- }
- }
-
- fclose(file);
-}
+++ /dev/null
-#ifndef DS_TIZEN_KEYROUTER_H
-#define DS_TIZEN_KEYROUTER_H
-
-#include <stdbool.h>
-#include <wayland-server.h>
-#include <tizen-extension-server-protocol.h>
-
-#define KEYROUTER_MAX_KEYS 512
-
-struct ds_tizen_keyrouter_key_info
-{
- void *data;
- struct wl_list link;
-};
-
-struct ds_tizen_keyrouter_grabbed
-{
- int keycode;
-
- struct {
- struct wl_list excl;
- struct wl_list or_excl;
- struct wl_list top;
- struct wl_list shared;
- } grab;
-
- struct wl_list pressed;
-};
-
-struct ds_tizen_keyrouter_grab
-{
- struct ds_tizen_keyrouter_grabbed *hard_keys;
-
- void *focus_client;
- void *top_client;
-};
-
-struct ds_tizen_keyrouter_key_options
-{
- bool enabled;
- bool no_privilege;
-};
-
-struct ds_tizen_keyrouter
-{
- struct wl_global *global;
-
- struct wl_list clients;
-
- struct wl_listener display_destroy;
-
- struct {
- struct wl_signal destroy;
- } events;
-
- struct ds_tizen_keyrouter_key_options *opts;
-
- struct ds_tizen_keyrouter_grab *keyrouter_grab;
-};
-
-struct ds_tizen_keyrouter_client
-{
- struct ds_tizen_keyrouter *keyrouter;
-
- struct wl_resource *resource;
-
- bool grabbed;
-
- struct wl_list link; // ds_tizen_keyrouter::clients
-};
-
-struct ds_tizen_grab_data
-{
- int key;
- int mode;
- int err;
-};
-
-struct ds_tizen_ungrab_data
-{
- int key;
- int err;
-};
-
-struct ds_tizen_keyrouter_grab *
-keyrouter_grab_create(void);
-void
-keyrouter_grab_destroy(struct ds_tizen_keyrouter_grab *keyrouter_grab);
-int
-keyrouter_grab_grab_key(struct ds_tizen_keyrouter_grab *keyrouter_grab,
- int type, int keycode, void *data);
-void
-keyrouter_grab_ungrab_key(struct ds_tizen_keyrouter_grab *keyrouter_grab,
- int type, int keycode, void *data);
-int
-keyrouter_grab_key_process(struct ds_tizen_keyrouter_grab *keyrouter_grab,
- int keycode, int pressed, struct wl_list *delivery_list);
-void
-keyrouter_grab_set_focus_client(struct ds_tizen_keyrouter_grab *keyrouter_grab,
- void *focus_client);
-void
-keyrouter_grab_set_top_client(struct ds_tizen_keyrouter_grab *keyrouter_grab,
- void *top_client);
-bool
-keyrouter_grab_check_grabbed_key(struct ds_tizen_keyrouter_grab *keyrouter_grab,
- int keycode);
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libds/log.h"
-
-#include "keyrouter.h"
-
-static struct wl_list *
-keyrouter_grab_get_grabbed_list(struct ds_tizen_keyrouter_grab *keyrouter_grab,
- int type, int keycode)
-{
- switch(type) {
- case TIZEN_KEYROUTER_MODE_EXCLUSIVE:
- return &keyrouter_grab->hard_keys[keycode].grab.excl;
- case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE:
- return &keyrouter_grab->hard_keys[keycode].grab.or_excl;
- case TIZEN_KEYROUTER_MODE_TOPMOST:
- return &keyrouter_grab->hard_keys[keycode].grab.top;
- case TIZEN_KEYROUTER_MODE_SHARED:
- return &keyrouter_grab->hard_keys[keycode].grab.shared;
- default:
- return NULL;
- }
-}
-
-bool
-keyrouter_grab_check_grabbed_key(struct ds_tizen_keyrouter_grab *keyrouter_grab, int keycode)
-{
- struct wl_list *list;
-
- list = keyrouter_grab_get_grabbed_list(keyrouter_grab, TIZEN_KEYROUTER_MODE_EXCLUSIVE, keycode);
- if (list && !wl_list_empty(list))
- return true;
-
- list = keyrouter_grab_get_grabbed_list(keyrouter_grab, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE, keycode);
- if (list && !wl_list_empty(list))
- return true;
-
- list = keyrouter_grab_get_grabbed_list(keyrouter_grab, TIZEN_KEYROUTER_MODE_TOPMOST, keycode);
- if (list && !wl_list_empty(list))
- return true;
-
- list = keyrouter_grab_get_grabbed_list(keyrouter_grab, TIZEN_KEYROUTER_MODE_SHARED, keycode);
- if (list && !wl_list_empty(list))
- return true;
-
- return false;
-}
-
-static bool
-keyrouter_grab_check_duplicated_data(struct wl_list *list, void *data)
-{
- struct ds_tizen_keyrouter_key_info *info;
-
- if (wl_list_empty(list))
- return false;
-
- wl_list_for_each(info, list, link) {
- if (info->data == data)
- return true;
- }
-
- return false;
-}
-
-static bool
-keyrouter_grab_check_grabbed(struct ds_tizen_keyrouter_grab *keyrouter_grab,
- int type, int keycode, void *data)
-{
- struct wl_list *list;
- bool ret;
-
- list = keyrouter_grab_get_grabbed_list(keyrouter_grab, type, keycode);
- if (list == NULL) {
- ds_err("keycode(%d) had no list for type(%d).", keycode, type);
- return false;
- }
-
- switch(type) {
- case TIZEN_KEYROUTER_MODE_EXCLUSIVE:
- if (wl_list_empty(list) == false)
- ret = true;
- else
- ret = false;
- break;
- case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE:
- ret = keyrouter_grab_check_duplicated_data(list, data);
- break;
- case TIZEN_KEYROUTER_MODE_TOPMOST:
- ret = keyrouter_grab_check_duplicated_data(list, data);
- break;
- case TIZEN_KEYROUTER_MODE_SHARED:
- ret = keyrouter_grab_check_duplicated_data(list, data);
- break;
- default:
- ret = true;
- break;
- }
-
- return ret;
-}
-
-void
-keyrouter_grab_set_focus_client(struct ds_tizen_keyrouter_grab *keyrouter_grab,
- void *focus_client)
-{
- keyrouter_grab->focus_client = focus_client;
-
- if (focus_client)
- ds_dbg("[%s] focus client has been set. (focus_client=0x%p)", __FUNCTION__, focus_client);
- else
- ds_dbg("[%s] focus client has been set to NULL.", __FUNCTION__);
-}
-
-void
-keyrouter_grab_set_top_client(struct ds_tizen_keyrouter_grab *keyrouter_grab, void *top_client)
-{
- keyrouter_grab->top_client = top_client;
-
- if (top_client)
- ds_dbg("[%s] top client has been set. (top_client=0x%p)", __FUNCTION__, top_client);
- else
- ds_dbg("[%s] top client has been set to NULL.", __FUNCTION__);
-}
-
-int
-keyrouter_grab_key_process(struct ds_tizen_keyrouter_grab *keyrouter_grab,
- int keycode, int pressed, struct wl_list *delivery_list)
-{
- struct ds_tizen_keyrouter_key_info *info, *delivery;
- int count = 0;
-
- if (keycode <= 0 || keycode >= KEYROUTER_MAX_KEYS) {
- ds_err("Invalid keycode(%d)", keycode);
- return 0;
- }
-
- if (!wl_list_empty(&keyrouter_grab->hard_keys[keycode].grab.excl)) {
- info = wl_container_of(keyrouter_grab->hard_keys[keycode].grab.excl.next, info, link);
- if (info) {
- delivery = calloc(1, sizeof(struct ds_tizen_keyrouter_key_info));
- if (delivery == NULL) {
- ds_err("Failed to allocate memory.");
- return 0;
- }
- delivery->data = info->data;
- wl_list_insert(delivery_list, &delivery->link);
- ds_dbg("Exclusive Mode: keycode: %d to data: %p", keycode, info->data);
- return 1;
- }
- } else if (!wl_list_empty(&keyrouter_grab->hard_keys[keycode].grab.or_excl)) {
- info = wl_container_of(keyrouter_grab->hard_keys[keycode].grab.or_excl.next, info, link);
- if (info) {
- delivery = calloc(1, sizeof(struct ds_tizen_keyrouter_key_info));
- if (delivery == NULL) {
- ds_err("Failed to allocate memory.");
- return 0;
- }
- delivery->data = info->data;
- wl_list_insert(delivery_list, &delivery->link);
- ds_dbg("OR-Excl Mode: keycode: %d to data: %p", keycode, info->data);
- return 1;
- }
- } else if (!wl_list_empty(&keyrouter_grab->hard_keys[keycode].grab.top)) {
- wl_list_for_each(info, &keyrouter_grab->hard_keys[keycode].grab.top, link) {
- if (keyrouter_grab->top_client && keyrouter_grab->top_client == info->data) {
- delivery = calloc(1, sizeof(struct ds_tizen_keyrouter_key_info));
- if (delivery == NULL) {
- ds_err("Failed to allocate memory.");
- return 0;
- }
- delivery->data = info->data;
- wl_list_insert(delivery_list, &delivery->link);
- ds_dbg("Topmost Mode: keycode: %d to data: %p", keycode, info->data);
- return 1;
- }
- }
- }
-
- if (keyrouter_grab->focus_client) {
- delivery = calloc(1, sizeof(struct ds_tizen_keyrouter_key_info));
- if (delivery == NULL) {
- ds_err("Failed to allocate memory.");
- return 0;
- }
- delivery->data = keyrouter_grab->focus_client;
- wl_list_insert(delivery_list, &delivery->link);
- count++;
- ds_dbg("Focus: keycode: %d to data: %p, count: %d", keycode, delivery->data, count);
- }
-
- if (!wl_list_empty(&keyrouter_grab->hard_keys[keycode].grab.shared)) {
- wl_list_for_each(info, &keyrouter_grab->hard_keys[keycode].grab.shared, link) {
- if (keyrouter_grab->focus_client && keyrouter_grab->focus_client == info->data)
- continue;
- delivery = calloc(1, sizeof(struct ds_tizen_keyrouter_key_info));
- if (delivery == NULL) {
- ds_err("Failed to allocate memory.");
- return 0;
- }
- delivery->data = info->data;
- wl_list_insert(delivery_list, &delivery->link);
- count++;
- ds_dbg("Shared: keycode: %d to data: %p, count: %d", keycode, info->data, count);
- }
- }
-
- return count;
-}
-
-int
-keyrouter_grab_grab_key(struct ds_tizen_keyrouter_grab *keyrouter_grab,
- int type, int keycode, void *data)
-{
- struct ds_tizen_keyrouter_key_info *info = NULL;
- struct wl_list *list = NULL;
-
- if (keycode <= 0 || keycode >= KEYROUTER_MAX_KEYS) {
- ds_err("Invalid keycode(%d)", keycode);
- return TIZEN_KEYROUTER_ERROR_INVALID_KEY;
- }
-
- if (keyrouter_grab_check_grabbed(keyrouter_grab, type, keycode, data))
- return TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY;
-
- info = calloc(1, sizeof(struct ds_tizen_keyrouter_key_info));
- if (info == NULL) {
- ds_err("Failed to allocate memory.");
- return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES;
- }
- info->data = data;
-
- wl_list_init(&info->link);
-
- list = keyrouter_grab_get_grabbed_list(keyrouter_grab, type, keycode);
- if (!list) {
- ds_err("keycode(%d) had no list for type(%d)", keycode, type);
- free(info);
- return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
- }
-
- if (!keyrouter_grab->hard_keys[keycode].keycode)
- keyrouter_grab->hard_keys[keycode].keycode = keycode;
-
- wl_list_insert(list, &info->link);
-
- return TIZEN_KEYROUTER_ERROR_NONE;
-}
-
-static void
-keyrouter_list_remove_data(struct wl_list *list, void *data)
-{
- struct ds_tizen_keyrouter_key_info *info, *tmp;
-
- if (wl_list_empty(list))
- return;
-
- wl_list_for_each_safe(info ,tmp, list, link) {
- if (info->data == data) {
- wl_list_remove(&info->link);
- free(info);
- }
- }
-}
-
-void
-keyrouter_grab_ungrab_key(struct ds_tizen_keyrouter_grab *keyrouter_grab,
- int type, int keycode, void *data)
-{
- struct wl_list *list;
-
- if (keycode <= 0 || keycode >= KEYROUTER_MAX_KEYS) {
- ds_err("Invalid keycode(%d)", keycode);
- return;
- }
-
- if (keyrouter_grab->hard_keys[keycode].keycode == 0)
- return;
-
- list = keyrouter_grab_get_grabbed_list(keyrouter_grab, type, keycode);
- if (list == NULL) {
- ds_err("keycode(%d) had no list for type(%d)", keycode, type);
- return;
- }
-
- keyrouter_list_remove_data(list, data);
-}
-
-struct ds_tizen_keyrouter_grab *
-keyrouter_grab_create(void)
-{
- struct ds_tizen_keyrouter_grab *keyrouter_grab = NULL;
- int i;
-
- keyrouter_grab = calloc(1, sizeof(struct ds_tizen_keyrouter_grab));
- if (keyrouter_grab == NULL) {
- ds_err("Failed to allocate memory.");
- return NULL;
- }
-
- /* FIXME: Who defined max keycode? */
- keyrouter_grab->hard_keys = calloc(KEYROUTER_MAX_KEYS, sizeof(struct ds_tizen_keyrouter_grabbed));
- if (keyrouter_grab == NULL) {
- ds_err("Failed to allocate memory.");
- free(keyrouter_grab);
- return NULL;
- }
-
- for (i = 0; i < KEYROUTER_MAX_KEYS; i++) {
- /* Enable all of keys to grab */
- //keyrouter_grab->hard_keys[i].keycode = i;
- wl_list_init(&keyrouter_grab->hard_keys[i].grab.excl);
- wl_list_init(&keyrouter_grab->hard_keys[i].grab.or_excl);
- wl_list_init(&keyrouter_grab->hard_keys[i].grab.top);
- wl_list_init(&keyrouter_grab->hard_keys[i].grab.shared);
- wl_list_init(&keyrouter_grab->hard_keys[i].pressed);
- }
-
- return keyrouter_grab;
-}
-
-static void
-keyrouter_grab_delete_list(struct wl_list *list)
-{
- struct ds_tizen_keyrouter_key_info *info, *tmp;
-
- if (wl_list_empty(list))
- return;
-
- wl_list_for_each_safe(info, tmp, list, link) {
- wl_list_remove(&info->link);
- free(info);
- }
-}
-
-void
-keyrouter_grab_destroy(struct ds_tizen_keyrouter_grab *keyrouter_grab)
-{
- int i;
-
- for (i = 0; i < KEYROUTER_MAX_KEYS; i++) {
- keyrouter_grab_delete_list(&keyrouter_grab->hard_keys[i].grab.excl);
- keyrouter_grab_delete_list(&keyrouter_grab->hard_keys[i].grab.or_excl);
- keyrouter_grab_delete_list(&keyrouter_grab->hard_keys[i].grab.top);
- keyrouter_grab_delete_list(&keyrouter_grab->hard_keys[i].grab.shared);
- keyrouter_grab_delete_list(&keyrouter_grab->hard_keys[i].pressed);
- }
-
- free(keyrouter_grab->hard_keys);
- free(keyrouter_grab);
-}
+++ /dev/null
-libds_tizen_keyrouter_files = [
- 'keyrouter_grab.c',
- 'keyrouter.c',
-]
-
-libds_tizen_keyrouter_deps = [
- dep_libds,
- dep_libds_tizen,
- dependency('tizen-extension-server', required: true),
-]
-
-keylayout_dir = get_option('keylayout_dir')
-
-lib_libds_tizen_keyrouter = shared_library('ds-tizen-keyrouter', libds_tizen_keyrouter_files,
- dependencies: libds_tizen_keyrouter_deps,
- include_directories: [ common_inc, include_directories('.'), include_directories('..') ],
- version: meson.project_version(),
- c_args: [ '-DKEYLAYOUT_DIR="@0@"'.format(keylayout_dir) ],
- install: true
-)
-
-dep_libds_tizen_keyrouter = declare_dependency(
- link_with: lib_libds_tizen_keyrouter,
- dependencies: libds_tizen_keyrouter_deps,
- include_directories: [ common_inc, include_directories('.') ],
-)
-
-pkgconfig = import('pkgconfig')
-pkgconfig.generate(lib_libds_tizen_keyrouter,
- version: meson.project_version(),
- filebase: 'libds-tizen-keyrouter',
- name: 'libds-tizen-keyrouter',
- description: 'tizen keyrouter extension of libds-tizen for tizen platform',
-)
\ No newline at end of file
+++ /dev/null
-libds_tizen_files = [
- 'pixel_format.c',
- 'tbm_server.c',
- 'dpms.c',
-]
-
-libds_tizen_deps = [
- dep_libds,
- dependency('libdrm', required: true),
- dependency('libtbm', required: true),
- dependency('wayland-tbm-server', required: true),
- dependency('tizen-dpms-server', required: true),
-]
-
-subdir('allocator')
-subdir('backend')
-subdir('util')
-
-lib_libds_tizen = shared_library('ds-tizen', libds_tizen_files,
- dependencies: libds_tizen_deps,
- include_directories: [ common_inc, include_directories('.') ],
- version: meson.project_version(),
- install: true
-)
-
-dep_libds_tizen = declare_dependency(
- link_with: lib_libds_tizen,
- dependencies: libds_tizen_deps,
- include_directories: [ common_inc, include_directories('.') ],
-)
-
-pkgconfig = import('pkgconfig')
-pkgconfig.generate(lib_libds_tizen,
- version: meson.project_version(),
- filebase: 'libds-tizen',
- name: 'libds-tizen',
- description: 'extension of libds for tizen platform',
-)
-
-subdir('keyrouter')
-subdir('input-devicemgr')
-
+++ /dev/null
-#include <inttypes.h>
-#include <drm_fourcc.h>
-#include <tbm_type.h>
-
-#include "libds/log.h"
-#include "pixel_format.h"
-
-#ifdef ARRAY_LENGTH
-#undef ARRAY_LENGTH
-#endif
-
-#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
-
-struct ds_tbm_format
-{
- uint32_t drm_format;
- uint32_t tbm_format;
-};
-
-static const struct ds_tbm_format formats[] =
-{
- {
- .drm_format = DRM_FORMAT_ARGB8888,
- .tbm_format = TBM_FORMAT_ARGB8888,
- },
- {
- .drm_format = DRM_FORMAT_XRGB8888,
- .tbm_format = TBM_FORMAT_XRGB8888,
- },
- /* TODO more format */
-};
-
-uint32_t
-convert_drm_format_to_tbm(uint32_t fmt)
-{
- size_t i;
-
- for (i = 0; i < ARRAY_LENGTH(formats); i++) {
- if (formats[i].drm_format == fmt)
- return formats[i].tbm_format;
- }
-
- ds_err("DRM format 0x%"PRIX32" has no TBM equivalent", fmt);
-
- return 0;
-}
-
-uint32_t
-convert_tbm_format_to_drm(uint32_t fmt)
-{
- size_t i;
-
- for (i = 0; i < ARRAY_LENGTH(formats); i++) {
- if (formats[i].tbm_format == fmt)
- return formats[i].drm_format;
- }
-
- ds_err("TBM format 0x%"PRIX32" has no DRM equivalent", fmt);
-
- return 0;
-}
+++ /dev/null
-#ifndef DS_TIZEN_PIXEL_FORMAT_H
-#define DS_TIZEN_PIXEL_FORMAT_H
-
-#include <stdint.h>
-
-uint32_t convert_drm_format_to_tbm(uint32_t fmt);
-
-uint32_t convert_tbm_format_to_drm(uint32_t fmt);
-
-#endif
+++ /dev/null
-#include <assert.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#include <tbm_bufmgr.h>
-
-#include "libds/log.h"
-#include "pixel_format.h"
-#include "tbm_server.h"
-
-static const struct ds_buffer_resource_interface tbm_buffer_resource_iface;
-static const struct ds_buffer_interface tbm_client_buffer_iface;
-
-static void tbm_server_handle_display_destroy(struct wl_listener *listener,
- void *data);
-
-WL_EXPORT struct ds_tbm_server *
-ds_tbm_server_create(struct wl_display *display)
-{
- struct ds_tbm_server *tbm;
- tbm_bufmgr bufmgr;
-
- tbm = calloc(1, sizeof *tbm);
- if (!tbm)
- return NULL;
-
- wl_signal_init(&tbm->events.destroy);
-
- tbm->wl_tbm = wayland_tbm_server_init(display, NULL, -1, 0);
- if (!tbm->wl_tbm) {
- goto err_wl_tbm;
- }
-
- bufmgr = wayland_tbm_server_get_bufmgr(tbm->wl_tbm);
- if (!bufmgr) {
- goto err_bind;
- }
-
- if (!tbm_bufmgr_bind_native_display(bufmgr, (void *)display)) {
- goto err_bind;
- }
-
- tbm->display_destroy.notify = tbm_server_handle_display_destroy;
- wl_display_add_destroy_listener(display, &tbm->display_destroy);
-
- ds_buffer_register_resource_interface(&tbm_buffer_resource_iface);
-
- return tbm;
-
-err_bind:
- wayland_tbm_server_deinit(tbm->wl_tbm);
-err_wl_tbm:
- free(tbm);
-
- return NULL;
-}
-
-WL_EXPORT void
-ds_tbm_server_add_destroy_listener(struct ds_tbm_server *tbm,
- struct wl_listener *listener)
-{
- wl_signal_add(&tbm->events.destroy, listener);
-}
-
-WL_EXPORT struct ds_tbm_client_buffer *
-ds_tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer)
-{
- if (ds_buffer->iface != &tbm_client_buffer_iface)
- return NULL;
- return (struct ds_tbm_client_buffer *)ds_buffer;
-}
-
-WL_EXPORT tbm_surface_h
-ds_tbm_client_buffer_get_tbm_surface(struct ds_tbm_client_buffer *buffer)
-{
- if (buffer->base.iface != &tbm_client_buffer_iface)
- return NULL;
- return buffer->surface;
-}
-
-static void
-tbm_server_handle_display_destroy(struct wl_listener *listener, void *data)
-{
- struct ds_tbm_server *tbm;
-
- tbm = wl_container_of(listener, tbm, display_destroy);
-
- wl_signal_emit(&tbm->events.destroy, tbm);
-
- wayland_tbm_server_deinit(tbm->wl_tbm);
- free(tbm);
-}
-
-static void
-tbm_client_buffer_handle_release(struct wl_listener *listener, void *data)
-{
- struct ds_tbm_client_buffer *buffer;
-
- buffer = wl_container_of(listener, buffer, buffer_release);
- if (buffer->resource)
- wl_buffer_send_release(buffer->resource);
-}
-
-static void
-tbm_client_buffer_handle_resource_destroy(struct wl_listener *listener,
- void *data)
-{
- struct ds_tbm_client_buffer *buffer;
-
- buffer = wl_container_of(listener, buffer, resource_destroy);
-
- buffer->resource = NULL;
- buffer->surface = NULL;
- wl_list_remove(&buffer->resource_destroy.link);
- wl_list_init(&buffer->resource_destroy.link);
-
- ds_buffer_drop(&buffer->base);
-}
-
-static struct ds_tbm_client_buffer *
-tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer)
-{
- assert(ds_buffer->iface == &tbm_client_buffer_iface);
- return (struct ds_tbm_client_buffer *)ds_buffer;
-}
-
-static void
-tbm_client_buffer_iface_destroy(struct ds_buffer *ds_buffer)
-{
- struct ds_tbm_client_buffer *buffer;
-
- buffer = tbm_client_buffer_from_buffer(ds_buffer);
-
- ds_inf("Destroy TBM client buffer(%p)", buffer);
-
- wl_list_remove(&buffer->resource_destroy.link);
- wl_list_remove(&buffer->buffer_release.link);
- free(buffer);
-}
-
-static bool
-tbm_client_buffer_iface_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_tbm_client_buffer *buffer;
- tbm_surface_info_s info;
- tbm_bo_access_option op = TBM_OPTION_NONE;
- int err;
-
- buffer = tbm_client_buffer_from_buffer(ds_buffer);
-
- if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ)
- op |= TBM_OPTION_READ;
-
- if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE)
- op |= TBM_OPTION_WRITE;
-
- err = tbm_surface_map(buffer->surface, op, &info);
- if (err != TBM_SURFACE_ERROR_NONE) {
- ds_err("Failed tbm_surface_map()");
- return false;
- }
-
- *format = convert_tbm_format_to_drm(buffer->format);
- *stride = info.planes[0].stride;
- *data = info.planes[0].ptr;
-
- return true;
-}
-
-static void
-tbm_client_buffer_iface_end_ptr_access(struct ds_buffer *ds_buffer)
-{
- struct ds_tbm_client_buffer *buffer;
-
- buffer = tbm_client_buffer_from_buffer(ds_buffer);
-
- tbm_surface_unmap(buffer->surface);
-}
-
-static const struct ds_buffer_interface tbm_client_buffer_iface = {
- .destroy = tbm_client_buffer_iface_destroy,
- .begin_data_ptr_access = tbm_client_buffer_iface_begin_data_ptr_access,
- .end_data_ptr_access = tbm_client_buffer_iface_end_ptr_access,
-};
-
-static struct ds_tbm_client_buffer *
-tbm_client_buffer_create(struct wl_resource *resource)
-{
- struct ds_tbm_client_buffer *buffer;
- tbm_surface_h surface;
- int32_t width, height;
-
- surface = wayland_tbm_server_get_surface(NULL, resource);
- if (!surface) {
- ds_err("Could not get tbm_surface from wl_resource@%d",
- wl_resource_get_id(resource));
- return NULL;
- }
-
- width = tbm_surface_get_width(surface);
- height = tbm_surface_get_height(surface);
-
- buffer = calloc(1, sizeof *buffer);
- if (!buffer)
- return NULL;
-
- ds_buffer_init(&buffer->base, &tbm_client_buffer_iface, width, height);
-
- buffer->resource = resource;
- buffer->surface = surface;
- buffer->format = tbm_surface_get_format(surface);
-
- buffer->buffer_release.notify = tbm_client_buffer_handle_release;
- ds_buffer_add_release_listener(&buffer->base, &buffer->buffer_release);
-
- buffer->resource_destroy.notify =
- tbm_client_buffer_handle_resource_destroy;
- wl_resource_add_destroy_listener(resource, &buffer->resource_destroy);
-
- ds_inf("TBM client buffer(%p) created", buffer);
-
- return buffer;
-}
-
-static struct ds_tbm_client_buffer *
-tbm_client_buffer_get_or_create(struct wl_resource *resource)
-{
- struct ds_tbm_client_buffer *buffer;
- struct wl_listener *resource_destroy_listener;
-
- resource_destroy_listener = wl_resource_get_destroy_listener(resource,
- tbm_client_buffer_handle_resource_destroy);;
- if (resource_destroy_listener) {
- buffer = wl_container_of(resource_destroy_listener,
- buffer, resource_destroy);
- return buffer;
- }
-
- return tbm_client_buffer_create(resource);
-}
-
-static bool
-tbm_buffer_resource_iface_is_instance(struct wl_resource *resource)
-{
- return !!wayland_tbm_server_get_surface(NULL, resource);
-}
-
-static struct ds_buffer *
-tbm_buffer_resource_iface_from_resource(struct wl_resource *resource)
-{
- struct ds_tbm_client_buffer *buffer;
-
- buffer = tbm_client_buffer_get_or_create(resource);
- if (!buffer) {
- ds_err("Could not get or create ds_tbm_client_buffer");
- return NULL;
- }
-
- return &buffer->base;
-}
-
-static const struct ds_buffer_resource_interface tbm_buffer_resource_iface = {
- .name = "tbm",
- .is_instance = tbm_buffer_resource_iface_is_instance,
- .from_resource = tbm_buffer_resource_iface_from_resource,
-};
+++ /dev/null
-#ifndef DS_TIZEN_TBM_SERVER_H
-#define DS_TIZEN_TBM_SERVER_H
-
-#include <wayland-server.h>
-#include <wayland-tbm-server.h>
-#include <tbm_surface.h>
-#include "libds/interfaces/buffer.h"
-
-struct ds_tbm_server
-{
- struct wayland_tbm_server *wl_tbm;
-
- struct wl_listener display_destroy;
-
- struct {
- struct wl_signal destroy;
- } events;
-};
-
-struct ds_tbm_client_buffer
-{
- struct ds_buffer base;
-
- tbm_surface_h surface;
- struct wl_resource *resource;
-
- struct wl_listener buffer_release;
- struct wl_listener resource_destroy;
-
- uint32_t format;
- size_t stride;
-};
-
-#endif
+++ /dev/null
-#ifndef DS_UTIL_H
-#define DS_UTIL_H
-
-#include <unistd.h>
-
-#define MIN(a,b) ((a)<(b)?(a):(b))
-
-bool
-tizen_security_init(void);
-
-void
-tizen_security_finish(void);
-
-bool
-tizen_security_check_privilege(pid_t pid, uid_t uid, const char *privilege);
-
-#endif
+++ /dev/null
-libds_tizen_files += files('security.c')
-libds_tizen_deps += [
- dependency('cynara-client', required: true),
- dependency('cynara-session', required: true),
- dependency('libsmack', required: true)
-]
+++ /dev/null
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdbool.h>
-
-#include <cynara-session.h>
-#include <cynara-client.h>
-#include <cynara-creds-socket.h>
-#include <sys/smack.h>
-
-#include "libds/log.h"
-#include "util.h"
-
-#define CYNARA_BUFSIZE 128
-
-struct ds_cynara
-{
- cynara *handle;
- int references;
-};
-
-static struct ds_cynara ds_cynara;
-
-static bool ds_cynara_init(void);
-static void ds_cynara_finish(void);
-static bool ds_cynara_check_privilege(pid_t pid, uid_t uid,
- const char *privilege);
-
-bool
-tizen_security_check_privilege(pid_t pid, uid_t uid, const char *privilege)
-{
- return ds_cynara_check_privilege(pid, uid, privilege);
-}
-
-bool
-tizen_security_init(void)
-{
- return ds_cynara_init();
-}
-
-void
-tizen_security_finish(void)
-{
- ds_cynara_finish();
-}
-
-static void
-print_cynara_error(int err, const char *fmt, ...)
-{
- int ret;
- va_list args;
- char buf[CYNARA_BUFSIZE] = "\0";
- char tmp[CYNARA_BUFSIZE + CYNARA_BUFSIZE] = "\0";
-
- if (fmt) {
- va_start(args, fmt);
- vsnprintf(tmp, CYNARA_BUFSIZE + CYNARA_BUFSIZE, fmt, args);
- va_end(args);
- }
-
- ret = cynara_strerror(err, buf, CYNARA_BUFSIZE);
- if (ret != CYNARA_API_SUCCESS) {
- ds_err("Failed to get cynara_strerror. error : %d (error log about %s: %d)\n", ret, tmp, err);
- return;
- }
-
- ds_err("%s is failed. (%s)\n", tmp, buf);
-}
-
-static bool
-ds_cynara_init(void)
-{
- int ret = CYNARA_API_SUCCESS;
- int retry_cnt = 0;
-
- if (++ds_cynara.references != 1)
- return true;
-
- for (retry_cnt = 0; retry_cnt < 5; retry_cnt++) {
- ds_dbg("Retry cynara initialize: %d\n", retry_cnt + 1);
-
- ret = cynara_initialize(&ds_cynara.handle, NULL);
-
- if (CYNARA_API_SUCCESS == ret) {
- ds_dbg("Succeed to initialize cynara !\n");
- return true;
- }
-
- print_cynara_error(ret, "cynara_initialize");
- }
-
- ds_err("Failed to initialize cynara! (error:%d, retry_cnt=%d)\n",
- ret, retry_cnt);
-
- --ds_cynara.references;
-
- return false;
-
-}
-
-static void
-ds_cynara_finish(void)
-{
- if (ds_cynara.references < 1) {
- ds_err("%s called without ds_cynara_init\n", __FUNCTION__);
- return;
- }
-
- if (--ds_cynara.references != 0)
- return;
-
- cynara_finish(ds_cynara.handle);
- ds_cynara.handle = NULL;
-}
-
-static bool
-ds_cynara_check_privilege(pid_t pid, uid_t uid, const char *privilege)
-{
- bool res = false;
- char *client_smack = NULL;
- char *client_session = NULL;
- char uid_str[16] = { 0, };
- int len = -1;
- int ret = -1;
-
- if (!ds_cynara.handle) {
- ds_err("ds_cynara has not been initialized.\n");
- return false;
- }
-
- ret = smack_new_label_from_process((int)pid, &client_smack);
- if (ret <= 0)
- goto finish;
-
- snprintf(uid_str, 15, "%d", (int)uid);
-
- client_session = cynara_session_from_pid(pid);
- if (!client_session)
- goto finish;
-
- ret = cynara_check(ds_cynara.handle, client_smack, client_session,
- uid_str, privilege);
-
- if (ret == CYNARA_API_ACCESS_ALLOWED)
- res = true;
- else
- print_cynara_error(ret, "privilege: %s, client_smack: %s, pid: %d",
- privilege, client_smack, pid);
-
-finish:
- ds_dbg("Privilege Check For '%s' %s pid:%u uid:%u client_smack:%s(len:%d) "
- "client_session:%s ret:%d",
- privilege, res ? "SUCCESS" : "FAIL", pid, uid,
- client_smack ? client_smack : "N/A", len,
- client_session ? client_session: "N/A", ret);
-
- if (client_session)
- free(client_session);
-
- if (client_smack)
- free(client_smack);
-
- return res;
-}
)
subdir('libds')
-if get_option('tizen')
- subdir('libds-tizen')
-endif
subdir('tests')
subdir('examples')
subdir('clients')