From be02238a0e92c74a13daaf516b5f379f29217eb8 Mon Sep 17 00:00:00 2001 From: Kazumasa Mitsunari Date: Mon, 23 Oct 2017 18:26:46 +0900 Subject: Modify event notification from broadcast to subscribe model The event notification was implemented using a broadcast model, change it to a subscription model. Bug-AGL: SPEC-987 Change-Id: I344a3a73320eb81c3f670736b032f07400bb8f64 Signed-off-by: Kazumasa Mitsunari --- generate-binding-glue.py | 53 +++++++++++++++++++++++++++++++++--------------- src/app.cpp | 23 ++++++++++++--------- src/app.hpp | 28 ++++++++++++++++++++++++- src/main.cpp | 10 ++++----- 4 files changed, 82 insertions(+), 32 deletions(-) diff --git a/generate-binding-glue.py b/generate-binding-glue.py index dbebbcd..376350a 100644 --- a/generate-binding-glue.py +++ b/generate-binding-glue.py @@ -30,22 +30,41 @@ def p(*args): def emit_func_impl(api, f): args = f.get('args', []) - if len(args) > 0: - p(' json_object *jreq = afb_req_json(req);', '') - for arg in args: - arg['jtype'] = arg.get('jtype', arg['type']) # add jtype default - p(' json_object *j_%(name)s = nullptr;' % arg, - ' if (! json_object_object_get_ex(jreq, "%(name)s", &j_%(name)s)) {' % arg, - ' afb_req_fail(req, "failed", "Need %(type)s argument %(name)s");' % arg, - ' return;', - ' }', - ' %(type)s a_%(name)s = json_object_get_%(jtype)s(j_%(name)s);' % arg, '') - p(' auto ret = %(api)s' % api + '%(name)s(' % f + ', '.join(map(lambda x: 'a_' + x['name'], args)) + ');') - p(' if (ret.is_err()) {', - ' afb_req_fail(req, "failed", ret.unwrap_err());', - ' return;', - ' }', '') - p(' afb_req_success(req, ret.unwrap(), "success");') + func_name = f.get('name', []) + if "wm_subscribe" == func_name: + p(' json_object *jreq = afb_req_json(req);') + p(' json_object *j = nullptr;') + p(' if (! json_object_object_get_ex(jreq, "event", &j)) {') + p(' afb_req_fail(req, "failed", "Need char const* argument event");') + p(' return;') + p(' }') + p(' int event_type = json_object_get_int(j);') + p(' const char *event_name = g_afb_instance->app.kListEventName[event_type];') + p(' struct afb_event event = g_afb_instance->app.map_afb_event[event_name];') + p(' int ret = afb_req_subscribe(req, event);') + p(' if (ret) {', + ' afb_req_fail(req, "failed", "Error: afb_req_subscribe()");', + ' return;', + ' }') + p(' afb_req_success(req, NULL, "success");') + + else: + if len(args) > 0: + p(' json_object *jreq = afb_req_json(req);', '') + for arg in args: + arg['jtype'] = arg.get('jtype', arg['type']) # add jtype default + p(' json_object *j_%(name)s = nullptr;' % arg, + ' if (! json_object_object_get_ex(jreq, "%(name)s", &j_%(name)s)) {' % arg, + ' afb_req_fail(req, "failed", "Need %(type)s argument %(name)s");' % arg, + ' return;', + ' }', + ' %(type)s a_%(name)s = json_object_get_%(jtype)s(j_%(name)s);' % arg, '') + p(' auto ret = %(api)s' % api + '%(name)s(' % f + ', '.join(map(lambda x: 'a_' + x['name'], args)) + ');') + p(' if (ret.is_err()) {', + ' afb_req_fail(req, "failed", ret.unwrap_err());', + ' return;', + ' }', '') + p(' afb_req_success(req, ret.unwrap(), "success");') def emit_func(api, f): p('void %(impl_name)s(afb_req req) noexcept {' % f) @@ -132,6 +151,8 @@ API = { { 'name': 'drawing_name', 'type': 'char const*', 'jtype': 'string' }, ], }, + { 'name': 'wm_subscribe', }, + { 'name': 'list_drawing_names', }, { 'name': 'ping' }, diff --git a/src/app.cpp b/src/app.cpp index f38668f..f4dbba6 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -105,6 +105,11 @@ int App::init() { return -1; } + // Make afb event + for (int i=Event_Val_Min; i<=Event_Val_Max; i++) { + map_afb_event[kListEventName[i]] = afb_daemon_make_event(kListEventName[i]); + } + this->display->add_global_handler( "wl_output", [this](wl_registry *r, uint32_t name, uint32_t v) { this->outputs.emplace_back(std::make_unique(r, name, v)); @@ -118,8 +123,7 @@ int App::init() { // Init controller hooks this->controller->chooks = &this->chooks; - // XXX: This protocol needs the output, so lets just add our mapping - // here... + // This protocol needs the output, so lets just add our mapping here... this->controller->add_proxy_to_id_mapping( this->outputs.back()->proxy.get(), wl_proxy_get_id(reinterpret_cast( @@ -575,23 +579,23 @@ void App::surface_removed(uint32_t surface_id) { } void App::emit_activated(char const *label) { - this->api.send_event("active", label); + this->api.send_event(kListEventName[Event_Active], label); } void App::emit_deactivated(char const *label) { - this->api.send_event("inactive", label); + this->api.send_event(kListEventName[Event_Inactive], label); } void App::emit_syncdraw(char const *label, char const *area) { - this->api.send_event("syncdraw", label, area); + this->api.send_event(kListEventName[Event_SyncDraw], label, area); } void App::emit_flushdraw(char const *label) { - this->api.send_event("flushdraw", label); + this->api.send_event(kListEventName[Event_FlushDraw], label); } void App::emit_visible(char const *label, bool is_visible) { - this->api.send_event(is_visible ? "visible" : "invisible", label); + this->api.send_event(is_visible ? kListEventName[Event_Visible] : kListEventName[Event_Invisible], label); } void App::emit_invisible(char const *label) { @@ -603,7 +607,7 @@ void App::emit_visible(char const *label) { return emit_visible(label, true); } result App::api_request_surface(char const *drawing_name) { auto lid = this->layers.get_layer_id(std::string(drawing_name)); if (!lid) { - // XXX: to we need to put these applications on the App layer? + // TODO: Do we need to put these applications on the App layer? return Err("Drawing name does not match any role"); } @@ -613,8 +617,7 @@ result App::api_request_surface(char const *drawing_name) { auto id = int(this->id_alloc.generate_id(drawing_name)); this->layers.add_surface(id, *lid); - // XXX: we set the main_surface[_name] here and now, - // not sure if we want this, but it worked so far. + // set the main_surface[_name] here and now if (!this->layers.main_surface_name.empty() && this->layers.main_surface_name == drawing_name) { this->layers.main_surface = id; diff --git a/src/app.hpp b/src/app.hpp index ea3e92b..9f8b7ce 100644 --- a/src/app.hpp +++ b/src/app.hpp @@ -93,7 +93,6 @@ struct id_allocator { } // Remove a surface id and name - // I don't think I will need this, do I? void remove_id(std::string const &name) { auto i = this->name2id.find(name); if (i != this->name2id.end()) { @@ -112,6 +111,30 @@ struct id_allocator { }; struct App { + enum EventType { + Event_Val_Min = 0, + + Event_Active = Event_Val_Min, + Event_Inactive, + + Event_Visible, + Event_Invisible, + + Event_SyncDraw, + Event_FlushDraw, + + Event_Val_Max = Event_FlushDraw, + }; + + const std::vector kListEventName{ + "active", + "inactive", + "visible", + "invisible", + "syncdraw", + "flushdraw" + }; + struct binding_api api; struct controller_hooks chooks; @@ -136,6 +159,8 @@ struct App { Policy policy; + std::map map_afb_event; + explicit App(wl::display *d); ~App() = default; @@ -155,6 +180,7 @@ struct App { char const *api_activate_surface(char const *drawing_name, char const *drawing_area); char const *api_deactivate_surface(char const *drawing_name); char const *api_enddraw(char const *drawing_name); + char const *api_subscribe(afb_req *req, char const *event_name); void api_ping(); // Events from the compositor we are interested in diff --git a/src/main.cpp b/src/main.cpp index f33b20e..c90eeb1 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -167,22 +167,22 @@ void binding_api::send_event(char const *evname, char const *label) { json_object *j = json_object_new_object(); json_object_object_add(j, kKeyDrawingName, json_object_new_string(label)); - int ret = afb_daemon_broadcast_event(evname, j); + int ret = afb_event_push(g_afb_instance->app.map_afb_event[evname], j); if (ret != 0) { - logdebug("afb_event_broadcast failed: %m"); + logdebug("afb_event_push failed: %m"); } } void binding_api::send_event(char const *evname, char const *label, char const *area) { - logdebug("%s: %s(%s, %s)", __func__, evname, label, area); + logdebug("%s: %s(%s, %s)", __func__, evname, label, area); json_object *j = json_object_new_object(); json_object_object_add(j, kKeyDrawingName, json_object_new_string(label)); json_object_object_add(j, kKeyDrawingArea, json_object_new_string(area)); - int ret = afb_daemon_broadcast_event(evname, j); + int ret = afb_event_push(g_afb_instance->app.map_afb_event[evname], j); if (ret != 0) { - logdebug("afb_event_broadcast failed: %m"); + logdebug("afb_event_push failed: %m"); } } } // namespace wm -- cgit 1.2.3-korg