2 * Copyright (c) 2014, Intel Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Intel Corporation nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <sys/types.h>
42 #include <murphy/common.h>
44 #include <genivi-shell/ivi-controller-client-protocol.h>
45 #include <genivi-shell/ivi-application-client-protocol.h>
46 #include <ico-uxf-weston-plugin/ico_window_mgr-client-protocol.h>
50 #include "glm-window-manager.h"
53 #include "animation.h"
55 #include "window-manager.h"
58 #define MAX_COORDINATE 16383
60 #define SURFACELESS_TIMEOUT 1000 /* ms */
61 #define CONSTRUCTOR_TIMEOUT 10000 /* ms */
62 #define TITLE_TIMEOUT 1500 /* ms */
64 #define INVALID_INDEX (~(uint32_t)0)
66 #define SURFACE_TO_NODE(s) (((s) >> 16) & 0xFF)
67 #define SURFACE_TO_HOST(s) (((s) >> 24) & 0xFF)
69 #define SURFACE_ID_OUR_FLAG 0x70000000
70 #define SURFACE_ID_MAX 0x00ffffff
75 typedef enum constructor_state_e constructor_state_t;
76 typedef enum match_e match_t;
78 typedef struct ctrl_surface_s ctrl_surface_t;
79 typedef struct ctrl_layer_s ctrl_layer_t;
80 typedef struct ctrl_screen_s ctrl_screen_t;
81 typedef struct app_surface_s app_surface_t;
82 typedef struct application_s application_t;
83 typedef struct ico_extension_s ico_extension_t;
84 typedef struct constructor_s constructor_t;
85 typedef struct screen_layer_iterator_s screen_layer_iterator_t;
86 typedef struct surface_layer_iterator_s surface_layer_iterator_t;
87 typedef struct layer_defaults_s layer_defaults_t;
89 struct mrp_glm_window_manager_s {
90 MRP_WAYLAND_WINDOW_MANAGER_COMMON;
93 mrp_list_hook_t constructors;
99 struct ctrl_surface_s {
101 struct ivi_controller_surface *ctrl_surface;
102 struct wl_surface *wl_surface;
109 int32_t width, height;
110 int32_t requested_x, requested_y;
111 int32_t requested_width, requested_height;
115 mrp_wayland_window_t *win;
121 struct ctrl_layer_s {
123 struct ivi_controller_layer *ctrl_layer;
126 struct wl_array surfaces;
129 struct ctrl_screen_s {
131 struct ivi_controller_screen *ctrl_screen;
133 uint32_t output_index;
134 int32_t width, height;
137 struct app_surface_s {
138 MRP_WAYLAND_OBJECT_COMMON;
141 struct application_s {
142 MRP_WAYLAND_OBJECT_COMMON;
145 struct ico_extension_s {
146 MRP_WAYLAND_OBJECT_COMMON;
149 enum constructor_state_e {
150 CONSTRUCTOR_FAILED = 0, /* handle request failed */
151 CONSTRUCTOR_INCOMPLETE, /* pid is set but title is missing */
152 CONSTRUCTOR_TITLED, /* pid and title set */
153 CONSTRUCTOR_SURFACELESS, /* needs an ivi surface created by us */
154 CONSTRUCTOR_REQUESTED, /* native handle was requested */
155 CONSTRUCTOR_BOUND, /* got native handle and ivi surface created */
158 struct constructor_s {
159 mrp_list_hook_t link;
160 mrp_glm_window_manager_t *wm;
164 struct wl_surface *wl_surface;
165 constructor_state_t state;
167 mrp_timer_t *timeout;
168 mrp_timer_t *surfaceless;
177 struct screen_layer_iterator_s {
178 mrp_glm_window_manager_t *wm;
179 mrp_wayland_output_t *out;
184 struct surface_layer_iterator_s {
185 struct ivi_controller_layer *ctrl_layer;
189 struct layer_defaults_s {
196 static bool window_manager_constructor(mrp_wayland_t *,mrp_wayland_object_t *);
197 static void ctrl_screen_callback(void *, struct ivi_controller *, uint32_t,
198 struct ivi_controller_screen *);
199 static void ctrl_layer_callback(void *, struct ivi_controller *, uint32_t);
200 static void ctrl_surface_callback(void *, struct ivi_controller *, uint32_t,
201 int32_t, const char *);
202 static void ctrl_error_callback(void *, struct ivi_controller *, int32_t,
203 int32_t, int32_t, const char *);
204 static void ctrl_native_handle_callback(void *, struct ivi_controller *,
205 struct wl_surface *);
207 static ctrl_surface_t *surface_create(mrp_glm_window_manager_t *,
208 uint32_t, int32_t, const char *,
209 struct wl_surface *);
210 static void surface_destroy(mrp_glm_window_manager_t *, ctrl_surface_t *);
211 static ctrl_surface_t *surface_find(mrp_glm_window_manager_t *, uint32_t);
213 static void surface_visibility_callback(void*, struct ivi_controller_surface*,
215 static void surface_opacity_callback(void *, struct ivi_controller_surface *,
217 static void surface_source_rectangle_callback(void *,
218 struct ivi_controller_surface *,
219 int32_t,int32_t,int32_t,int32_t);
220 static void surface_destination_rectangle_callback(void *,
221 struct ivi_controller_surface *,
222 int32_t,int32_t, int32_t,int32_t);
223 static void surface_configuration_callback(void *,
224 struct ivi_controller_surface *,
226 static void surface_orientation_callback(void *,
227 struct ivi_controller_surface *,
229 static void surface_pixelformat_callback(void *,
230 struct ivi_controller_surface *,
232 static void surface_added_to_layer_callback(void *,
233 struct ivi_controller_surface *,
234 struct ivi_controller_layer *);
235 static void surface_stats_callback(void *, struct ivi_controller_surface *,
236 uint32_t, uint32_t, uint32_t,
237 uint32_t, const char *);
238 static void surface_destroyed_callback(void *,struct ivi_controller_surface *);
239 static void surface_content_callback(void *, struct ivi_controller_surface *,
241 static void surface_input_focus_callback(void *,
242 struct ivi_controller_surface *,
244 static bool surface_is_ready(mrp_glm_window_manager_t *, ctrl_surface_t *);
245 static void surface_set_title(mrp_glm_window_manager_t *, ctrl_surface_t *,
247 static void surface_titleless(mrp_timer_t *, void *);
250 static ctrl_layer_t *layer_create(mrp_glm_window_manager_t *,
251 mrp_wayland_layer_t *, ctrl_screen_t *);
253 static void layer_destroy(mrp_glm_window_manager_t *, ctrl_layer_t *);
255 static void layer_visibility_callback(void *, struct ivi_controller_layer *,
257 static void layer_opacity_callback(void *, struct ivi_controller_layer *,
259 static void layer_source_rectangle_callback(void *,
260 struct ivi_controller_layer *,
261 int32_t,int32_t, int32_t,int32_t);
262 static void layer_destination_rectangle_callback(void *,
263 struct ivi_controller_layer *,
264 int32_t,int32_t, int32_t,int32_t);
265 static void layer_configuration_callback(void *, struct ivi_controller_layer *,
267 static void layer_orientation_callback(void *, struct ivi_controller_layer *,
269 static void layer_added_to_screen_callback(void*, struct ivi_controller_layer*,
271 static void layer_destroyed_callback(void *, struct ivi_controller_layer *);
272 static bool layer_add_surface_to_top(ctrl_layer_t *, ctrl_surface_t *);
274 static bool layer_add_surface_to_bottom(ctrl_layer_t *, ctrl_surface_t *);
276 static bool layer_move_surface_to_top(ctrl_layer_t *, ctrl_surface_t *);
277 static bool layer_move_surface_to_bottom(ctrl_layer_t *, ctrl_surface_t *);
278 static bool layer_remove_surface(ctrl_layer_t *, ctrl_surface_t *);
279 static void layer_send_surfaces(ctrl_layer_t *);
282 static uint32_t surface_id_generate(void);
283 static bool surface_id_is_ours(uint32_t);
284 static char *surface_id_print(uint32_t, char *, size_t);
286 static bool application_manager_constructor(mrp_wayland_t *,
287 mrp_wayland_object_t *);
288 static void shell_info_callback(void *, struct ivi_application *,
289 int32_t, const char *, uint32_t);
291 static bool ico_extension_constructor(mrp_wayland_t *,mrp_wayland_object_t *);
292 static void ico_extension_window_active_callback(void*,struct ico_window_mgr*,
294 static void ico_extension_map_surface_callback(void *,struct ico_window_mgr *,
295 int32_t, uint32_t, uint32_t,
296 int32_t,int32_t, int32_t,
298 static void ico_extension_update_surface_callback(void *,
299 struct ico_window_mgr *,
304 static void ico_extension_destroy_surface_callback(void *,
305 struct ico_window_mgr *,
309 static constructor_t *constructor_create(mrp_glm_window_manager_t *,
311 int32_t, const char *, uint32_t);
312 static void constructor_destroy(constructor_t *);
313 static void constructor_timeout(mrp_timer_t *, void *);
314 static void constructor_surfaceless(mrp_timer_t *, void *);
315 static constructor_t *constructor_find_first(mrp_glm_window_manager_t *,
317 constructor_state_t);
318 static constructor_t *constructor_find_surface(mrp_glm_window_manager_t *,
319 uint32_t,int32_t,const char *);
322 static constructor_t *constructor_find_bound(mrp_glm_window_manager_t *,
325 static void constructor_set_title(mrp_glm_window_manager_t *,
326 constructor_t *, const char *);
327 static void constructor_issue_next_request(mrp_glm_window_manager_t *);
328 static bool constructor_bind_ivi_surface(mrp_glm_window_manager_t *,
330 static char *constructor_state_str(constructor_state_t);
333 static ctrl_layer_t *layer_find(mrp_glm_window_manager_t *, int32_t);
334 static void layer_request(mrp_wayland_layer_t *,
335 mrp_wayland_layer_update_t *);
338 static void window_request(mrp_wayland_window_t *,
339 mrp_wayland_window_update_t *,
340 mrp_wayland_animation_t *, uint32_t);
343 static void buffer_request(mrp_wayland_window_manager_t *, const char *,
346 static uint32_t sid_hash(const void *);
347 static uint32_t lid_hash(const void *);
348 static uint32_t oid_hash(const void *);
349 static int id_compare(const void *, const void *);
351 static void get_appid(int32_t, char *, int);
353 static layer_defaults_t layer_defaults[MRP_WAYLAND_LAYER_TYPE_MAX] = {
354 /* layer type zorder opacity visibility */
355 /*---------------------------------------------------------------- */
356 [ MRP_WAYLAND_LAYER_TYPE_UNKNOWN ] = { 2, 0.750, HIDDEN },
357 [ MRP_WAYLAND_LAYER_BACKGROUND ] = { 1, 0.000, VISIBLE },
358 [ MRP_WAYLAND_LAYER_APPLICATION ] = { 3, 1.000, HIDDEN, },
359 [ MRP_WAYLAND_LAYER_INPUT ] = { 4, 1.000, HIDDEN },
360 [ MRP_WAYLAND_LAYER_TOUCH ] = { 5, 1.000, HIDDEN },
361 [ MRP_WAYLAND_LAYER_CURSOR ] = { 6, 1.000, HIDDEN },
362 [ MRP_WAYLAND_LAYER_STARTUP ] = { 7, 1.000, HIDDEN },
363 [ MRP_WAYLAND_LAYER_FULLSCREEN ] = { 8, 1.000, HIDDEN },
367 bool mrp_glm_window_manager_register(mrp_wayland_t *wl)
369 mrp_wayland_factory_t factory;
371 factory.size = sizeof(mrp_glm_window_manager_t);
372 factory.interface = &ivi_controller_interface;
373 factory.constructor = window_manager_constructor;
374 factory.destructor = NULL;
375 mrp_wayland_register_interface(wl, &factory);
377 factory.size = sizeof(application_t);
378 factory.interface = &ivi_application_interface;
379 factory.constructor = application_manager_constructor;
380 factory.destructor = NULL;
381 mrp_wayland_register_interface(wl, &factory);
383 factory.size = sizeof(ico_extension_t);
384 factory.interface = &ico_window_mgr_interface;
385 factory.constructor = ico_extension_constructor;
386 factory.destructor = NULL;
387 mrp_wayland_register_interface(wl, &factory);
392 static bool window_manager_constructor(mrp_wayland_t *wl,
393 mrp_wayland_object_t *obj)
395 static struct ivi_controller_listener listener = {
396 .screen = ctrl_screen_callback,
397 .layer = ctrl_layer_callback,
398 .surface = ctrl_surface_callback,
399 .error = ctrl_error_callback,
400 .native_handle = ctrl_native_handle_callback
403 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)obj;
404 mrp_wayland_interface_t *wif;
405 mrp_htbl_config_t scfg, lcfg, ocfg;
409 MRP_ASSERT(wm, "invalid argument");
411 memset(&scfg, 0, sizeof(scfg));
412 scfg.nentry = MRP_WAYLAND_WINDOW_MAX;
413 scfg.comp = id_compare;
414 scfg.hash = sid_hash;
415 scfg.nbucket = MRP_WAYLAND_WINDOW_BUCKETS;
417 memset(&lcfg, 0, sizeof(lcfg));
418 lcfg.nentry = MRP_WAYLAND_LAYER_MAX;
419 lcfg.comp = id_compare;
420 lcfg.hash = lid_hash;
421 lcfg.nbucket = MRP_WAYLAND_LAYER_BUCKETS;
423 memset(&ocfg, 0, sizeof(ocfg));
424 ocfg.nentry = MRP_WAYLAND_OUTPUT_MAX;
425 ocfg.comp = id_compare;
426 ocfg.hash = oid_hash;
427 ocfg.nbucket = MRP_WAYLAND_OUTPUT_BUCKETS;
429 wm->layer_request = layer_request;
430 wm->window_request = window_request;
431 wm->buffer_request = buffer_request;
433 mrp_list_init(&wm->constructors);
435 wm->surfaces = mrp_htbl_create(&scfg);
436 wm->layers = mrp_htbl_create(&lcfg);
437 wm->screens = mrp_htbl_create(&ocfg);
439 MRP_ASSERT(wm->surfaces && wm->layers && wm->screens,
440 "failed to create hash table");
442 sts = ivi_controller_add_listener((struct ivi_controller *)wm->proxy,
448 mrp_wayland_register_window_manager(wl, (mrp_wayland_window_manager_t*)wm);
450 wif = mrp_htbl_lookup(wl->interfaces,
451 (void *)ivi_application_interface.name);
453 if (wif && !mrp_list_empty(&wif->object_list)) {
454 app = mrp_list_entry(wif->object_list.next,
455 application_t, interface_link);
457 mrp_debug("registering application interface to window manager");
465 static int screen_layer_iterator_cb(void *key, void *object, void *user_data)
467 mrp_wayland_layer_t *layer = (mrp_wayland_layer_t *)object;
468 screen_layer_iterator_t *it = (screen_layer_iterator_t *)user_data;
472 if (!strcmp(layer->outputname, it->out->outputname)) {
473 layer_create(it->wm, layer, it->scr);
474 it->need_commit = true;
477 return MRP_HTBL_ITER_MORE;
480 static void ctrl_screen_callback(void *data,
481 struct ivi_controller *ivi_controller,
483 struct ivi_controller_screen *screen)
485 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)data;
487 mrp_wayland_output_t *output;
489 screen_layer_iterator_t it;
491 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
492 MRP_ASSERT(ivi_controller == (struct ivi_controller *)wm->proxy,
493 "confused with data structures");
495 wl = wm->interface->wl;
497 mrp_debug("id_screen=%u screen=%p", id_screen, screen);
499 if (!(output = mrp_wayland_output_find_by_id(wl, id_screen))) {
500 mrp_log_warning("system-controller: can't find output for screen %u",
505 if (!output->name || output->width <= 0 || output->height <= 0) {
506 mrp_log_warning("system-controller: incomplete output (id %u)",
511 if (!(s = mrp_allocz(sizeof(ctrl_screen_t)))) {
512 mrp_log_error("system-controller: can't allocate memory for screen");
517 s->ctrl_screen = screen;
519 s->output_index = output->index;
520 s->width = output->width;
521 s->height = output->height;
526 it.need_commit = false;
527 mrp_htbl_foreach(wl->layers.by_type, screen_layer_iterator_cb, &it);
529 if (it.need_commit) {
530 mrp_debug("calling ivi_controller_commit_changes()");
531 ivi_controller_commit_changes((struct ivi_controller *)wm->proxy);
534 mrp_wayland_flush(wl);
537 static void ctrl_layer_callback(void *data,
538 struct ivi_controller *ivi_controller,
541 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)data;
543 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
544 MRP_ASSERT(ivi_controller == (struct ivi_controller *)wm->proxy,
545 "confused with data structures");
547 mrp_debug("id_layer=%u", id_layer);
550 static void ctrl_surface_callback(void *data,
551 struct ivi_controller *ivi_controller,
556 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)data;
558 struct wl_surface *wl_surface;
561 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
562 MRP_ASSERT(ivi_controller == (struct ivi_controller *)wm->proxy,
563 "confused with data structures");
565 mrp_debug("id_surface=%s pid=%d title='%s'",
566 surface_id_print(id_surface, buf,sizeof(buf)),
567 pid, title ? title:"<null>");
571 if ((c = constructor_find_surface(wm, id_surface, pid, title))) {
574 case CONSTRUCTOR_BOUND:
575 wl_surface = c->wl_surface;
576 /* intentional fall over */
578 case CONSTRUCTOR_TITLED:
579 case CONSTRUCTOR_REQUESTED:
580 if (!title || !title[0])
588 constructor_destroy(c);
591 surface_create(wm, id_surface, pid, title, wl_surface);
595 static void ctrl_error_callback(void *data,
596 struct ivi_controller *ivi_controller,
600 const char *error_text)
602 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)data;
603 const char *type_str;
605 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
606 MRP_ASSERT(ivi_controller == (struct ivi_controller *)wm->proxy,
607 "confused with data structures");
609 switch (object_type) {
610 case IVI_CONTROLLER_OBJECT_TYPE_SURFACE: type_str = "surface"; break;
611 case IVI_CONTROLLER_OBJECT_TYPE_LAYER: type_str = "layer"; break;
612 case IVI_CONTROLLER_OBJECT_TYPE_SCREEN: type_str = "screen"; break;
613 default: type_str = "<unknown>"; break;
619 mrp_debug("%s %d error %d: %s", type_str,object_id, error_code,error_text);
621 switch (object_type) {
623 case IVI_CONTROLLER_OBJECT_TYPE_SURFACE:
624 if (error_code == IVI_CONTROLLER_ERROR_CODE_NATIVE_HANDLE_END) {
625 mrp_debug("native_handle_list end marker");
626 constructor_issue_next_request(wm);
629 mrp_log_error("system-controller: surface error %d: %s",
630 error_code, error_text);
639 static void ctrl_native_handle_callback(void *data,
640 struct ivi_controller *ivi_controller,
641 struct wl_surface *wl_surface)
643 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)data;
645 constructor_t *reqsurf;
647 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
648 MRP_ASSERT(ivi_controller == (struct ivi_controller *)wm->proxy,
649 "confused with data structures");
651 mrp_debug("wl_surface=%p", wl_surface);
653 if (!(app = wm->app)) {
654 mrp_log_error("system-controller: ivi application interface is down "
655 "when %s() is called", __FUNCTION__);
659 reqsurf = constructor_find_first(wm, DOES_MATCH, CONSTRUCTOR_REQUESTED);
662 mrp_debug("no pendig request");
664 /* create an ivi-surface and bind it to wl_surface */
665 reqsurf->id_surface = surface_id_generate();
666 reqsurf->wl_surface = wl_surface;
668 if (constructor_bind_ivi_surface(wm, reqsurf))
669 reqsurf->state = CONSTRUCTOR_BOUND;
674 static ctrl_surface_t *surface_create(mrp_glm_window_manager_t *wm,
678 struct wl_surface *wl_surface)
680 static struct ivi_controller_surface_listener listener = {
681 .visibility = surface_visibility_callback,
682 .opacity = surface_opacity_callback,
683 .source_rectangle = surface_source_rectangle_callback,
684 .destination_rectangle = surface_destination_rectangle_callback,
685 .configuration = surface_configuration_callback,
686 .orientation = surface_orientation_callback,
687 .pixelformat = surface_pixelformat_callback,
688 .layer = surface_added_to_layer_callback,
689 .stats = surface_stats_callback,
690 .destroyed = surface_destroyed_callback,
691 .content = surface_content_callback,
692 .input_focus = surface_input_focus_callback
696 struct ivi_controller *ctrl;
697 struct ivi_controller_surface *ctrl_surface;
702 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
704 wl = wm->interface->wl;
705 ctrl = (struct ivi_controller *)wm->proxy;
707 surface_id_print(id_surface, id_str, sizeof(id_str));
708 get_appid(pid, appid, sizeof(appid));
710 mrp_debug("create surface "
711 "(id=%s pid=%d appid='%s' title='%s' wl_surface=%p)",
712 id_str, pid, appid, title ? title : "<null>", wl_surface);
714 if (surface_find(wm, id_surface)) {
715 mrp_log_error("system-controller: attempt to create multiple times "
716 "surface %s", id_str);
720 if (!(ctrl_surface = ivi_controller_surface_create(ctrl, id_surface))) {
721 mrp_log_error("system-controller: failed to create controller "
722 "surface for surface %s", id_str);
726 mrp_debug("ctrl_surface %p was created for surface %s",
727 ctrl_surface, id_str);
729 if (surface_id_is_ours(id_surface)) {
730 /* The ivi surface was created by us meaning we already had
731 a surfaceless timeout. If title was not set during this
732 time it is pointless to set another timeout to wait for
733 the title. So, we set it to something to prevent furter
739 if (!(sf = mrp_allocz(sizeof(ctrl_surface_t)))) {
740 mrp_log_error("system-controller: failed to allocate memory "
741 "for surface %s", id_str);
746 sf->ctrl_surface = ctrl_surface;
747 sf->wl_surface = wl_surface;
750 sf->appid = mrp_strdup(appid);
751 sf->title = title ? mrp_strdup(title) : NULL;
754 sf->requested_x = MAX_COORDINATE+1;
755 sf->requested_y = MAX_COORDINATE+1;
756 sf->requested_width = -1;
757 sf->requested_height = -1;
761 if (!mrp_htbl_insert(wm->surfaces, &sf->id, sf)) {
762 mrp_log_error("system-controller: hashmap insertion error when "
763 "trying to create surface %s ", id_str);
768 if (ivi_controller_surface_add_listener(ctrl_surface, &listener, sf) < 0) {
769 mrp_log_error("system-controller: failed to create surface %s "
770 "(can't listen to surface)", id_str);
772 mrp_htbl_remove(wm->surfaces, &sf->id, false);
781 sf->timer.title = mrp_add_timer(wl->ml, TITLE_TIMEOUT,
782 surface_titleless, sf);
785 mrp_wayland_flush(wl);
791 static void surface_destroy(mrp_glm_window_manager_t *wm, ctrl_surface_t *sf)
796 if (wm && wm->surfaces && sf) {
797 mrp_debug("surface %s going to be destroyed",
798 surface_id_print(sf->id, buf, sizeof(buf)));
800 if (!(d = mrp_htbl_remove(wm->surfaces, &sf->id, false)) || sf != d) {
801 mrp_log_error("system-controller: confused with data structures "
802 "(surface hashtable entry mismatch)");
805 mrp_del_timer(sf->timer.title);
808 mrp_wayland_window_destroy(sf->win);
817 static ctrl_surface_t *surface_find(mrp_glm_window_manager_t *wm,
822 if (!wm || !wm->surfaces)
825 sf = mrp_htbl_lookup(wm->surfaces, &id_surface);
831 static void surface_visibility_callback(void *data,
832 struct ivi_controller_surface *ctrl_surface,
835 ctrl_surface_t *sf = (ctrl_surface_t *)data;
837 mrp_glm_window_manager_t *wm;
838 mrp_wayland_window_update_t u;
841 MRP_ASSERT(sf && sf->wl, "invalid argument");
842 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
843 "confused with data structures");
846 wm = (mrp_glm_window_manager_t *)wl->wm;
848 MRP_ASSERT(wm, "data inconsitency");
850 mrp_debug("ctrl_surface=%p (id=%s) visibility=%d", ctrl_surface,
851 surface_id_print(sf->id, buf, sizeof(buf)), visibility);
853 sf->visible = visibility ? true : false;
855 if (surface_is_ready(wm, sf)) {
856 memset(&u, 0, sizeof(u));
857 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
858 MRP_WAYLAND_WINDOW_VISIBLE_MASK;
859 u.surfaceid = sf->id;
860 u.visible = sf->visible;
862 mrp_wayland_window_update(sf->win, MRP_WAYLAND_WINDOW_VISIBLE, &u);
866 static void surface_opacity_callback(void *data,
867 struct ivi_controller_surface *ctrl_surface,
870 ctrl_surface_t *sf = (ctrl_surface_t *)data;
872 mrp_glm_window_manager_t *wm;
873 mrp_wayland_window_update_t u;
876 MRP_ASSERT(sf && sf->wl, "invalid argument");
877 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
878 "confused with data structures");
881 wm = (mrp_glm_window_manager_t *)wl->wm;
883 MRP_ASSERT(wm, "data inconsitency");
884 mrp_debug("ctrl_surface=%p (id=%s) opacity=%d", ctrl_surface,
885 surface_id_print(sf->id, buf, sizeof(buf)), opacity);
887 sf->opacity = wl_fixed_to_double(opacity);
889 if (surface_is_ready(wm, sf)) {
890 memset(&u, 0, sizeof(u));
891 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
892 MRP_WAYLAND_WINDOW_OPACITY_MASK;
893 u.surfaceid = sf->id;
894 u.opacity = sf->opacity;
896 mrp_wayland_window_update(sf->win, MRP_WAYLAND_WINDOW_VISIBLE, &u);
900 static void surface_source_rectangle_callback(void *data,
901 struct ivi_controller_surface *ctrl_surface,
907 ctrl_surface_t *sf = (ctrl_surface_t *)data;
909 mrp_glm_window_manager_t *wm;
912 MRP_ASSERT(sf && sf->wl, "invalid argument");
913 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
914 "confused with data structures");
917 wm = (mrp_glm_window_manager_t *)wl->wm;
919 MRP_ASSERT(wm, "data inconsitency");
921 mrp_debug("ctrl_surface=%p (id=%s) x=%d y=%d width=%d height=%d",
922 ctrl_surface, surface_id_print(sf->id, buf, sizeof(buf)),
923 x, y, width, height);
926 static void surface_destination_rectangle_callback(void *data,
927 struct ivi_controller_surface *ctrl_surface,
933 ctrl_surface_t *sf = (ctrl_surface_t *)data;
935 mrp_glm_window_manager_t *wm;
936 mrp_wayland_window_update_t u;
939 MRP_ASSERT(sf && sf->wl, "invalid argument");
940 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
941 "confused with data structures");
944 wm = (mrp_glm_window_manager_t *)wl->wm;
946 MRP_ASSERT(wm, "data inconsitency");
948 mrp_debug("ctrl_surface=%p (id=%s) x=%d y=%d width=%d height=%d",
949 ctrl_surface, surface_id_print(sf->id, buf, sizeof(buf)),
950 x, y, width, height);
957 if (surface_is_ready(wm, sf)) {
959 * system-controller is the sole authority who manages the
960 * destination rectangle. So if a rouge app is is fiddling
961 * with it here we fight back and set it back what it was
964 * A quick series of legitime requests might result extra
965 * wayland messages but hopefully will not end up in a infinite
968 if ((sf->requested_x <= MAX_COORDINATE && x != sf->requested_x ) ||
969 (sf->requested_y <= MAX_COORDINATE && x != sf->requested_y ) ||
970 (sf->requested_width > 0 && width != sf->requested_width ) ||
971 (sf->requested_height > 0 && height != sf->requested_height) )
973 mrp_debug("calling ivi_controller_surface_set_destination_"
974 "rectangle(ivi_controller_surface=%p, x=%d, y=%d, "
975 "width=%d height=%d)", sf->ctrl_surface,
976 sf->requested_x, sf->requested_y,
977 sf->requested_width, sf->requested_height);
979 ivi_controller_surface_set_destination_rectangle(sf->ctrl_surface,
980 sf->requested_x, sf->requested_y,
981 sf->requested_width, sf->requested_height);
984 memset(&u, 0, sizeof(u));
985 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
986 MRP_WAYLAND_WINDOW_POSITION_MASK |
987 MRP_WAYLAND_WINDOW_SIZE_MASK ;
988 u.surfaceid = sf->id;
992 u.height = sf->height;
994 mrp_wayland_window_update(sf->win, MRP_WAYLAND_WINDOW_CONFIGURE, &u);
998 static void surface_configuration_callback(void *data,
999 struct ivi_controller_surface *ctrl_surface,
1003 ctrl_surface_t *sf = (ctrl_surface_t *)data;
1005 mrp_glm_window_manager_t *wm;
1008 MRP_ASSERT(sf && sf->wl, "invalid argument");
1009 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1010 "confused with data structures");
1013 wm = (mrp_glm_window_manager_t *)wl->wm;
1015 MRP_ASSERT(wm, "data inconsitency");
1017 mrp_debug("ctrl_surface=%p (id=%s) width=%d height=%d", ctrl_surface,
1018 surface_id_print(sf->id, buf, sizeof(buf)), width, height);
1021 static void surface_orientation_callback(void *data,
1022 struct ivi_controller_surface *ctrl_surface,
1023 int32_t orientation)
1025 ctrl_surface_t *sf = (ctrl_surface_t *)data;
1027 mrp_glm_window_manager_t *wm;
1030 MRP_ASSERT(sf && sf->wl, "invalid argument");
1031 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1032 "confused with data structures");
1035 wm = (mrp_glm_window_manager_t *)wl->wm;
1037 MRP_ASSERT(wm, "data inconsitency");
1039 mrp_debug("ctrl_surface=%p (id=%s) orientation=%d", ctrl_surface,
1040 surface_id_print(sf->id, buf, sizeof(buf)), orientation);
1043 static void surface_pixelformat_callback(void *data,
1044 struct ivi_controller_surface *ctrl_surface,
1045 int32_t pixelformat)
1047 ctrl_surface_t *sf = (ctrl_surface_t *)data;
1049 mrp_glm_window_manager_t *wm;
1052 MRP_ASSERT(sf && sf->wl, "invalid argument");
1053 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1054 "confused with data structures");
1057 wm = (mrp_glm_window_manager_t *)wl->wm;
1059 MRP_ASSERT(wm, "data inconsitency");
1061 mrp_debug("ctrl_surface=%p (id=%s) pixelformat=%d", ctrl_surface,
1062 surface_id_print(sf->id, buf, sizeof(buf)), pixelformat);
1065 static int surface_layer_iterator_cb(void *key, void *object, void *user_data)
1067 ctrl_layer_t *ly = (ctrl_layer_t *)object;
1068 surface_layer_iterator_t *it = (surface_layer_iterator_t *)user_data;
1072 if (it->ctrl_layer == ly->ctrl_layer) {
1074 return MRP_HTBL_ITER_STOP;
1077 return MRP_HTBL_ITER_MORE;
1080 static void surface_added_to_layer_callback(void *data,
1081 struct ivi_controller_surface *ctrl_surface,
1082 struct ivi_controller_layer *ctrl_layer)
1084 ctrl_surface_t *sf = (ctrl_surface_t *)data;
1086 mrp_glm_window_manager_t *wm;
1087 mrp_wayland_layer_t *layer;
1088 surface_layer_iterator_t it;
1090 mrp_wayland_window_update_t u;
1093 MRP_ASSERT(sf && sf->wl, "invalid argument");
1094 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1095 "confused with data structures");
1098 wm = (mrp_glm_window_manager_t *)wl->wm;
1100 MRP_ASSERT(wm, "data inconsitency");
1102 surface_id_print(sf->id, id_str, sizeof(id_str));
1104 mrp_debug("ctrl_surface=%p (id=%s) ctrl_layer=%p", ctrl_surface,
1105 id_str, ctrl_layer);
1108 /* surface is removed from a layer */
1109 #if 0 /* silently ignore the removal */
1112 return; /* do not send notification of removal for the time being */
1115 /* surface is added/moved to a layer */
1116 memset(&it, 0, sizeof(it));
1117 it.ctrl_layer = ctrl_layer;
1119 mrp_htbl_foreach(wm->layers, surface_layer_iterator_cb, &it);
1121 if (!(ly = it.ly)) {
1122 mrp_log_error("system-controller: can't update layer of surface %s"
1123 "(ctrl_layer not found)", id_str);
1127 if (!(layer = mrp_wayland_layer_find_by_id(wl, ly->id))) {
1128 mrp_log_error("system-controller: can't update layer of surface %s"
1129 "(layer %d not found)", id_str, ly->id);
1133 if (!surface_is_ready(wm, sf)) {
1134 mrp_log_error("system-controller: attempt to update layer "
1135 "of non-ready surface %s", id_str);
1140 memset(&u, 0, sizeof(u));
1141 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK | MRP_WAYLAND_WINDOW_LAYER_MASK;
1142 u.surfaceid = sf->id;
1145 mrp_wayland_window_update(sf->win, MRP_WAYLAND_WINDOW_CONFIGURE, &u);
1148 static void surface_stats_callback(void *data,
1149 struct ivi_controller_surface *ctrl_surface,
1150 uint32_t redraw_count,
1151 uint32_t frame_count,
1152 uint32_t update_count,
1154 const char *process_name)
1156 ctrl_surface_t *sf = (ctrl_surface_t *)data;
1158 mrp_glm_window_manager_t *wm;
1161 MRP_ASSERT(sf && sf->wl, "invalid argument");
1162 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1163 "confused with data structures");
1166 wm = (mrp_glm_window_manager_t *)wl->wm;
1168 MRP_ASSERT(wm, "data inconsitency");
1170 mrp_debug("ctrl_surface=%p (id=%s)"
1171 "redraw_count=%u frame_count=%u update_count=%u "
1172 "pid=%u process_name='%s'",
1173 ctrl_surface, surface_id_print(sf->id, buf, sizeof(buf)),
1174 redraw_count, frame_count, update_count, pid,
1175 process_name ? process_name : "<null>");
1177 if (sf->pid != (int32_t)pid) {
1178 mrp_debug("confused with data structures (mismatching pids)");
1184 static void surface_destroyed_callback(void *data,
1185 struct ivi_controller_surface *ctrl_surface)
1187 ctrl_surface_t *sf = (ctrl_surface_t *)data;
1189 mrp_glm_window_manager_t *wm;
1193 MRP_ASSERT(sf && sf->wl, "invalid argument");
1194 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1195 "confused with data structures");
1198 wm = (mrp_glm_window_manager_t *)wl->wm;
1200 MRP_ASSERT(wm, "data inconsitency");
1202 mrp_debug("ctrl_surface=%p (id=%s)", ctrl_surface,
1203 surface_id_print(sf->id, buf, sizeof(buf)));
1205 if (sf->layerid >= 0 && (ly = layer_find(wm, sf->layerid))) {
1206 layer_remove_surface(ly, sf);
1208 mrp_debug("calling ivi_controller_commit_changes()");
1209 ivi_controller_commit_changes((struct ivi_controller *)wm->proxy);
1211 mrp_wayland_flush(wl);
1214 surface_destroy(wm, sf);
1217 static void surface_content_callback(void *data,
1218 struct ivi_controller_surface *ctrl_surface,
1219 int32_t content_state)
1221 ctrl_surface_t *sf = (ctrl_surface_t *)data;
1223 mrp_glm_window_manager_t *wm;
1226 MRP_ASSERT(sf && sf->wl, "invalid argument");
1227 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1228 "confused with data structures");
1231 wm = (mrp_glm_window_manager_t *)wl->wm;
1233 MRP_ASSERT(wm, "data inconsitency");
1235 mrp_debug("ctrl_surface=%p (id=%s) content_state=%d", ctrl_surface,
1236 surface_id_print(sf->id, buf, sizeof(buf)), content_state);
1240 static void surface_input_focus_callback(void *data,
1241 struct ivi_controller_surface *ctrl_surface,
1245 ctrl_surface_t *sf = (ctrl_surface_t *)data;
1247 mrp_glm_window_manager_t *wm;
1250 MRP_ASSERT(sf && sf->wl, "invalid argument");
1251 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1252 "confused with data structures");
1255 wm = (mrp_glm_window_manager_t *)wl->wm;
1257 MRP_ASSERT(wm, "data inconsitency");
1259 mrp_debug("ctrl_surface=%p (id=%s) device=%u enabled=%d", ctrl_surface,
1260 surface_id_print(sf->id, buf, sizeof(buf)), device, enabled);
1263 static bool surface_is_ready(mrp_glm_window_manager_t *wm, ctrl_surface_t *sf)
1266 mrp_wayland_window_update_t u;
1269 ready = sf->win ? true : false;
1271 if (!ready && wm->interface && wm->interface->wl) {
1272 wl = wm->interface->wl;
1281 memset(&u, 0, sizeof(u));
1282 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
1283 MRP_WAYLAND_WINDOW_NAME_MASK |
1284 MRP_WAYLAND_WINDOW_APPID_MASK |
1285 MRP_WAYLAND_WINDOW_PID_MASK |
1286 MRP_WAYLAND_WINDOW_NODEID_MASK |
1287 MRP_WAYLAND_WINDOW_POSITION_MASK |
1288 MRP_WAYLAND_WINDOW_SIZE_MASK ;
1289 u.surfaceid = sf->id;
1291 u.appid = sf->appid;
1293 u.nodeid = sf->nodeid;
1296 u.width = sf->width;
1297 u.height = sf->height;
1299 sf->win = mrp_wayland_window_create(wl, &u);
1301 if (sf->visible || sf->opacity >= 0) {
1302 memset(&u, 0, sizeof(u));
1303 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK;
1304 u.surfaceid = sf->id;
1307 u.mask |= MRP_WAYLAND_WINDOW_VISIBLE_MASK;
1308 u.visible = sf->visible;
1311 if (sf->opacity >= 0) {
1312 u.mask |= MRP_WAYLAND_WINDOW_OPACITY_MASK;
1313 u.opacity = sf->opacity;
1316 mrp_wayland_window_update(sf->win, MRP_WAYLAND_WINDOW_VISIBLE,
1325 static void surface_set_title(mrp_glm_window_manager_t *wm,
1329 mrp_wayland_window_update_t u;
1331 mrp_debug("title='%s'", title);
1333 mrp_del_timer(sf->timer.title);
1334 sf->timer.title = NULL;
1336 if (sf->title && !strcmp(title, sf->title))
1337 mrp_debug("nothing to do (same title)");
1339 mrp_free(sf->title);
1340 sf->title = mrp_strdup(title ? title : "");
1342 if (surface_is_ready(wm, sf)) {
1343 memset(&u, 0, sizeof(u));
1344 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
1345 MRP_WAYLAND_WINDOW_NAME_MASK;
1346 u.surfaceid = sf->id;
1349 mrp_wayland_window_update(sf->win,MRP_WAYLAND_WINDOW_NAMECHANGE,&u);
1354 static void surface_titleless(mrp_timer_t *timer, void *user_data)
1356 ctrl_surface_t *sf = (ctrl_surface_t *)user_data;
1357 mrp_glm_window_manager_t *wm;
1359 MRP_ASSERT(timer && sf && sf->wl && sf->wl->wm, "invalid argument");
1360 MRP_ASSERT(timer == sf->timer.title, "confused with data structures");
1362 wm = (mrp_glm_window_manager_t *)sf->wl->wm;
1364 mrp_debug("id=%u pid=%d appid='%s'", sf->id, sf->pid, sf->appid);
1366 mrp_del_timer(sf->timer.title);
1367 sf->timer.title = NULL;
1369 surface_set_title(wm, sf, "");
1373 static ctrl_layer_t *layer_create(mrp_glm_window_manager_t *wm,
1374 mrp_wayland_layer_t *layer,
1377 static struct ivi_controller_layer_listener listener = {
1378 .visibility = layer_visibility_callback,
1379 .opacity = layer_opacity_callback,
1380 .source_rectangle = layer_source_rectangle_callback,
1381 .destination_rectangle = layer_destination_rectangle_callback,
1382 .configuration = layer_configuration_callback,
1383 .orientation = layer_orientation_callback,
1384 .screen = layer_added_to_screen_callback,
1385 .destroyed = layer_destroyed_callback
1388 struct ivi_controller_layer *ctrl_layer;
1390 layer_defaults_t *def;
1393 mrp_debug("create and link layer %s (id=0x%08x size=%dx%d) to screen %d",
1394 layer->name, layer->layerid, s->width, s->height, s->id);
1396 ctrl_layer = ivi_controller_layer_create((struct ivi_controller*)wm->proxy,
1398 s->width, s->height);
1400 mrp_log_error("system-controller: can't create controller layer for "
1401 "%s layer (0x%08x)", layer->name, layer->layerid);
1405 if (layer->type < 0 || layer->type >= MRP_WAYLAND_LAYER_TYPE_MAX)
1406 def = layer_defaults;
1408 def = layer_defaults + layer->type;
1410 if (!(ly = mrp_allocz(sizeof(ctrl_layer_t)))) {
1411 mrp_log_error("system-controller: can't allocate memory for layer "
1412 "%s (0x%08x)", layer->name, layer->layerid);
1417 ly->ctrl_layer = ctrl_layer;
1418 ly->id = layer->layerid;
1419 ly->name = mrp_strdup(layer->name);
1421 if (!mrp_htbl_insert(wm->layers, &ly->id, ly)) {
1422 mrp_log_error("system-controller: failed to instantiate layer %s "
1423 "(0x%08x): already exists", layer->name, layer->layerid);
1428 if (ivi_controller_layer_add_listener(ctrl_layer, &listener, ly) < 0) {
1429 mrp_debug("can't listen to layer %s (0x%08x)",
1430 layer->name, layer->layerid);
1431 mrp_htbl_remove(wm->layers, &ly->id, false);
1436 ivi_controller_screen_add_layer(s->ctrl_screen, ctrl_layer);
1439 opacity = wl_fixed_from_double(def->opacity);
1440 mrp_debug("calling ivi_controller_layer_set_opacity"
1441 "(struct ivi_controller_layer=%p, opacity=%d)",
1442 ctrl_layer, opacity);
1443 ivi_controller_layer_set_opacity(ctrl_layer, opacity);
1446 mrp_debug("calling ivi_controller_layer_set_visibility"
1447 "(ivi_controller_layer=%p, visibility=%d)",
1448 ctrl_layer, def->visibility);
1449 ivi_controller_layer_set_visibility(ctrl_layer, def->visibility);
1456 static void layer_destroy(mrp_glm_window_manager_t *wm, ctrl_layer_t *ly)
1460 if (wm && wm->layers && ly) {
1461 mrp_debug("layer %s 0x%08x going to be destroyed", ly->name, ly->id);
1463 if (!(d = mrp_htbl_remove(wm->layers, &ly->id, false)) || ly != d) {
1464 mrp_log_error("system-controller: confused with data structures "
1465 "(layer hashtable mismatch)");
1468 wl_array_release(&ly->surfaces);
1476 static void layer_visibility_callback(void *data,
1477 struct ivi_controller_layer *ctrl_layer,
1480 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1482 mrp_glm_window_manager_t *wm;
1484 MRP_ASSERT(ly && ly->wl, "invalid argument");
1485 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1486 "confused with data structures");
1489 wm = (mrp_glm_window_manager_t *)wl->wm;
1491 MRP_ASSERT(wm, "data inconsitency");
1493 mrp_debug("ctrl_layer=%p (%s %d) visibility=%d", ctrl_layer,
1494 ly->name, ly->id, visibility);
1497 static void layer_opacity_callback(void *data,
1498 struct ivi_controller_layer *ctrl_layer,
1501 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1503 mrp_glm_window_manager_t *wm;
1505 MRP_ASSERT(ly && ly->wl, "invalid argument");
1506 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1507 "confused with data structures");
1510 wm = (mrp_glm_window_manager_t *)wl->wm;
1512 MRP_ASSERT(wm, "data inconsitency");
1514 mrp_debug("ctrl_layer=%p (%s %d) opacity=%d", ctrl_layer,
1515 ly->name, ly->id, opacity);
1518 static void layer_source_rectangle_callback(void *data,
1519 struct ivi_controller_layer *ctrl_layer,
1525 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1527 mrp_glm_window_manager_t *wm;
1529 MRP_ASSERT(ly && ly->wl, "invalid argument");
1530 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1531 "confused with data structures");
1534 wm = (mrp_glm_window_manager_t *)wl->wm;
1536 MRP_ASSERT(wm, "data inconsitency");
1538 mrp_debug("ctrl_layer=%p (%s %d) x=%d y=%d width=%d height=%d", ctrl_layer,
1539 ly->name, ly->id, x,y, width,height);
1542 static void layer_destination_rectangle_callback(void *data,
1543 struct ivi_controller_layer *ctrl_layer,
1549 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1551 mrp_glm_window_manager_t *wm;
1553 MRP_ASSERT(ly && ly->wl, "invalid argument");
1554 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1555 "confused with data structures");
1558 wm = (mrp_glm_window_manager_t *)wl->wm;
1560 MRP_ASSERT(wm, "data inconsitency");
1562 mrp_debug("ctrl_layer=%p (%s %d) x=%d y=%d width=%d height=%d", ctrl_layer,
1563 ly->name, ly->id, x,y, width,height);
1566 static void layer_configuration_callback(void *data,
1567 struct ivi_controller_layer *ctrl_layer,
1571 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1573 mrp_glm_window_manager_t *wm;
1575 MRP_ASSERT(ly && ly->wl, "invalid argument");
1576 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1577 "confused with data structures");
1580 wm = (mrp_glm_window_manager_t *)wl->wm;
1582 MRP_ASSERT(wm, "data inconsitency");
1584 mrp_debug("ctrl_layer=%p (%s %d) width=%d height=%d", ctrl_layer,
1585 ly->name, ly->id, width,height);
1588 static void layer_orientation_callback(void *data,
1589 struct ivi_controller_layer *ctrl_layer,
1590 int32_t orientation)
1592 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1594 mrp_glm_window_manager_t *wm;
1596 MRP_ASSERT(ly && ly->wl, "invalid argument");
1597 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1598 "confused with data structures");
1601 wm = (mrp_glm_window_manager_t *)wl->wm;
1603 MRP_ASSERT(wm, "data inconsitency");
1605 mrp_debug("ctrl_layer=%p (%s %d) orientation=%d", ctrl_layer,
1606 ly->name, ly->id, orientation);
1609 static void layer_added_to_screen_callback(void *data,
1610 struct ivi_controller_layer *ctrl_layer,
1611 struct wl_output *screen)
1613 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1615 mrp_glm_window_manager_t *wm;
1617 MRP_ASSERT(ly && ly->wl, "invalid argument");
1618 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1619 "confused with data structures");
1622 wm = (mrp_glm_window_manager_t *)wl->wm;
1624 MRP_ASSERT(wm, "data inconsitency");
1626 mrp_debug("ctrl_layer=%p (%s %d) screen=%p", ctrl_layer,
1627 ly->name, ly->id, screen);
1630 static void layer_destroyed_callback(void *data,
1631 struct ivi_controller_layer *ctrl_layer)
1633 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1635 mrp_glm_window_manager_t *wm;
1637 MRP_ASSERT(ly && ly->wl, "invalid argument");
1638 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1639 "confused with data structures");
1642 wm = (mrp_glm_window_manager_t *)wl->wm;
1644 MRP_ASSERT(wm, "data inconsitency");
1646 mrp_debug("ctrl_layer=%p (%s %d)", ctrl_layer, ly->name, ly->id);
1650 static bool layer_add_surface_to_bottom(ctrl_layer_t *ly, ctrl_surface_t *sf)
1652 uint32_t *last, *pos;
1655 MRP_ASSERT(ly && sf, "invalid argument");
1656 MRP_ASSERT(ly->id == sf->layerid, "mismatching layer ID's");
1658 surface_id_print(sf->id, id_str, sizeof(id_str));
1660 wl_array_for_each(pos, &ly->surfaces) {
1661 if (*pos == (uint32_t)sf->id) {
1662 mrp_log_error("system-controller: can't add surface %s to the "
1663 "bottom of layer %d (surface already exists)",
1664 id_str, sf->layerid);
1669 if (!(last = wl_array_add(&ly->surfaces, sizeof(uint32_t)))) {
1670 mrp_log_error("system-controller: can't add surface %s to the bottom "
1671 "of layer %d (no memory)", id_str, sf->layerid);
1675 for (pos = last; (void *)pos > ly->surfaces.data; pos--)
1680 mrp_debug("surface %s added to the bottom of layer %d",
1681 id_str, sf->layerid);
1683 layer_send_surfaces(ly);
1689 static bool layer_add_surface_to_top(ctrl_layer_t *ly, ctrl_surface_t *sf)
1691 uint32_t *last, *pos;
1694 MRP_ASSERT(ly && sf, "invalid argument");
1695 MRP_ASSERT(ly->id == sf->layerid, "mismatching layer ID's");
1697 surface_id_print(sf->id, id_str, sizeof(id_str));
1699 wl_array_for_each(pos, &ly->surfaces) {
1700 if (*pos == (uint32_t)sf->id) {
1701 mrp_log_error("system-controller: can't add surface %s to the "
1702 "top of layer %d (surface already exists)",
1703 id_str, sf->layerid);
1708 if (!(last = wl_array_add(&ly->surfaces, sizeof(uint32_t)))) {
1709 mrp_log_error("system-controller: can't add surface %s to the top "
1710 "of layer %d (no memory)", id_str, sf->layerid);
1716 mrp_debug("surface %s added to the top of layer %d", id_str, sf->layerid);
1718 layer_send_surfaces(ly);
1723 static bool layer_move_surface_to_bottom(ctrl_layer_t *ly, ctrl_surface_t *sf)
1725 uint32_t *pos, *first, *last;
1730 MRP_ASSERT(ly && sf, "invalid argument");
1731 MRP_ASSERT(ly->id == sf->layerid, "mismatching layer ID's");
1733 surface_id_print(sf->id, id_str, sizeof(id_str));
1735 dim = ly->surfaces.size / sizeof(uint32_t);
1736 first = (uint32_t *)ly->surfaces.data;
1737 last = first + (dim - 1);
1741 for (pos = last; pos >= first; pos--) {
1742 if (pos[0] == (uint32_t)sf->id)
1749 mrp_debug("failed to move surface %s to bottom of layer %d "
1750 "(can't find surface)", id_str, sf->layerid);
1754 *first = (uint32_t)sf->id;
1756 mrp_debug("surface %s moved to bottom of layer %d", id_str, sf->layerid);
1758 layer_send_surfaces(ly);
1763 static bool layer_move_surface_to_top(ctrl_layer_t *ly, ctrl_surface_t *sf)
1765 uint32_t *pos, *first, *last;
1770 MRP_ASSERT(ly && sf, "invalid argument");
1771 MRP_ASSERT(ly->id == sf->layerid, "mismatching layer ID's");
1773 surface_id_print(sf->id, id_str, sizeof(id_str));
1775 dim = ly->surfaces.size / sizeof(uint32_t);
1776 first = (uint32_t *)ly->surfaces.data;
1777 last = first + (dim - 1);
1781 wl_array_for_each(pos, &ly->surfaces) {
1782 if (pos[0] == (uint32_t)sf->id)
1789 mrp_debug("failed to move surface %s to top of layer %d "
1790 "(can't find surface)", id_str, sf->layerid);
1794 *last = (uint32_t)sf->id;
1796 mrp_debug("surface %s moved to top of layer %d", id_str, sf->layerid);
1798 layer_send_surfaces(ly);
1803 static bool layer_remove_surface(ctrl_layer_t *ly, ctrl_surface_t *sf)
1809 MRP_ASSERT(ly && sf, "invalid argument");
1810 MRP_ASSERT(ly->id == sf->layerid, "mismatching layer ID's");
1812 surface_id_print(sf->id, id_str, sizeof(id_str));
1815 wl_array_for_each(pos, &ly->surfaces) {
1816 if (pos[0] == (uint32_t)sf->id)
1823 mrp_debug("failed to remove surface %s from layer %d "
1824 "(can't find surface)", id_str, sf->layerid);
1828 ly->surfaces.size -= sizeof(uint32_t);
1830 mrp_debug("surface %s removed from layer %d", id_str, sf->layerid);
1832 mrp_debug("calling ivi_controller_layer_remove_surface"
1833 "(ivi_controller_layer=%p, surface=%p)",
1834 ly->ctrl_layer, sf->ctrl_surface);
1835 ivi_controller_layer_remove_surface(ly->ctrl_layer, sf->ctrl_surface);
1837 layer_send_surfaces(ly);
1842 static void layer_send_surfaces(ctrl_layer_t *ly)
1848 e = (p = buf) + sizeof(buf);
1851 wl_array_for_each(id_ptr, &ly->surfaces) {
1855 p += snprintf(p, e-p, "%s%u", s, *id_ptr);
1860 mrp_debug("calling ivi_controller_layer_set_render_order"
1861 "(ivi_controller_layer=%p, id_surfaces=[%s])",
1862 ly->ctrl_layer, buf);
1864 ivi_controller_layer_set_render_order(ly->ctrl_layer, &ly->surfaces);
1868 static bool application_manager_constructor(mrp_wayland_t *wl,
1869 mrp_wayland_object_t *obj)
1871 static struct ivi_application_listener listener = {
1872 .wl_shell_info = shell_info_callback
1875 application_t *app = (application_t *)obj;
1876 mrp_glm_window_manager_t *wm;
1879 MRP_ASSERT(wl && app, "invalid argument");
1881 sts = ivi_application_add_listener((struct ivi_application *)app->proxy,
1886 if ((wm = (mrp_glm_window_manager_t *)wl->wm)) {
1887 mrp_debug("registering application interface to window manager");
1894 static void shell_info_callback(void *data,
1895 struct ivi_application *ivi_application,
1898 uint32_t id_surface)
1900 application_t *app = (application_t *)data;
1902 mrp_glm_window_manager_t *wm;
1904 mrp_list_hook_t *c, *n;
1905 constructor_t *entry, *found;
1906 constructor_state_t state;
1910 MRP_ASSERT(pid > 0 && title, "invalid argument");
1911 MRP_ASSERT(app && app->interface && app->interface->wl,"invalid argument");
1912 MRP_ASSERT(ivi_application == (struct ivi_application *)app->proxy,
1913 "confused with data structures");
1915 wl = app->interface->wl;
1917 mrp_debug("pid=%d title='%s' id_surface=%s",
1918 pid, title ? title : "<null>",
1919 surface_id_print(id_surface, buf, sizeof(buf)));
1921 if (!(wm = (mrp_glm_window_manager_t *)wl->wm)) {
1922 mrp_debug("controller interface is not ready");
1926 has_title = (title && title[0]);
1932 constructor_create(wm, CONSTRUCTOR_INCOMPLETE, pid, NULL, 0);
1934 /* try to find an incomplete constructor with a matching pid */
1937 mrp_list_foreach(&wm->constructors, c, n) {
1938 entry = mrp_list_entry(c, constructor_t, link);
1940 if (pid == entry->pid) {
1941 if ((entry->state == CONSTRUCTOR_INCOMPLETE) ||
1942 (entry->state == CONSTRUCTOR_TITLED &&
1943 !strcmp(title, entry->title) ) )
1952 constructor_create(wm, CONSTRUCTOR_TITLED, pid, title, 0);
1954 constructor_set_title(wm, found, title);
1958 /* we have a surface ID */
1960 if (!(sf = surface_find(wm, id_surface))) {
1961 /* no surface found with the ID */
1963 /* try to find a matching constructor */
1964 found = constructor_find_surface(wm, id_surface, pid, title);
1968 state = CONSTRUCTOR_TITLED;
1970 state = CONSTRUCTOR_INCOMPLETE;
1972 constructor_create(wm, state, pid, title, id_surface);
1975 if (id_surface > 0) {
1976 /* found a constructor with the ID */
1977 if (pid != found->pid) {
1978 mrp_log_error("system-controller: confused with "
1979 "surface constructors "
1980 "(mismatching PIDs: %d vs. %d)",
1985 constructor_set_title(wm, found, title);
1989 mrp_debug("found a constructor with matching pid/title. "
1992 found->id_surface = id_surface;
1994 if (found->timer.surfaceless) {
1995 mrp_del_timer(found->timer.surfaceless);
1996 found->timer.surfaceless = NULL;
2000 constructor_set_title(wm, found, title);
2005 /* found a surface with the ID */
2006 if (pid != sf->pid) {
2007 mrp_log_error("system-controller: confused with control "
2008 "surfaces (mismatching PIDs: %d vs. %d)",
2013 surface_set_title(wm, sf, title);
2020 static bool ico_extension_constructor(mrp_wayland_t *wl,
2021 mrp_wayland_object_t *obj)
2023 static struct ico_window_mgr_listener listener = {
2024 .window_active = ico_extension_window_active_callback,
2025 .map_surface = ico_extension_map_surface_callback,
2026 .update_surface = ico_extension_update_surface_callback,
2027 .destroy_surface = ico_extension_destroy_surface_callback
2030 ico_extension_t *ico = (ico_extension_t *)obj;
2031 mrp_glm_window_manager_t *wm;
2034 if (!(wm = (mrp_glm_window_manager_t *)(wl->wm))) {
2035 mrp_log_error("system-controller: phase error in %s(): "
2036 "window manager does not exist", __FUNCTION__);
2040 sts = ico_window_mgr_add_listener((struct ico_window_mgr *)ico->proxy,
2051 static void ico_extension_window_active_callback(void *data,
2052 struct ico_window_mgr *ico_window_mgr,
2056 ico_extension_t *ico = (ico_extension_t *)data;
2058 mrp_glm_window_manager_t *wm;
2060 mrp_wayland_window_t *win;
2061 mrp_wayland_window_update_t u;
2064 MRP_ASSERT(ico && ico->interface && ico->interface->wl,
2065 "invalid argument");
2066 MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)ico->proxy,
2067 "confused with data structures");
2069 wl = ico->interface->wl;
2070 wm = (mrp_glm_window_manager_t *)(wl->wm);
2072 MRP_ASSERT(wm, "data inconsitency");
2074 mrp_debug("surfaceid=%u select=%d", surfaceid, select);
2077 mrp_debug("ignoring select=0 events");
2081 surface_id_print(surfaceid, id_str, sizeof(id_str));
2083 if (!(sf = surface_find(wm, surfaceid))) {
2084 mrp_debug("can't find surface for id=%s", id_str);
2088 if (!(win = sf->win)) {
2089 mrp_debug("can't forward selection event for surface id=%s "
2090 "(no window)", id_str);
2094 memset(&u, 0, sizeof(u));
2095 u.mask = MRP_WAYLAND_WINDOW_ACTIVE_MASK;
2098 if ((select & ICO_WINDOW_MGR_SELECT_POINTER))
2099 u.active |= MRP_WAYLAND_WINDOW_ACTIVE_POINTER;
2100 if ((select & ICO_WINDOW_MGR_SELECT_TOUCH))
2101 u.active |= MRP_WAYLAND_WINDOW_ACTIVE_TOUCH;
2103 mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_ACTIVE, &u);
2107 static void ico_extension_map_surface_callback(void *data,
2108 struct ico_window_mgr *ico_window_mgr,
2117 ico_extension_t *ico = (ico_extension_t *)data;
2119 mrp_glm_window_manager_t *wm;
2121 mrp_wayland_window_t *win;
2122 mrp_wayland_window_update_t u;
2123 mrp_wayland_window_map_t map;
2126 MRP_ASSERT(ico && ico->interface && ico->interface->wl,
2127 "invalid argument");
2128 MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)ico->proxy,
2129 "confused with data structures");
2131 wl = ico->interface->wl;
2132 wm = (mrp_glm_window_manager_t *)(wl->wm);
2134 MRP_ASSERT(wm, "data inconsitency");
2136 mrp_debug("event=%d surfaceid=%u type=%u width=%d height=%d stride=%d "
2138 event, surfaceid, type, width,height, stride, format);
2140 surface_id_print(surfaceid, id_str, sizeof(id_str));
2142 if (!(sf = surface_find(wm, surfaceid))) {
2143 mrp_debug("can't find surface for id=%s", id_str);
2147 if (!(win = sf->win)) {
2148 mrp_debug("can't forward map event for surface id=%s "
2149 "(no window)", id_str);
2153 memset(&map, 0, sizeof(map));
2156 map.height = height;
2157 map.stride = stride;
2158 map.format = format;
2160 memset(&u, 0, sizeof(u));
2161 u.mask = MRP_WAYLAND_WINDOW_MAPPED_MASK | MRP_WAYLAND_WINDOW_MAP_MASK;
2166 case ICO_WINDOW_MGR_MAP_SURFACE_EVENT_CONTENTS:
2167 case ICO_WINDOW_MGR_MAP_SURFACE_EVENT_RESIZE:
2168 case ICO_WINDOW_MGR_MAP_SURFACE_EVENT_MAP:
2172 case ICO_WINDOW_MGR_MAP_SURFACE_EVENT_UNMAP:
2173 case ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR:
2178 mrp_debug("ignoring unknown event type %d event", event);
2182 mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_MAP, &u);
2185 static void ico_extension_update_surface_callback(void *data,
2186 struct ico_window_mgr *ico_window_mgr,
2196 ico_extension_t *ico = (ico_extension_t *)data;
2198 mrp_glm_window_manager_t *wm;
2200 MRP_ASSERT(ico && ico->interface && ico->interface->wl,
2201 "invalid argument");
2202 MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)ico->proxy,
2203 "confused with data structures");
2205 wl = ico->interface->wl;
2206 wm = (mrp_glm_window_manager_t *)(wl->wm);
2208 MRP_ASSERT(wm, "data inconsitency");
2210 mrp_debug("surfaceid=%u visible=%d srcwidth=%d srcheight=%d x=%d y=%d "
2211 "width=%d height=%d",
2212 surfaceid, visible, srcwidth,srcheight, x,y, width,height);
2216 static void ico_extension_destroy_surface_callback(void *data,
2217 struct ico_window_mgr *ico_window_mgr,
2220 ico_extension_t *ico = (ico_extension_t *)data;
2222 mrp_glm_window_manager_t *wm;
2224 MRP_ASSERT(ico && ico->interface && ico->interface->wl,
2225 "invalid argument");
2226 MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)ico->proxy,
2227 "confused with data structures");
2229 wl = ico->interface->wl;
2230 wm = (mrp_glm_window_manager_t *)(wl->wm);
2232 MRP_ASSERT(wm, "data inconsitency");
2234 mrp_debug("surfaceid=%u", surfaceid);
2240 static uint32_t surface_id_generate(void)
2242 #define FIRST_ID (SURFACE_ID_OUR_FLAG | 1)
2243 #define MAX_ID (SURFACE_ID_OUR_FLAG | SURFACE_ID_MAX)
2245 static uint32_t id = FIRST_ID;
2256 static bool surface_id_is_ours(uint32_t id)
2258 return ((id & SURFACE_ID_OUR_FLAG) == SURFACE_ID_OUR_FLAG) ? true : false;
2261 static char *surface_id_print(uint32_t id, char *buf, size_t len)
2264 snprintf(buf, len, "<not set>");
2266 snprintf(buf, len, "%u(%s-id-%u)", id,
2267 surface_id_is_ours(id) ? "our":"native",
2268 (id & SURFACE_ID_MAX));
2274 static constructor_t *constructor_create(mrp_glm_window_manager_t *wm,
2275 constructor_state_t state,
2278 uint32_t id_surface)
2284 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
2286 wl = wm->interface->wl;
2288 if (!(c = mrp_allocz(sizeof(constructor_t)))) {
2289 mrp_log_error("system-controller: can't allocate memory for surface"
2290 "(pid=%d title='%s' id_surface=%s)",
2291 pid, title ? title : "<null>",
2292 surface_id_print(id_surface, buf, sizeof(buf)));
2296 mrp_list_init(&c->link);
2300 c->title = title ? mrp_strdup(title) : NULL;
2301 c->id_surface = id_surface;
2302 c->timer.timeout = mrp_add_timer(wl->ml, CONSTRUCTOR_TIMEOUT,
2303 constructor_timeout, c);
2306 c->timer.surfaceless = mrp_add_timer(wl->ml, SURFACELESS_TIMEOUT,
2307 constructor_surfaceless, c);
2310 mrp_list_append(&wm->constructors, &c->link);
2312 mrp_debug("constructor created (state=%s, pid=%d, title='%s' "
2313 "id_surface=%u)", constructor_state_str(state), pid,
2314 title ? title: "<null>", id_surface);
2319 static void constructor_destroy(constructor_t *c)
2324 mrp_debug("surface %s of application (pid=%d) destroyed",
2325 surface_id_print(c->id_surface, buf, sizeof(buf)), c->pid);
2327 mrp_del_timer(c->timer.timeout);
2328 mrp_del_timer(c->timer.surfaceless);
2330 mrp_list_delete(&c->link);
2337 static void constructor_timeout(mrp_timer_t *timer, void *user_data)
2339 constructor_t *c = (constructor_t *)user_data;
2340 mrp_glm_window_manager_t *wm;
2343 MRP_ASSERT(timer && c && c->wm, "invalid argument");
2344 MRP_ASSERT(timer == c->timer.timeout, "confused with data structures");
2346 mrp_debug("pid=%d title='%s' id_surface=%s state=%s",
2347 c->pid, c->title ? c->title : "",
2348 surface_id_print(c->id_surface, buf, sizeof(buf)),
2349 constructor_state_str(c->state));
2353 constructor_destroy(c);
2354 constructor_issue_next_request(wm);
2357 static void constructor_surfaceless(mrp_timer_t *timer, void *user_data)
2359 constructor_t *c = (constructor_t *)user_data;
2360 mrp_glm_window_manager_t *wm;
2362 MRP_ASSERT(timer && c && c->wm, "invalid argument");
2363 MRP_ASSERT(timer == c->timer.surfaceless, "confused with data structures");
2365 mrp_debug("pid=%d title='%s' state=%s",
2366 c->pid, c->title ? c->title : "<not set>",
2367 constructor_state_str(c->state));
2371 mrp_del_timer(c->timer.surfaceless);
2372 c->timer.surfaceless = NULL;
2374 c->state = CONSTRUCTOR_SURFACELESS;
2375 constructor_issue_next_request(wm);
2378 static constructor_t *constructor_find_first(mrp_glm_window_manager_t *wm,
2380 constructor_state_t state)
2382 mrp_list_hook_t *c, *n;
2383 constructor_t *entry;
2385 mrp_list_foreach(&wm->constructors, c, n) {
2386 entry = mrp_list_entry(c, constructor_t, link);
2388 if (( match && state == entry->state) ||
2389 (!match && state != entry->state))
2396 static constructor_t *constructor_find_surface(mrp_glm_window_manager_t *wm,
2397 uint32_t id_surface,
2401 mrp_list_hook_t *c, *n;
2402 constructor_t *entry, *candidate;
2403 bool candidate_titleless;
2406 candidate_titleless = false;
2408 mrp_list_foreach(&wm->constructors, c, n) {
2409 entry = mrp_list_entry(c, constructor_t, link);
2411 if (id_surface > 0) {
2412 if (id_surface == entry->id_surface)
2416 if (pid == entry->pid) {
2417 if (entry->state == CONSTRUCTOR_INCOMPLETE) {
2418 if (!title && !candidate)
2422 if (title && !strcmp(title, entry->title)) {
2423 if (!candidate || !candidate_titleless) {
2425 candidate_titleless = false;
2436 static constructor_t *constructor_find_bound(mrp_glm_window_manager_t *wm,
2437 uint32_t id_surface)
2439 mrp_list_hook_t *c, *n;
2440 constructor_t *entry;
2442 if (id_surface > 0) {
2443 mrp_list_foreach(&wm->constructors, c, n) {
2444 entry = mrp_list_entry(c, constructor_t, link);
2446 if (id_surface == entry->id_surface &&
2447 entry->state == CONSTRUCTOR_BOUND)
2456 static void constructor_set_title(mrp_glm_window_manager_t *wm,
2462 if (title && title[0]) {
2463 mrp_free((void *)c->title);
2464 c->title = title ? mrp_strdup(title) : NULL;
2466 mrp_debug("constructor title changed to '%s'", c->title);
2468 if (c->state == CONSTRUCTOR_INCOMPLETE) {
2469 c->state = CONSTRUCTOR_TITLED;
2470 mrp_debug("constructor state changed to %s",
2471 constructor_state_str(c->state));
2476 static void constructor_issue_next_request(mrp_glm_window_manager_t *wm)
2478 mrp_list_hook_t *c, *n;
2479 constructor_t *entry;
2481 mrp_debug("loop through constructors ...");
2483 mrp_list_foreach(&wm->constructors, c, n) {
2484 entry = mrp_list_entry(c, constructor_t, link);
2486 mrp_debug(" state %s", constructor_state_str(entry->state));
2488 if (entry->state == CONSTRUCTOR_SURFACELESS) {
2489 mrp_debug(" call ivi_controller_get_native_handle"
2490 "(pid=%d title='%s')", entry->pid,
2491 entry->title ? entry->title : "<not set>");
2493 ivi_controller_get_native_handle((struct ivi_controller*)wm->proxy,
2494 entry->pid, entry->title);
2496 entry->state = CONSTRUCTOR_REQUESTED;
2498 mrp_wayland_flush(wm->interface->wl);
2503 if (entry->state == CONSTRUCTOR_REQUESTED)
2507 mrp_debug(" do not issue native handle request");
2510 static bool constructor_bind_ivi_surface(mrp_glm_window_manager_t *wm,
2513 struct ivi_surface *ivi_surface;
2517 if (!wm || !(app = wm->app) || !c)
2520 if (!c->id_surface) {
2521 mrp_log_error("system-controller: failed to create ivi-surface "
2522 "(id_surface is not set)");
2526 if (!c->wl_surface) {
2527 mrp_log_error("system-controller: failed to create ivi-surface "
2528 "(wl_surface not set)");
2532 mrp_debug("call ivi_application_surface_create(id_surface=%s surface=%p)",
2533 surface_id_print(c->id_surface, buf,sizeof(buf)), c->wl_surface);
2535 ivi_surface = ivi_application_surface_create(
2536 (struct ivi_application *)app->proxy,
2537 c->id_surface, c->wl_surface);
2539 mrp_log_error("system-controller: failed to create "
2540 "ivi-application-surface (id=%s)",
2541 surface_id_print(c->id_surface, buf, sizeof(buf)));
2548 static char *constructor_state_str(constructor_state_t state)
2551 case CONSTRUCTOR_FAILED: return "failed";
2552 case CONSTRUCTOR_INCOMPLETE: return "incomplete";
2553 case CONSTRUCTOR_TITLED: return "titled";
2554 case CONSTRUCTOR_SURFACELESS: return "surfaceless";
2555 case CONSTRUCTOR_REQUESTED: return "requested";
2556 case CONSTRUCTOR_BOUND: return "bound";
2557 default: return "<unknown>";
2561 static ctrl_layer_t *layer_find(mrp_glm_window_manager_t *wm, int32_t id_layer)
2565 if (!wm || !wm->layers)
2568 ly = mrp_htbl_lookup(wm->layers, &id_layer);
2573 static bool set_layer_visibility(mrp_wayland_layer_t *layer,
2574 mrp_wayland_layer_update_mask_t passthrough,
2575 mrp_wayland_layer_update_t *u)
2577 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)layer->wm;
2579 uint32_t visibility;
2583 if (!(ly = layer_find(wm, layer->layerid))) {
2584 mrp_debug("can't find layer");
2588 visibility = u->visible ? 1 : 0;
2590 mrp_debug("call ivi_controller_layer_set_visibility"
2591 "(ivi_controller_layer=%p, visibility=%u)",
2592 ly->ctrl_layer, visibility);
2594 ivi_controller_layer_set_visibility(ly->ctrl_layer, visibility);
2599 static void layer_request(mrp_wayland_layer_t *layer,
2600 mrp_wayland_layer_update_t *u)
2603 mrp_glm_window_manager_t *wm;
2604 mrp_wayland_layer_update_mask_t mask;
2605 mrp_wayland_layer_update_mask_t passthrough;
2609 MRP_ASSERT(layer && layer->wm && layer->wm->proxy &&
2610 layer->wm->interface && layer->wm->interface->wl,
2611 "invalid argument");
2613 wm = (mrp_glm_window_manager_t *)layer->wm;
2614 wl = wm->interface->wl;
2615 passthrough = wm->passthrough.layer_request;
2619 mrp_wayland_layer_request_print(u, buf, sizeof(buf));
2620 mrp_debug("request for layer %d update:%s", layer->layerid, buf);
2623 if ((mask & MRP_WAYLAND_LAYER_VISIBLE_MASK)) {
2624 changed |= set_layer_visibility(layer, passthrough, u);
2625 mask &= ~MRP_WAYLAND_LAYER_VISIBLE_MASK;
2634 mrp_debug("calling ivi_controller_commit_changes()");
2635 ivi_controller_commit_changes((struct ivi_controller *)wm->proxy);
2638 mrp_wayland_flush(wl);
2642 static void set_window_animation(mrp_wayland_window_t *win,
2643 mrp_wayland_animation_type_t type,
2644 mrp_wayland_animation_t *anims)
2646 static int32_t ico_types[MRP_WAYLAND_ANIMATION_MAX] = {
2647 [MRP_WAYLAND_ANIMATION_HIDE] = ICO_WINDOW_MGR_ANIMATION_TYPE_HIDE,
2648 [MRP_WAYLAND_ANIMATION_SHOW] = ICO_WINDOW_MGR_ANIMATION_TYPE_SHOW,
2649 [MRP_WAYLAND_ANIMATION_MOVE] = ICO_WINDOW_MGR_ANIMATION_TYPE_MOVE,
2650 [MRP_WAYLAND_ANIMATION_RESIZE] = ICO_WINDOW_MGR_ANIMATION_TYPE_RESIZE
2653 mrp_glm_window_manager_t *wm;
2654 ico_extension_t *ico;
2655 struct ico_window_mgr *ico_window_mgr;
2656 mrp_wayland_animation_t *a;
2658 MRP_ASSERT(win && win->wm, "invalid argument");
2660 wm = (mrp_glm_window_manager_t *)(win->wm);
2664 mrp_debug("can't animate on window %u (ico-extension not available)",
2669 ico_window_mgr = (struct ico_window_mgr *)ico->proxy;
2671 if (anims && type >= 0 && type < MRP_WAYLAND_ANIMATION_MAX) {
2674 if (a->name && a->name[0] && a->time > 0) {
2675 mrp_debug("calling ico_window_mgr_set_animation"
2676 "(surfaceid=%d type=%d, animation='%s' time=%d)",
2677 win->surfaceid, ico_types[type], a->name, a->time);
2679 ico_window_mgr_set_animation(ico_window_mgr, win->surfaceid,
2680 ico_types[type], a->name, a->time);
2685 static bool set_window_layer(mrp_wayland_window_t *win,
2686 mrp_wayland_window_update_mask_t passthrough,
2687 mrp_wayland_window_update_t *u)
2689 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
2695 mrp_wayland_window_update_t u2;
2701 mrp_log_error("system-controller: broken request (layer is <null>)");
2705 id_surface = win->surfaceid;
2706 id_layer = u->layer->layerid;
2708 if (!(sf = surface_find(wm, id_surface))) {
2709 mrp_debug("can't find surface %s",
2710 surface_id_print(id_surface, buf, sizeof(buf)));
2714 if (!(ly = layer_find(wm, id_layer))) {
2715 mrp_debug("can't find layer %d", id_layer);
2719 if (sf->layerid == id_layer) {
2720 if ((u->mask & MRP_WAYLAND_WINDOW_RAISE_MASK))
2723 changed = layer_move_surface_to_top(ly, sf);
2726 sf->layerid = id_layer;
2727 changed = layer_add_surface_to_top(ly, sf);
2731 memset(&u2, 0, sizeof(u2));
2732 u2.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
2733 MRP_WAYLAND_WINDOW_RAISE_MASK;
2734 u2.surfaceid = win->surfaceid;
2737 mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_VISIBLE, &u2);
2743 static bool set_window_mapped(mrp_wayland_window_t *win,
2744 mrp_wayland_window_update_mask_t passthrough,
2745 mrp_wayland_window_update_t *u,
2746 mrp_wayland_animation_t *anims,
2749 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
2750 ico_extension_t *ico = wm->ico;
2752 struct ico_window_mgr *ico_window_mgr;
2753 const char *filepath;
2756 ico_window_mgr = ico ? (struct ico_window_mgr *)ico->proxy : NULL;
2757 id_surface = win->surfaceid;
2759 surface_id_print(id_surface, id_str, sizeof(id_str));
2761 if (((u->mapped && win->mapped) || (!u->mapped && !win->mapped)) &&
2762 !(passthrough & MRP_WAYLAND_WINDOW_MAPPED_MASK))
2764 mrp_debug("nothing to do");
2769 if (!anims || !(filepath = anims[MRP_WAYLAND_ANIMATION_MAP].name)) {
2770 mrp_log_error("system-controller: broken map request "
2775 if (!ico_window_mgr) {
2776 mrp_debug("can't map surface %s to file '%s' (ico-extension not "
2777 "available)", id_str, filepath);
2784 mrp_debug("calling ico_window_mgr_map_surface"
2785 "(ico_window_mgr=%p, surfaceid=%u, framerate=%d, "
2787 ico_window_mgr, id_surface, framerate, filepath);
2789 ico_window_mgr_map_surface(ico_window_mgr, id_surface, framerate,
2793 if (!ico_window_mgr) {
2794 mrp_debug("can't unmap surface %s (ico-extension not available)",
2799 mrp_debug("calling ico_window_mgr_unmap_surface"
2800 "(ico_window_mgr=%p, surfaceid=%u)",
2801 ico_window_mgr, id_surface);
2803 ico_window_mgr_unmap_surface(ico_window_mgr, id_surface);
2809 static bool set_window_geometry(mrp_wayland_window_t *win,
2810 mrp_wayland_window_update_mask_t passthrough,
2811 mrp_wayland_window_update_t *u,
2812 mrp_wayland_animation_t *anims)
2814 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
2815 mrp_wayland_window_update_mask_t mask = u->mask;
2816 int32_t id_surface = win->surfaceid;
2817 bool output_changed = false;
2825 if (!output_changed &&
2826 (!(mask & MRP_WAYLAND_WINDOW_POSITION_MASK) ||
2827 (u->x == win->x && u->y == win->y) ) &&
2828 (!(mask & MRP_WAYLAND_WINDOW_SIZE_MASK) ||
2829 (u->width == win->width && u->height == win->height)) )
2831 mrp_debug("nothing to do");
2835 if (!(sf = surface_find(wm, id_surface))) {
2836 mrp_debug("can't find surface %s",
2837 surface_id_print(id_surface, buf, sizeof(buf)));
2841 x = (mask & MRP_WAYLAND_WINDOW_X_MASK ) ? u->x : win->x;
2842 y = (mask & MRP_WAYLAND_WINDOW_Y_MASK ) ? u->y : win->y;
2843 w = (mask & MRP_WAYLAND_WINDOW_WIDTH_MASK ) ? u->width : win->width;
2844 h = (mask & MRP_WAYLAND_WINDOW_HEIGHT_MASK) ? u->height : win->height;
2846 if (x != win->x || y != win->y)
2847 set_window_animation(win, MRP_WAYLAND_ANIMATION_MOVE, anims);
2848 if (w != win->width || h != win->height)
2849 set_window_animation(win, MRP_WAYLAND_ANIMATION_RESIZE, anims);
2852 mrp_debug("calling ivi_controller_surface_set_source_rectangle"
2853 "(ivi_controller_surface=%p, x=0, y=0, width=%d height=%d)",
2854 sf->ctrl_surface, w,h);
2856 ivi_controller_surface_set_source_rectangle(sf->ctrl_surface, 0,0, w,h);
2860 sf->requested_x = x;
2861 sf->requested_y = y;
2862 sf->requested_width = w;
2863 sf->requested_height = h;
2865 mrp_debug("calling ivi_controller_surface_set_destination_rectangle"
2866 "(ivi_controller_surface=%p, x=%d, y=%d, width=%d height=%d)",
2867 sf->ctrl_surface, x,y, w,h);
2869 ivi_controller_surface_set_destination_rectangle(sf->ctrl_surface,
2876 static bool set_window_opacity(mrp_wayland_window_t *win,
2877 mrp_wayland_window_update_mask_t passthrough,
2878 mrp_wayland_window_update_t *u)
2880 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
2881 int32_t id_surface = win->surfaceid;
2886 if (u->opacity == win->opacity &&
2887 !(passthrough & MRP_WAYLAND_WINDOW_OPACITY_MASK))
2889 mrp_debug("nothing to do");
2893 if (!(sf = surface_find(wm, id_surface))) {
2894 mrp_debug("can't find surface %s",
2895 surface_id_print(id_surface, buf, sizeof(buf)));
2899 opacity = wl_fixed_from_double(u->opacity);
2901 mrp_debug("calling ivi_controller_surface_set_opacity"
2902 "(ivi_controller_surface=%p, opacity=%d)",
2903 sf->ctrl_surface, opacity);
2905 ivi_controller_surface_set_opacity(sf->ctrl_surface, opacity);
2911 static bool raise_window(mrp_wayland_window_t *win,
2912 mrp_wayland_window_update_mask_t passthrough,
2913 mrp_wayland_window_update_t *u)
2915 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
2916 mrp_wayland_window_update_t u2;
2917 int32_t id_surface = win->surfaceid;
2925 do { /* not a loop */
2928 if (((u->raise && win->raise) || (!u->raise && !win->raise))) {
2929 mrp_debug("no actual change is needed");
2933 if (!(sf = surface_find(wm, win->surfaceid))) {
2934 mrp_debug("can't find surface %s",
2935 surface_id_print(id_surface, buf, sizeof(buf)));
2940 mrp_debug("layer is not set");
2944 if (!(ly = layer_find(wm, win->layer->layerid))) {
2945 mrp_debug("can't find layer %d", win->layer->layerid);
2950 changed = layer_move_surface_to_top(ly, sf);
2952 changed = layer_move_surface_to_bottom(ly, sf);
2957 memset(&u2, 0, sizeof(u2));
2958 u2.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
2959 MRP_WAYLAND_WINDOW_RAISE_MASK;
2960 u2.surfaceid = win->surfaceid;
2961 u2.raise = u->raise;
2963 mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_VISIBLE, &u2);
2969 static bool set_window_visibility(mrp_wayland_window_t *win,
2970 mrp_wayland_window_update_mask_t passthrough,
2971 mrp_wayland_window_update_t *u,
2972 mrp_wayland_animation_t *anims)
2974 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
2976 uint32_t visibility;
2978 mrp_wayland_animation_type_t anim_type;
2981 if ((((u->visible && win->visible) || (!u->visible && !win->visible)) &&
2982 !(passthrough & MRP_WAYLAND_WINDOW_VISIBLE_MASK)))
2984 mrp_debug("nothing to do");
2988 id_surface = win->surfaceid;
2989 visibility = u->visible ? 1 : 0;
2990 anim_type = visibility ? MRP_WAYLAND_ANIMATION_SHOW :
2991 MRP_WAYLAND_ANIMATION_HIDE;
2993 if (!(sf = surface_find(wm, id_surface))) {
2994 mrp_debug("can't find surface %s",
2995 surface_id_print(id_surface, buf, sizeof(buf)));
2999 set_window_animation(win, anim_type, anims);
3001 mrp_debug("calling ivi_controller_surface_set_visibility"
3002 "(ivi_controller_surface=%p, visibility=%u)",
3003 sf->ctrl_surface, visibility);
3005 ivi_controller_surface_set_visibility(sf->ctrl_surface, visibility);
3010 static bool set_window_active(mrp_wayland_window_t *win,
3011 mrp_wayland_window_update_mask_t passthrough,
3012 mrp_wayland_window_update_t *u)
3014 static mrp_wayland_active_t focus_mask = MRP_WAYLAND_WINDOW_ACTIVE_POINTER|
3015 MRP_WAYLAND_WINDOW_ACTIVE_TOUCH ;
3017 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
3018 int32_t id_surface = win->surfaceid;
3020 int32_t focus_enabled;
3023 surface_id_print(id_surface, id_str, sizeof(id_str));
3025 if (u->active == win->active &&
3026 !(passthrough & MRP_WAYLAND_WINDOW_ACTIVE_MASK))
3028 mrp_debug("nothing to do");
3032 if (!(sf = surface_find(wm, id_surface))) {
3033 mrp_debug("can't find surface %s", id_str);
3037 focus_enabled = (u->active & focus_mask) ? 1 : 0;
3039 mrp_debug("calling ivi_controller_surface_set_input_focus"
3040 "(struct ivi_controller_surface=%p, enabled=%d)",
3041 sf->ctrl_surface, focus_enabled);
3044 ivi_controller_surface_set_input_focus(sf->ctrl_surface,
3045 IVI_CONTROLLER_SURFACE_INPUT_DEVICE_ALL,
3051 static void window_request(mrp_wayland_window_t *win,
3052 mrp_wayland_window_update_t *u,
3053 mrp_wayland_animation_t *anims,
3057 static mrp_wayland_window_update_mask_t area_mask =
3058 MRP_WAYLAND_WINDOW_AREA_MASK;
3060 static mrp_wayland_window_update_mask_t mapped_mask =
3061 MRP_WAYLAND_WINDOW_MAPPED_MASK;
3062 static mrp_wayland_window_update_mask_t geometry_mask =
3063 /* MRP_WAYLAND_WINDOW_NODEID_MASK | */
3064 MRP_WAYLAND_WINDOW_POSITION_MASK |
3065 MRP_WAYLAND_WINDOW_SIZE_MASK ;
3066 static mrp_wayland_window_update_mask_t opacity_mask =
3067 MRP_WAYLAND_WINDOW_OPACITY_MASK;
3068 static mrp_wayland_window_update_mask_t raise_mask =
3069 MRP_WAYLAND_WINDOW_RAISE_MASK;
3070 static mrp_wayland_window_update_mask_t layer_mask =
3071 MRP_WAYLAND_WINDOW_LAYER_MASK;
3072 static mrp_wayland_window_update_mask_t visible_mask =
3073 MRP_WAYLAND_WINDOW_VISIBLE_MASK;
3074 static mrp_wayland_window_update_mask_t active_mask =
3075 MRP_WAYLAND_WINDOW_ACTIVE_MASK;
3079 mrp_glm_window_manager_t *wm;
3080 mrp_wayland_window_update_mask_t passthrough;
3081 mrp_wayland_window_update_mask_t mask;
3086 MRP_ASSERT(win && win->wm && win->wm->proxy && win->wm->interface &&
3087 win->wm->interface->wl && u, "invalid argument");
3089 wm = (mrp_glm_window_manager_t *)win->wm;
3090 wl = wm->interface->wl;
3091 passthrough = wm->passthrough.window_request;
3095 mrp_wayland_window_request_print(u, wbuf, sizeof(wbuf));
3096 mrp_wayland_animation_print(anims, abuf, sizeof(abuf));
3097 mrp_debug("request for window %d update:%s\n animations:%s",
3098 win->surfaceid, wbuf, abuf);
3101 if ((mask & layer_mask)) {
3102 changed |= set_window_layer(win, passthrough, u);
3103 mask &= ~layer_mask;
3105 else if ((mask & mapped_mask)) {
3106 changed |= set_window_mapped(win, passthrough, u,
3108 mask &= ~(mapped_mask);
3111 else if ((mask & area_mask)) {
3112 changed |= set_window_area(win, passthrough, u, anims);
3113 mask &= ~(area_mask | geometry_mask);
3116 else if ((mask & geometry_mask)) {
3117 changed |= set_window_geometry(win, passthrough, u, anims);
3118 mask &= ~geometry_mask;
3120 else if ((mask & opacity_mask)) {
3121 changed |= set_window_opacity(win, passthrough, u);
3122 mask &= ~opacity_mask;
3124 else if ((mask & raise_mask)) {
3125 changed |= raise_window(win, passthrough, u);
3126 mask &= ~raise_mask;
3128 else if ((mask & visible_mask)) {
3129 changed |= set_window_visibility(win, passthrough, u, anims);
3130 mask &= ~visible_mask;
3132 else if ((mask & active_mask)) {
3133 changed |= set_window_active(win, passthrough, u);
3134 mask &= ~active_mask;
3142 mrp_debug("calling ivi_controller_commit_changes()");
3143 ivi_controller_commit_changes((struct ivi_controller *)wm->proxy);
3146 mrp_wayland_flush(wl);
3150 static void buffer_request(mrp_wayland_window_manager_t *wm,
3151 const char *shmname,
3158 MRP_ASSERT(wm && wm->proxy && shmname, "invalid argument");
3160 mrp_log_warning("system-controller: buffer_request is not supported in "
3161 "Genivi Layer Management");
3165 static uint32_t sid_hash(const void *pkey)
3167 uint32_t key = *(uint32_t *)pkey;
3169 return key % MRP_WAYLAND_WINDOW_BUCKETS;
3172 static uint32_t lid_hash(const void *pkey)
3174 uint32_t key = *(uint32_t *)pkey;
3176 return key % MRP_WAYLAND_LAYER_BUCKETS;
3180 static uint32_t oid_hash(const void *pkey)
3182 uint32_t key = *(uint32_t *)pkey;
3184 return key % MRP_WAYLAND_OUTPUT_BUCKETS;
3188 static int id_compare(const void *pkey1, const void *pkey2)
3190 int32_t key1 = *(int32_t *)pkey1;
3191 int32_t key2 = *(int32_t *)pkey2;
3193 return (key1 == key2) ? 0 : ((key1 < key2) ? -1 : 1);
3196 static int32_t get_parent_pid(int32_t pid)
3202 char *ppid_line, *c, *e;
3205 snprintf(path, sizeof(path), "/proc/%d/status", pid);
3207 if ((fd = open(path, O_RDONLY)) < 0)
3210 while ((size = read(fd, buf, sizeof(buf)-1)) <= 0) {
3211 if (errno != EINTR) {
3221 if ((ppid_line = strstr(buf, "PPid:"))) {
3222 for (c = ppid_line + 5; (*c == ' ' || *c == '\t'); c++)
3225 if ((ppid = strtol(c, &e, 10)) > 0 && e > c && *e == '\n')
3232 static void get_binary_basename(int32_t pid, char *buf, int len)
3240 snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
3244 if ((fd = open(path, O_RDONLY)) < 0)
3247 while ((size = read(fd, cmdline, sizeof(cmdline))) <= 0) {
3248 if (errno != EINTR) {
3257 bnam = basename(cmdline);
3259 strncpy(buf, bnam, len-1);
3263 static void get_appid(int32_t pid, char *buf, int len)
3267 if (!buf || len < 2)
3272 if ((ppid = pid) > 0) {
3273 while (aul_app_get_appid_bypid(ppid, buf, len) != AUL_R_OK) {
3274 if ((ppid = get_parent_pid(ppid)) <= 1) {
3275 get_binary_basename(pid, buf, len);