From 53cec53f1ab4b74ce91c1f244c72e73a4ff3f14e Mon Sep 17 00:00:00 2001 From: "Junseok, Kim" Date: Thu, 12 Nov 2020 11:17:46 +0900 Subject: [PATCH] dswayland-server: add new interface of input-method Change-Id: Icbfd28f6b77e54930524a1a467e09b4738525493 Signed-off-by: Junseok, Kim --- .../dswayland-server-input-method.cpp | 186 ++++++++++++++++++++- .../dswayland-server-input-method.h | 87 +++++++++- 2 files changed, 267 insertions(+), 6 deletions(-) diff --git a/src/DSWaylandServer/dswayland-server-input-method.cpp b/src/DSWaylandServer/dswayland-server-input-method.cpp index 34fb3e6..b9c41ac 100644 --- a/src/DSWaylandServer/dswayland-server-input-method.cpp +++ b/src/DSWaylandServer/dswayland-server-input-method.cpp @@ -1330,7 +1330,7 @@ namespace DSWaylandServer { } - void wl_input_method::send_show_input_panel(struct ::wl_resource *context) + void wl_input_method::send_show_input_panel(struct ::wl_resource *context, uint32_t degree) { DS_ASSERT_X(m_resource, "wl_input_method::show_input_panel", "Uninitialised resource"); if (DS_UNLIKELY(!m_resource)) { @@ -1339,14 +1339,16 @@ namespace DSWaylandServer { } send_show_input_panel( m_resource->handle, - context); + context, + degree); } - void wl_input_method::send_show_input_panel(struct ::wl_resource *resource, struct ::wl_resource *context) + void wl_input_method::send_show_input_panel(struct ::wl_resource *resource, struct ::wl_resource *context, uint32_t degree) { wl_input_method_send_show_input_panel( resource, - context); + context, + degree); } @@ -1787,6 +1789,182 @@ namespace DSWaylandServer { r, enabled); } + + wl_input_method_manager::wl_input_method_manager(struct ::wl_client *client, uint32_t id, int version) + : m_resource_map() + , m_resource(NULL) + , m_global(NULL) + , m_globalVersion(0) + , m_displayDestroyedListener() + { + init(client, id, version); + } + + wl_input_method_manager::wl_input_method_manager(struct ::wl_display *display, int version) + : m_resource_map() + , m_resource(NULL) + , m_global(NULL) + , m_globalVersion(0) + , m_displayDestroyedListener() + { + init(display, version); + } + + wl_input_method_manager::wl_input_method_manager(struct ::wl_resource *resource) + : m_resource_map() + , m_resource(NULL) + , m_global(NULL) + , m_globalVersion(0) + , m_displayDestroyedListener() + { + init(resource); + } + + wl_input_method_manager::wl_input_method_manager() + : m_resource_map() + , m_resource(NULL) + , m_global(NULL) + , m_globalVersion(0) + , m_displayDestroyedListener() + { + } + + wl_input_method_manager::~wl_input_method_manager() + { + std::multimap::iterator it; + for (it = m_resource_map.begin() ; it != m_resource_map.end() ; it++) { + wl_input_method_manager::Resource *resource = (*it).second; + wl_resource_set_implementation(resource->handle, NULL, NULL, NULL); + } + + if (m_global) { + wl_global_destroy(m_global); + wl_list_remove(&m_displayDestroyedListener.link); + } + } + + void wl_input_method_manager::init(struct ::wl_client *client, uint32_t id, int version) + { + m_resource = bind(client, id, version); + } + + void wl_input_method_manager::init(struct ::wl_resource *resource) + { + m_resource = bind(resource); + } + + wl_input_method_manager::Resource *wl_input_method_manager::add(struct ::wl_client *client, int version) + { + Resource *resource = bind(client, 0, version); + m_resource_map.insert(std::pair(client, resource)); + return resource; + } + + wl_input_method_manager::Resource *wl_input_method_manager::add(struct ::wl_client *client, uint32_t id, int version) + { + Resource *resource = bind(client, id, version); + m_resource_map.insert(std::pair(client, resource)); + return resource; + } + + void wl_input_method_manager::init(struct ::wl_display *display, int version) + { + m_global = wl_global_create(display, &::wl_input_method_manager_interface, version, this, bind_func); + m_globalVersion = version; + m_displayDestroyedListener.notify = wl_input_method_manager::display_destroy_func; + m_displayDestroyedListener.parent = this; + wl_display_add_destroy_listener(display, &m_displayDestroyedListener); + } + + const struct wl_interface *wl_input_method_manager::interface() + { + return &::wl_input_method_manager_interface; + } + + wl_input_method_manager::Resource *wl_input_method_manager::input_method_manager_allocate() + { + return new Resource; + } + + void wl_input_method_manager::input_method_manager_bind_resource(Resource *) + { + } + + void wl_input_method_manager::input_method_manager_destroy_resource(Resource *) + { + } + + void wl_input_method_manager::bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id) + { + wl_input_method_manager *that = static_cast(data); + that->add(client, id, std::min(that->m_globalVersion, version)); + } + + void wl_input_method_manager::display_destroy_func(struct ::wl_listener *listener, void *data) + { + DS_UNUSED(data); + wl_input_method_manager *that = static_cast(listener)->parent; + that->m_global = NULL; + } + + void wl_input_method_manager::destroy_func(struct ::wl_resource *client_resource) + { + Resource *resource = Resource::fromResource(client_resource); + DS_ASSERT(resource); + wl_input_method_manager *that = resource->input_method_manager_object; + that->m_resource_map.erase(resource->client()); + that->input_method_manager_destroy_resource(resource); + delete resource; + } + + wl_input_method_manager::Resource *wl_input_method_manager::bind(struct ::wl_client *client, uint32_t id, int version) + { + DS_ASSERT_X(!wl_client_get_object(client, id), "DSWaylandObject bind", "binding to object %u more than once", id); + struct ::wl_resource *handle = wl_resource_create(client, &::wl_input_method_manager_interface, version, id); + return bind(handle); + } + + wl_input_method_manager::Resource *wl_input_method_manager::bind(struct ::wl_resource *handle) + { + Resource *resource = input_method_manager_allocate(); + resource->input_method_manager_object = this; + + wl_resource_set_implementation(handle, &m_wl_input_method_manager_interface, resource, destroy_func); + resource->handle = handle; + input_method_manager_bind_resource(resource); + return resource; + } + wl_input_method_manager::Resource *wl_input_method_manager::Resource::fromResource(struct ::wl_resource *resource) + { + if (DS_UNLIKELY(!resource)) + return NULL; + if (wl_resource_instance_of(resource, &::wl_input_method_manager_interface, &m_wl_input_method_manager_interface)) + return static_cast(wl_resource_get_user_data(resource)); + return NULL; + } + + const struct ::wl_input_method_manager_interface wl_input_method_manager::m_wl_input_method_manager_interface = { + wl_input_method_manager::handle_set_transient_for + }; + + void wl_input_method_manager::input_method_manager_set_transient_for(Resource *, uint32_t , uint32_t ) + { + } + + + void wl_input_method_manager::handle_set_transient_for( + ::wl_client *client, + struct wl_resource *resource, + uint32_t parent_pid, + uint32_t child_pid) + { + DS_UNUSED(client); + Resource *r = Resource::fromResource(resource); + static_cast(r->input_method_manager_object)->input_method_manager_set_transient_for( + r, + parent_pid, + child_pid); + } } /*LCOV_EXCL_STOP*/ diff --git a/src/DSWaylandServer/dswayland-server-input-method.h b/src/DSWaylandServer/dswayland-server-input-method.h index 56c6844..0f9a071 100644 --- a/src/DSWaylandServer/dswayland-server-input-method.h +++ b/src/DSWaylandServer/dswayland-server-input-method.h @@ -364,8 +364,8 @@ namespace DSWaylandServer { void send_deactivate(struct ::wl_resource *resource, struct ::wl_resource *context, uint32_t focus_out_event); void send_destroy(struct ::wl_resource *context); void send_destroy(struct ::wl_resource *resource, struct ::wl_resource *context); - void send_show_input_panel(struct ::wl_resource *context); - void send_show_input_panel(struct ::wl_resource *resource, struct ::wl_resource *context); + void send_show_input_panel(struct ::wl_resource *context, uint32_t degree); + void send_show_input_panel(struct ::wl_resource *resource, struct ::wl_resource *context, uint32_t degree); void send_hide_input_panel(struct ::wl_resource *context); void send_hide_input_panel(struct ::wl_resource *resource, struct ::wl_resource *context); @@ -582,6 +582,89 @@ namespace DSWaylandServer { }; DisplayDestroyedListener m_displayDestroyedListener; }; + + class wl_input_method_manager + { + public: + wl_input_method_manager(struct ::wl_client *client, uint32_t id, int version); + wl_input_method_manager(struct ::wl_display *display, int version); + wl_input_method_manager(struct ::wl_resource *resource); + wl_input_method_manager(); + + virtual ~wl_input_method_manager(); + + class Resource + { + public: + Resource() : input_method_manager_object(NULL), handle(NULL) {} + virtual ~Resource() {} + + wl_input_method_manager *input_method_manager_object; + wl_input_method_manager *object() { return input_method_manager_object; } + struct ::wl_resource *handle; + + struct ::wl_client *client() const { return wl_resource_get_client(handle); } + int version() const { return wl_resource_get_version(handle); } + + static Resource *fromResource(struct ::wl_resource *resource); + }; + + void init(struct ::wl_client *client, uint32_t id, int version); + void init(struct ::wl_display *display, int version); + void init(struct ::wl_resource *resource); + + Resource *add(struct ::wl_client *client, int version); + Resource *add(struct ::wl_client *client, uint32_t id, int version); + Resource *add(struct wl_list *resource_list, struct ::wl_client *client, uint32_t id, int version); + + Resource *resource() { return m_resource; } + const Resource *resource() const { return m_resource; } + + std::multimap resourceMap() { return m_resource_map; } + const std::multimap resourceMap() const { return m_resource_map; } + + bool isGlobal() const { return m_global != NULL; } + bool isResource() const { return m_resource != NULL; } + + static const struct ::wl_interface *interface(); + static std::string interfaceName() { return interface()->name; } + static int interfaceVersion() { return interface()->version; } + + + protected: + virtual Resource *input_method_manager_allocate(); + + virtual void input_method_manager_bind_resource(Resource *resource); + virtual void input_method_manager_destroy_resource(Resource *resource); + + virtual void input_method_manager_set_transient_for(Resource *resource, uint32_t parent_pid, uint32_t child_pid); + + private: + static void bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id); + static void destroy_func(struct ::wl_resource *client_resource); + static void display_destroy_func(struct ::wl_listener *listener, void *data); + + Resource *bind(struct ::wl_client *client, uint32_t id, int version); + Resource *bind(struct ::wl_resource *handle); + + static const struct ::wl_input_method_manager_interface m_wl_input_method_manager_interface; + + static void handle_set_transient_for( + ::wl_client *client, + struct wl_resource *resource, + uint32_t parent_pid, + uint32_t child_pid); + + std::multimap m_resource_map; + Resource *m_resource; + struct ::wl_global *m_global; + uint32_t m_globalVersion; + struct DisplayDestroyedListener : ::wl_listener { + wl_input_method_manager *parent; + DisplayDestroyedListener(): parent(NULL) {} + }; + DisplayDestroyedListener m_displayDestroyedListener; + }; } #endif -- 2.7.4