summaryrefslogtreecommitdiffstats
path: root/src/layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/layout.c')
-rw-r--r--src/layout.c254
1 files changed, 254 insertions, 0 deletions
diff --git a/src/layout.c b/src/layout.c
new file mode 100644
index 0000000..1088bd5
--- /dev/null
+++ b/src/layout.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright © 2019 Collabora, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "ivi-compositor.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include <libweston-6/compositor.h>
+#include <libweston-6/libweston-desktop.h>
+
+static void
+ivi_background_init(struct ivi_compositor *ivi, struct ivi_output *output)
+{
+ struct weston_output *woutput = output->output;
+ struct ivi_surface *bg = output->background;
+ struct weston_view *view;
+
+ if (!bg) {
+ weston_log("WARNING: Output does not have a background\n");
+ return;
+ }
+
+ assert(bg->role == IVI_SURFACE_ROLE_BACKGROUND);
+
+ view = bg->view;
+
+ weston_view_set_output(view, woutput);
+ weston_view_set_position(view, woutput->x, woutput->y);
+
+ view->is_mapped = true;
+ view->surface->is_mapped = true;
+
+ weston_layer_entry_insert(&ivi->background.view_list, &view->layer_link);
+}
+
+static void
+ivi_panel_init(struct ivi_compositor *ivi, struct ivi_output *output,
+ struct ivi_surface *panel)
+{
+ struct weston_output *woutput = output->output;
+ struct weston_desktop_surface *dsurface;
+ struct weston_view *view;
+ struct weston_geometry geom;
+ int x = woutput->x;
+ int y = woutput->y;
+
+ if (!panel)
+ return;
+
+ assert(panel->role == IVI_SURFACE_ROLE_PANEL);
+ dsurface = panel->dsurface;
+ view = panel->view;
+ geom = weston_desktop_surface_get_geometry(dsurface);
+
+ switch (panel->panel.edge) {
+ case AGL_SHELL_EDGE_TOP:
+ output->area.y += geom.height;
+ output->area.height -= geom.height;
+ break;
+ case AGL_SHELL_EDGE_BOTTOM:
+ y += woutput->height - geom.height;
+ output->area.height -= geom.height;
+ break;
+ case AGL_SHELL_EDGE_LEFT:
+ output->area.x += geom.width;
+ output->area.width -= geom.width;
+ break;
+ case AGL_SHELL_EDGE_RIGHT:
+ x += woutput->width - geom.width;
+ output->area.width -= geom.width;
+ break;
+ }
+
+ x -= geom.x;
+ y -= geom.y;
+
+ weston_view_set_output(view, woutput);
+ weston_view_set_position(view, x, y);
+
+ view->is_mapped = true;
+ view->surface->is_mapped = true;
+
+ weston_layer_entry_insert(&ivi->panel.view_list, &view->layer_link);
+}
+
+/*
+ * Initializes all static parts of the layout, i.e. the background and panels.
+ */
+void
+ivi_layout_init(struct ivi_compositor *ivi, struct ivi_output *output)
+{
+ ivi_background_init(ivi, output);
+
+ output->area.x = 0;
+ output->area.y = 0;
+ output->area.width = output->output->width;
+ output->area.height = output->output->height;
+
+ ivi_panel_init(ivi, output, output->top);
+ ivi_panel_init(ivi, output, output->bottom);
+ ivi_panel_init(ivi, output, output->left);
+ ivi_panel_init(ivi, output, output->right);
+
+ weston_compositor_schedule_repaint(ivi->compositor);
+
+ weston_log("Usable area: %dx%d+%d,%d\n",
+ output->area.width, output->area.height,
+ output->area.x, output->area.y);
+}
+
+static struct ivi_surface *
+ivi_find_app(struct ivi_compositor *ivi, const char *app_id)
+{
+ struct ivi_surface *surf;
+ const char *id;
+
+ wl_list_for_each(surf, &ivi->surfaces, link) {
+ id = weston_desktop_surface_get_app_id(surf->dsurface);
+ if (id && strcmp(app_id, id) == 0)
+ return surf;
+ }
+
+ return NULL;
+}
+
+static void
+ivi_layout_activate_complete(struct ivi_output *output,
+ struct ivi_surface *surf)
+{
+ struct ivi_compositor *ivi = output->ivi;
+ struct weston_output *woutput = output->output;
+ struct weston_view *view = surf->view;
+
+ if (weston_view_is_mapped(view)) {
+ weston_layer_entry_remove(&view->layer_link);
+ }
+
+ weston_view_set_output(view, woutput);
+ weston_view_set_position(view,
+ woutput->x + output->area.x,
+ woutput->y + output->area.y);
+
+ view->is_mapped = true;
+ view->surface->is_mapped = true;
+
+ if (output->active) {
+ output->active->view->is_mapped = false;
+ output->active->view->surface->is_mapped = false;
+
+ weston_layer_entry_remove(&output->active->view->layer_link);
+ }
+ output->active = surf;
+
+ weston_layer_entry_insert(&ivi->normal.view_list, &view->layer_link);
+ weston_view_update_transform(view);
+
+ weston_view_schedule_repaint(view);
+ surf->desktop.pending_output = NULL;
+}
+
+void
+ivi_layout_desktop_committed(struct ivi_surface *surf)
+{
+ struct weston_desktop_surface *dsurf = surf->dsurface;
+ struct weston_geometry geom = weston_desktop_surface_get_geometry(dsurf);
+ struct ivi_output *output;
+
+ assert(surf->role == IVI_SURFACE_ROLE_DESKTOP);
+
+ output = surf->desktop.pending_output;
+ if (!output)
+ return;
+
+ if (!weston_desktop_surface_get_maximized(dsurf) ||
+ geom.width != output->area.width ||
+ geom.height != output->area.height)
+ return;
+
+ ivi_layout_activate_complete(output, surf);
+}
+
+void
+ivi_layout_activate(struct ivi_output *output, const char *app_id)
+{
+ struct ivi_compositor *ivi = output->ivi;
+ struct ivi_surface *surf;
+ struct weston_desktop_surface *dsurf;
+ struct weston_view *view;
+ struct weston_geometry geom;
+
+ surf = ivi_find_app(ivi, app_id);
+ if (!surf)
+ return;
+
+ weston_log("Found app_id %s\n", app_id);
+
+ if (surf == output->active)
+ return;
+
+ dsurf = surf->dsurface;
+ view = surf->view;
+ geom = weston_desktop_surface_get_geometry(dsurf);
+
+ if (weston_desktop_surface_get_maximized(dsurf) &&
+ geom.width == output->area.width &&
+ geom.height == output->area.height) {
+ ivi_layout_activate_complete(output, surf);
+ return;
+ }
+
+ weston_desktop_surface_set_maximized(dsurf, true);
+ weston_desktop_surface_set_size(dsurf,
+ output->area.width,
+ output->area.height);
+
+ /*
+ * If the view isn't mapped, we put it onto the hidden layer so it will
+ * start receiving frame events, and will be able to act on our
+ * configure event.
+ */
+ if (!weston_view_is_mapped(view)) {
+ view->is_mapped = true;
+ view->surface->is_mapped = true;
+
+ weston_view_set_output(view, output->output);
+ weston_layer_entry_insert(&ivi->hidden.view_list, &view->layer_link);
+ weston_view_schedule_repaint(view);
+ }
+
+ surf->desktop.pending_output = output;
+}