1 /*
2 * Copyright 2010-2012 Intel Corporation
3 * Copyright 2013 Raspberry Pi Foundation
4 * Copyright 2011-2012,2020 Collabora, Ltd.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26 /* Helper functions for kiosk-shell */
27
28 /* TODO: These functions are useful to many shells, and, in fact,
29 * much of content in this file was copied from desktop-shell. We should
30 * create a shared shell utility collection to deduplicate this code. */
31
32 #include "util.h"
33 #include "shared/helpers.h"
34 #include <libweston/libweston.h>
35
36 struct weston_output *
get_default_output(struct weston_compositor * compositor)37 get_default_output(struct weston_compositor *compositor)
38 {
39 if (wl_list_empty(&compositor->output_list))
40 return NULL;
41
42 return container_of(compositor->output_list.next,
43 struct weston_output, link);
44 }
45
46 struct weston_output *
get_focused_output(struct weston_compositor * compositor)47 get_focused_output(struct weston_compositor *compositor)
48 {
49 struct weston_seat *seat;
50 struct weston_output *output = NULL;
51
52 wl_list_for_each(seat, &compositor->seat_list, link) {
53 struct weston_touch *touch = weston_seat_get_touch(seat);
54 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
55 struct weston_keyboard *keyboard =
56 weston_seat_get_keyboard(seat);
57
58 /* Priority has touch focus, then pointer and
59 * then keyboard focus. We should probably have
60 * three for loops and check first for touch,
61 * then for pointer, etc. but unless somebody has some
62 * objections, I think this is sufficient. */
63 if (touch && touch->focus)
64 output = touch->focus->output;
65 else if (pointer && pointer->focus)
66 output = pointer->focus->output;
67 else if (keyboard && keyboard->focus)
68 output = keyboard->focus->output;
69
70 if (output)
71 break;
72 }
73
74 return output;
75 }
76
77 /* This is a copy of the same function from desktop-shell.
78 * TODO: Fix this function to take into account nested subsurfaces. */
79 static void
surface_subsurfaces_boundingbox(struct weston_surface * surface,int32_t * x,int32_t * y,int32_t * w,int32_t * h)80 surface_subsurfaces_boundingbox(struct weston_surface *surface, int32_t *x,
81 int32_t *y, int32_t *w, int32_t *h) {
82 pixman_region32_t region;
83 pixman_box32_t *box;
84 struct weston_subsurface *subsurface;
85
86 pixman_region32_init_rect(®ion, 0, 0,
87 surface->width,
88 surface->height);
89
90 wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) {
91 pixman_region32_union_rect(®ion, ®ion,
92 subsurface->position.x,
93 subsurface->position.y,
94 subsurface->surface->width,
95 subsurface->surface->height);
96 }
97
98 box = pixman_region32_extents(®ion);
99 if (x)
100 *x = box->x1;
101 if (y)
102 *y = box->y1;
103 if (w)
104 *w = box->x2 - box->x1;
105 if (h)
106 *h = box->y2 - box->y1;
107
108 pixman_region32_fini(®ion);
109 }
110
111 void
center_on_output(struct weston_view * view,struct weston_output * output)112 center_on_output(struct weston_view *view, struct weston_output *output)
113 {
114 int32_t surf_x, surf_y, width, height;
115 float x, y;
116
117 if (!output) {
118 weston_view_set_position(view, 0, 0);
119 return;
120 }
121
122 surface_subsurfaces_boundingbox(view->surface, &surf_x, &surf_y, &width, &height);
123
124 x = output->x + (output->width - width) / 2 - surf_x / 2;
125 y = output->y + (output->height - height) / 2 - surf_y / 2;
126
127 weston_view_set_position(view, x, y);
128 }
129
130 static void
colored_surface_committed(struct weston_surface * es,int32_t sx,int32_t sy)131 colored_surface_committed(struct weston_surface *es, int32_t sx, int32_t sy)
132 {
133 }
134
135 struct weston_view *
create_colored_surface(struct weston_compositor * compositor,float r,float g,float b,float x,float y,int w,int h)136 create_colored_surface(struct weston_compositor *compositor,
137 float r, float g, float b,
138 float x, float y, int w, int h)
139 {
140 struct weston_surface *surface = NULL;
141 struct weston_view *view;
142
143 surface = weston_surface_create(compositor);
144 if (surface == NULL) {
145 weston_log("no memory\n");
146 return NULL;
147 }
148 view = weston_view_create(surface);
149 if (surface == NULL) {
150 weston_log("no memory\n");
151 weston_surface_destroy(surface);
152 return NULL;
153 }
154
155 surface->committed = colored_surface_committed;
156 surface->committed_private = NULL;
157
158 weston_surface_set_color(surface, r, g, b, 1.0);
159 pixman_region32_fini(&surface->opaque);
160 pixman_region32_init_rect(&surface->opaque, 0, 0, w, h);
161 pixman_region32_fini(&surface->input);
162 pixman_region32_init_rect(&surface->input, 0, 0, w, h);
163
164 weston_surface_set_size(surface, w, h);
165 weston_view_set_position(view, x, y);
166
167 return view;
168 }
169