}
int App::dispatch_events() {
- if (this->pending_events.load(std::memory_order_consume)) {
- this->pending_events.store(false, std::memory_order_release);
- return this->display->dispatch_pending();
+ if (this->dispatch_events() == 0) {
+ return 0;
}
int ret = this->display->dispatch();
}
this->display->flush();
- // execute pending tasks, that is layout changes etc.
- // this->execute_pending();
-
return 0;
}
+int App::dispatch_pending_events() {
+ if (this->pop_pending_events()) {
+ this->display->dispatch_pending();
+ return 0;
+ }
+ return -1;
+}
+
// _ _ _ _ _ ____
// (_)_ __ (_) |_ | | __ _ _ _ ___ _ _| |_ / /\ \
// | | '_ \| | __| | |/ _` | | | |/ _ \| | | | __| | | |
namespace {
+#ifdef WE_LIKE_NOT_TO_USE_THIS
// This can fix the HomeScreen...
void redraw_fix(App *app, std::unique_ptr<genivi::surface> &s, int x, int y,
int w, int h) {
app->display->roundtrip();
}
}
+#endif
} // namespace
// set destination to the display rectangle
s->set_destination_rectangle(x, y, w, h);
- s->set_visibility(0);
- s->set_opacity(256);
-
- this->controller->commit_changes();
- this->display->roundtrip();
-
//redraw_fix(this, s, x, y, w, h);
logdebug("Surface %u now with rect { %d, %d, %d, %d }",
this->state.main = surface_id;
this->state.sub = sub_surface_id;
- this->state.state = LayoutState::LayoutSplit;
+ this->state.s = LayoutState::Split;
// less-than-0 values refer to MAX + 1 - $VALUE
// e.g. MAX is either screen width or height
// set destination to the display rectangle
s->set_destination_rectangle(x, y, w, h);
- s->set_visibility(1);
- s->set_opacity(256);
-
// configure surface to wxh dimensions
ss->set_configuration(w, h);
// set source reactangle, even if we should not need to set it.
// set destination to the display rectangle
ss->set_destination_rectangle(x+x_off, y+y_off, w, h);
- ss->set_visibility(1);
- ss->set_opacity(256);
-
- this->controller->commit_changes();
- this->display->roundtrip();
-
//redraw_fix(this, s, x, y, w, h);
//redraw_fix(this, ss, x+x_off, y+y_off, w, h);
}
char const *App::activate_surface(char const *drawing_name) {
- int surface_id = -1;
+ ST();
+ auto const &surface_id = this->lookup_id(drawing_name);
- {
- auto oid = this->lookup_id(drawing_name);
- if (oid) {
- surface_id = oid.value();
- } else {
- return "Surface does not exist";
- }
+ if (!surface_id) {
+ return "Surface does not exist";
}
- if (!this->controller->surface_exists(surface_id)) {
- return "Surface does not exist";
+ if (!this->controller->surface_exists(*surface_id)) {
+ return "Surface does not exist in controller!";
}
- if (this->state.main == surface_id || this->state.sub == surface_id) {
+ if (this->state.main == *surface_id || this->state.sub == *surface_id) {
return "Surface already active";
}
+ // Special case main_surface
+ if (*surface_id == this->layers.main_surface) {
+ for (auto const &s: this->controller->surfaces) {
+ if (s.second->id != *surface_id) {
+ this->deactivate(s.second->id);
+ }
+ }
+ this->activate(*surface_id);
+ this->state.main = this->state.sub = -1;
+ this->state.s = LayoutState::Single;
+ // commit changes
+ this->controller->commit_changes();
+ this->display->flush();
+ return nullptr;
+ }
+
// This should involve a policy check, but as we do not (yet) have
// such a thing, we will just switch to this surface.
// XXX: input focus missing!!1
- if (this->state != LayoutState{}) {
- switch (this->state.state) {
- case LayoutState::LayoutSingle:
- if (this->can_split(surface_id)) {
- this->surface_set_layout_split(this->state.main, surface_id);
- return nullptr;
- }
- break;
+ if (this->state.main == -1) {
+ this->emit_syncdraw(drawing_name);
- case LayoutState::LayoutSplit:
- if (this->can_split(surface_id)) {
- this->deactivate(this->state.sub);
- this->surface_set_layout_split(this->state.main, surface_id);
- }
+ this->surface_set_layout_full(*surface_id);
+ this->activate(*surface_id);
+ this->state.main = *surface_id;
+ this->state.sub = -1;
+ this->state.s = LayoutState::Single;
- case LayoutState::LayoutNone:
- break;
- }
- }
+ this->emit_flushdraw(drawing_name);
+ } else {
+ bool can_split = this->can_split(*surface_id);
- // Make it visible, no (or little effect) if already visible
- auto &s = this->controller->surfaces[surface_id];
+ if (this->state.sub == -1) {
+ if (can_split) {
+ if (this->state.main != *surface_id) {
+ this->emit_syncdraw(drawing_name);
+ this->emit_syncdraw(this->lookup_name(this->state.main)->c_str());
+
+ this->surface_set_layout_split(this->state.main, *surface_id);
+ this->activate(*surface_id);
+ this->state.sub = *surface_id;
- // Set all others invisible
- for (auto &i : this->controller->surfaces) {
- auto &si = this->controller->sprops[i.second->id];
- if (si.id != s->id && si.visibility != 0 &&
- int(si.id) != this->layers.main_surface) {
- this->deactivate(si.id);
+ // Should wait for EndDraw event...
+ this->emit_flushdraw(drawing_name);
+ this->emit_flushdraw(this->lookup_name(this->state.main)->c_str());
+ }
+ } else {
+ this->emit_syncdraw(drawing_name);
+
+ this->surface_set_layout_full(*surface_id);
+ this->deactivate(this->state.main);
+ this->activate(*surface_id);
+ this->deactivate(this->state.sub);
+ this->state.main = *surface_id;
+ this->state.sub = -1;
+ this->state.s = LayoutState::Single;
+
+ this->emit_flushdraw(drawing_name);
+ }
}
}
- this->activate(s->id);
// commit changes
this->controller->commit_changes();
this->display->flush();
- this->state.main = surface_id;
- this->state.state = LayoutState::LayoutSingle;
-
// no error
return nullptr;
}
char const *App::deactivate_surface(char const *drawing_name) {
- int surface_id = -1;
+ ST();
+ auto const &surface_id = this->lookup_id(drawing_name);
- {
- auto oid = this->lookup_id(drawing_name);
- if (oid) {
- surface_id = oid.value();
- } else {
- return "Surface does not exist";
- }
+ if (!surface_id) {
+ return "Surface does not exist";
}
- if (surface_id == this->layers.main_surface) {
+ if (*surface_id == this->layers.main_surface) {
return "Cannot deactivate main_surface";
}
- switch (this->state.state) {
- case LayoutState::LayoutSplit:
- if (surface_id == this->state.main) {
- this->deactivate(surface_id);
- this->surface_set_layout_full(this->state.main);
-
- this->deactivate(this->state.sub);
- this->surface_set_layout_full(this->state.sub);
+ if (this->state.main == -1) {
+ return "No surface active";
+ }
- this->state.main = -1;
- this->state.sub = -1;
- this->state.state = LayoutState::LayoutSingle;
- } else if (surface_id == this->state.sub) {
- this->deactivate(surface_id);
- this->surface_set_layout_full(this->state.sub);
- this->surface_set_layout_full(this->state.main);
+ if (*surface_id == this->layers.main_surface) {
+ logdebug("Refusing to deactivate main_surface %d", *surface_id);
+ return nullptr;
+ }
- // XXX send syndraw events....
+ if (this->state.main == *surface_id) {
+ if (this->state.sub != -1) {
+ this->emit_syncdraw(this->lookup_name(this->state.sub)->c_str());
- this->state.sub = -1;
- this->state.state = LayoutState::LayoutSingle;
- }
- break;
+ this->deactivate(*surface_id);
+ this->surface_set_layout_full(this->state.sub);
+ this->state.main = this->state.sub;
+ this->state.sub = -1;
+ this->state.s = LayoutState::Single;
- case LayoutState::LayoutSingle:
- this->deactivate(surface_id);
+ this->emit_flushdraw(this->lookup_name(this->state.sub)->c_str());
+ } else {
+ this->deactivate(*surface_id);
this->state.main = -1;
- this->state.sub = -1;
- break;
+ }
+ }else if (this->state.sub == *surface_id) {
+ this->emit_syncdraw(this->lookup_name(this->state.main)->c_str());
- case LayoutState::LayoutNone:
- break;
- }
+ this->deactivate(*surface_id);
+ this->deactivate(*surface_id);
+ this->surface_set_layout_full(this->state.main);
+ this->state.sub = -1;
+ this->state.s = LayoutState::Single;
+ this->emit_flushdraw(this->lookup_name(this->state.main)->c_str());
+ } else {
+ return "Surface is not active";
+ }
this->controller->commit_changes();
this->display->flush();
// | .__/|_| \___/_/\_\_|\___|\__,_| |_____| \_/ \___|_| |_|\__|___/
// |_|
void App::surface_created(uint32_t surface_id) {
- logdebug("surface_id is %u", surface_id);
-
- this->surface_set_layout_full(surface_id);
+ auto layer_id = this->layers.get_layer_id(surface_id);
+ logdebug("surface_id is %u, layer_id is %u", surface_id, layer_id ? *layer_id : -1u);
- this->controller->layers[this->layers.get_layer_id(surface_id).value()]
+ this->controller->layers[*layer_id]
->add_surface(this->controller->surfaces[surface_id].get());
// activate the main_surface right away
this->api.send_event(is_visible ? "visible" : "invisible", label);
}
-void App::emit_invisible(char const *label) { return emit_visible(label, 0); }
+void App::emit_invisible(char const *label) { return emit_visible(label, false); }
-void App::emit_visible(char const *label) { return emit_visible(label, 1); }
+void App::emit_visible(char const *label) { return emit_visible(label, true); }
result<int> App::request_surface(char const *drawing_name) {
auto lid = this->layers.get_layer_id(std::string(drawing_name));
if (!rname) {
// name does not exist yet, allocate surface id...
auto id = int(this->id_alloc.generate_id(drawing_name));
- this->layers.add_surface(id, lid.value());
+ 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.
return Err<int>("Surface already present");
}
-void App::activate(unsigned id) {
+void App::activate(int id) {
if (this->controller->sprops[id].visibility == 0) {
this->controller->surfaces[id]->set_visibility(1);
char const *label =
}
}
-void App::deactivate(unsigned id) {
+void App::deactivate(int id) {
if (this->controller->sprops[id].visibility != 0) {
this->controller->surfaces[id]->set_visibility(0);
char const *label =
}
}
-bool App::can_split(unsigned new_id) {
- if (this->state.state == LayoutState::LayoutSingle) {
+bool App::can_split(int new_id) {
+ if (this->state.main != -1 && this->state.main != new_id) {
auto new_id_layer = this->layers.get_layer_id(new_id).value();
auto current_id_layer =
this->layers.get_layer_id(this->state.main).value();
logdebug("%d sub_match '%s'", new_id_layer, i->sub_match.c_str());
auto res = std::regex(i->sub_match);
if (std::regex_match(new_id_str, res)) {
+ logdebug("layout matched!");
return true;
}
}