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 wid_hash(const void *);
347 static uint32_t sid_hash(const void *);
348 static uint32_t lid_hash(const void *);
349 static uint32_t oid_hash(const void *);
350 static int wid_compare(const void *, const void *);
351 static int id_compare(const void *, const void *);
353 static void get_appid(int32_t, char *, int);
355 static layer_defaults_t layer_defaults[MRP_WAYLAND_LAYER_TYPE_MAX] = {
356 /* layer type zorder opacity visibility */
357 /*---------------------------------------------------------------- */
358 [ MRP_WAYLAND_LAYER_TYPE_UNKNOWN ] = { 2, 0.750, HIDDEN },
359 [ MRP_WAYLAND_LAYER_BACKGROUND ] = { 1, 0.000, VISIBLE },
360 [ MRP_WAYLAND_LAYER_APPLICATION ] = { 3, 1.000, HIDDEN, },
361 [ MRP_WAYLAND_LAYER_INPUT ] = { 4, 1.000, HIDDEN },
362 [ MRP_WAYLAND_LAYER_TOUCH ] = { 5, 1.000, HIDDEN },
363 [ MRP_WAYLAND_LAYER_CURSOR ] = { 6, 1.000, HIDDEN },
364 [ MRP_WAYLAND_LAYER_STARTUP ] = { 7, 1.000, HIDDEN },
365 [ MRP_WAYLAND_LAYER_FULLSCREEN ] = { 8, 1.000, HIDDEN },
368 static uint32_t surface_hash_id = 1;
369 static mrp_htbl_t *surface_hash;
372 bool mrp_glm_window_manager_register(mrp_wayland_t *wl)
374 mrp_htbl_config_t cfg;
375 mrp_wayland_factory_t factory;
377 memset(&cfg, 0, sizeof(cfg));
378 cfg.nentry = MRP_WAYLAND_WINDOW_MAX;
379 cfg.comp = wid_compare;
381 cfg.nbucket = MRP_WAYLAND_WINDOW_BUCKETS;
383 if (!(surface_hash = mrp_htbl_create(&cfg))) {
384 mrp_log_error("system-controller: can't create hash for surface IDs");
388 factory.size = sizeof(mrp_glm_window_manager_t);
389 factory.interface = &ivi_controller_interface;
390 factory.constructor = window_manager_constructor;
391 factory.destructor = NULL;
392 mrp_wayland_register_interface(wl, &factory);
394 factory.size = sizeof(application_t);
395 factory.interface = &ivi_application_interface;
396 factory.constructor = application_manager_constructor;
397 factory.destructor = NULL;
398 mrp_wayland_register_interface(wl, &factory);
400 factory.size = sizeof(ico_extension_t);
401 factory.interface = &ico_window_mgr_interface;
402 factory.constructor = ico_extension_constructor;
403 factory.destructor = NULL;
404 mrp_wayland_register_interface(wl, &factory);
409 static bool window_manager_constructor(mrp_wayland_t *wl,
410 mrp_wayland_object_t *obj)
412 static struct ivi_controller_listener listener = {
413 .screen = ctrl_screen_callback,
414 .layer = ctrl_layer_callback,
415 .surface = ctrl_surface_callback,
416 .error = ctrl_error_callback,
417 .native_handle = ctrl_native_handle_callback
420 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)obj;
421 mrp_wayland_interface_t *wif;
422 mrp_htbl_config_t scfg, lcfg, ocfg;
426 MRP_ASSERT(wm, "invalid argument");
428 memset(&scfg, 0, sizeof(scfg));
429 scfg.nentry = MRP_WAYLAND_WINDOW_MAX;
430 scfg.comp = id_compare;
431 scfg.hash = sid_hash;
432 scfg.nbucket = MRP_WAYLAND_WINDOW_BUCKETS;
434 memset(&lcfg, 0, sizeof(lcfg));
435 lcfg.nentry = MRP_WAYLAND_LAYER_MAX;
436 lcfg.comp = id_compare;
437 lcfg.hash = lid_hash;
438 lcfg.nbucket = MRP_WAYLAND_LAYER_BUCKETS;
440 memset(&ocfg, 0, sizeof(ocfg));
441 ocfg.nentry = MRP_WAYLAND_OUTPUT_MAX;
442 ocfg.comp = id_compare;
443 ocfg.hash = oid_hash;
444 ocfg.nbucket = MRP_WAYLAND_OUTPUT_BUCKETS;
446 wm->layer_request = layer_request;
447 wm->window_request = window_request;
448 wm->buffer_request = buffer_request;
450 mrp_list_init(&wm->constructors);
452 wm->surfaces = mrp_htbl_create(&scfg);
453 wm->layers = mrp_htbl_create(&lcfg);
454 wm->screens = mrp_htbl_create(&ocfg);
456 MRP_ASSERT(wm->surfaces && wm->layers && wm->screens,
457 "failed to create hash table");
459 sts = ivi_controller_add_listener((struct ivi_controller *)wm->proxy,
465 mrp_wayland_register_window_manager(wl, (mrp_wayland_window_manager_t*)wm);
467 wif = mrp_htbl_lookup(wl->interfaces,
468 (void *)ivi_application_interface.name);
470 if (wif && !mrp_list_empty(&wif->object_list)) {
471 app = mrp_list_entry(wif->object_list.next,
472 application_t, interface_link);
474 mrp_debug("registering application interface to window manager");
482 static int screen_layer_iterator_cb(void *key, void *object, void *user_data)
484 mrp_wayland_layer_t *layer = (mrp_wayland_layer_t *)object;
485 screen_layer_iterator_t *it = (screen_layer_iterator_t *)user_data;
489 if (!strcmp(layer->outputname, it->out->outputname)) {
490 layer_create(it->wm, layer, it->scr);
491 it->need_commit = true;
494 return MRP_HTBL_ITER_MORE;
497 static void ctrl_screen_callback(void *data,
498 struct ivi_controller *ivi_controller,
500 struct ivi_controller_screen *screen)
502 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)data;
504 mrp_wayland_output_t *output;
506 screen_layer_iterator_t it;
508 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
509 MRP_ASSERT(ivi_controller == (struct ivi_controller *)wm->proxy,
510 "confused with data structures");
512 wl = wm->interface->wl;
514 mrp_debug("id_screen=%u screen=%p", id_screen, screen);
516 if (!(output = mrp_wayland_output_find_by_id(wl, id_screen))) {
517 mrp_log_warning("system-controller: can't find output for screen %u",
522 if (!output->name || output->width <= 0 || output->height <= 0) {
523 mrp_log_warning("system-controller: incomplete output (id %u)",
528 if (!(s = mrp_allocz(sizeof(ctrl_screen_t)))) {
529 mrp_log_error("system-controller: can't allocate memory for screen");
534 s->ctrl_screen = screen;
536 s->output_index = output->index;
537 s->width = output->width;
538 s->height = output->height;
543 it.need_commit = false;
544 mrp_htbl_foreach(wl->layers.by_type, screen_layer_iterator_cb, &it);
546 if (it.need_commit) {
547 mrp_debug("calling ivi_controller_commit_changes()");
548 ivi_controller_commit_changes((struct ivi_controller *)wm->proxy);
551 mrp_wayland_flush(wl);
554 static void ctrl_layer_callback(void *data,
555 struct ivi_controller *ivi_controller,
558 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)data;
560 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
561 MRP_ASSERT(ivi_controller == (struct ivi_controller *)wm->proxy,
562 "confused with data structures");
564 mrp_debug("id_layer=%u", id_layer);
567 static void ctrl_surface_callback(void *data,
568 struct ivi_controller *ivi_controller,
573 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)data;
575 struct wl_surface *wl_surface;
578 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
579 MRP_ASSERT(ivi_controller == (struct ivi_controller *)wm->proxy,
580 "confused with data structures");
582 mrp_debug("id_surface=%s pid=%d title='%s'",
583 surface_id_print(id_surface, buf,sizeof(buf)),
584 pid, title ? title:"<null>");
588 if ((c = constructor_find_surface(wm, id_surface, pid, title))) {
591 case CONSTRUCTOR_BOUND:
592 wl_surface = c->wl_surface;
593 /* intentional fall over */
595 case CONSTRUCTOR_TITLED:
596 case CONSTRUCTOR_REQUESTED:
597 if (!title || !title[0])
605 constructor_destroy(c);
608 surface_create(wm, id_surface, pid, title, wl_surface);
612 static void ctrl_error_callback(void *data,
613 struct ivi_controller *ivi_controller,
617 const char *error_text)
619 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)data;
620 const char *type_str;
622 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
623 MRP_ASSERT(ivi_controller == (struct ivi_controller *)wm->proxy,
624 "confused with data structures");
626 switch (object_type) {
627 case IVI_CONTROLLER_OBJECT_TYPE_SURFACE: type_str = "surface"; break;
628 case IVI_CONTROLLER_OBJECT_TYPE_LAYER: type_str = "layer"; break;
629 case IVI_CONTROLLER_OBJECT_TYPE_SCREEN: type_str = "screen"; break;
630 default: type_str = "<unknown>"; break;
636 mrp_debug("%s %d error %d: %s", type_str,object_id, error_code,error_text);
638 switch (object_type) {
640 case IVI_CONTROLLER_OBJECT_TYPE_SURFACE:
641 if (error_code == IVI_CONTROLLER_ERROR_CODE_NATIVE_HANDLE_END) {
642 mrp_debug("native_handle_list end marker");
643 constructor_issue_next_request(wm);
646 mrp_log_error("system-controller: surface error %d: %s",
647 error_code, error_text);
656 static void ctrl_native_handle_callback(void *data,
657 struct ivi_controller *ivi_controller,
658 struct wl_surface *wl_surface)
660 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)data;
662 constructor_t *reqsurf;
664 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
665 MRP_ASSERT(ivi_controller == (struct ivi_controller *)wm->proxy,
666 "confused with data structures");
668 mrp_debug("wl_surface=%p", wl_surface);
670 if (!(app = wm->app)) {
671 mrp_log_error("system-controller: ivi application interface is down "
672 "when %s() is called", __FUNCTION__);
676 reqsurf = constructor_find_first(wm, DOES_MATCH, CONSTRUCTOR_REQUESTED);
679 mrp_debug("no pendig request");
681 /* create an ivi-surface and bind it to wl_surface */
682 reqsurf->id_surface = surface_id_generate();
683 reqsurf->wl_surface = wl_surface;
685 if (constructor_bind_ivi_surface(wm, reqsurf))
686 reqsurf->state = CONSTRUCTOR_BOUND;
691 static ctrl_surface_t *surface_create(mrp_glm_window_manager_t *wm,
695 struct wl_surface *wl_surface)
697 static struct ivi_controller_surface_listener listener = {
698 .visibility = surface_visibility_callback,
699 .opacity = surface_opacity_callback,
700 .source_rectangle = surface_source_rectangle_callback,
701 .destination_rectangle = surface_destination_rectangle_callback,
702 .configuration = surface_configuration_callback,
703 .orientation = surface_orientation_callback,
704 .pixelformat = surface_pixelformat_callback,
705 .layer = surface_added_to_layer_callback,
706 .stats = surface_stats_callback,
707 .destroyed = surface_destroyed_callback,
708 .content = surface_content_callback,
709 .input_focus = surface_input_focus_callback
713 struct ivi_controller *ctrl;
714 struct ivi_controller_surface *ctrl_surface;
720 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
722 wl = wm->interface->wl;
723 ctrl = (struct ivi_controller *)wm->proxy;
725 data = NULL + surface_hash_id++;
727 surface_id_print(id_surface, id_str, sizeof(id_str));
728 get_appid(pid, appid, sizeof(appid));
730 mrp_debug("create surface "
731 "(id=%s pid=%d appid='%s' title='%s' wl_surface=%p)",
732 id_str, pid, appid, title ? title : "<null>", wl_surface);
734 if (surface_find(wm, id_surface)) {
735 mrp_log_error("system-controller: attempt to create multiple times "
736 "surface %s", id_str);
740 if (!(ctrl_surface = ivi_controller_surface_create(ctrl, id_surface))) {
741 mrp_log_error("system-controller: failed to create controller "
742 "surface for surface %s", id_str);
746 mrp_debug("ctrl_surface %p was created for surface %s",
747 ctrl_surface, id_str);
749 if (surface_id_is_ours(id_surface)) {
750 /* The ivi surface was created by us meaning we already had
751 a surfaceless timeout. If title was not set during this
752 time it is pointless to set another timeout to wait for
753 the title. So, we set it to something to prevent furter
759 if (!(sf = mrp_allocz(sizeof(ctrl_surface_t)))) {
760 mrp_log_error("system-controller: failed to allocate memory "
761 "for surface %s", id_str);
766 sf->ctrl_surface = ctrl_surface;
767 sf->wl_surface = wl_surface;
770 sf->appid = mrp_strdup(appid);
771 sf->title = title ? mrp_strdup(title) : NULL;
774 sf->requested_x = MAX_COORDINATE+1;
775 sf->requested_y = MAX_COORDINATE+1;
776 sf->requested_width = -1;
777 sf->requested_height = -1;
781 if (!mrp_htbl_insert(wm->surfaces, &sf->id, sf)) {
782 mrp_log_error("system-controller: hashmap by id: insertion error when "
783 "trying to create surface %s", id_str);
787 if (!mrp_htbl_insert(surface_hash, data, sf)) {
788 mrp_log_error("system-controller: hashmap by data insertion error when"
789 " trying to create surface %s", id_str);
794 if (ivi_controller_surface_add_listener(ctrl_surface,&listener,data) < 0) {
795 mrp_log_error("system-controller: failed to create surface %s "
796 "(can't listen to surface)", id_str);
801 sf->timer.title = mrp_add_timer(wl->ml, TITLE_TIMEOUT,
802 surface_titleless, sf);
805 mrp_wayland_flush(wl);
811 mrp_htbl_remove(wm->surfaces, &sf->id, false);
812 mrp_htbl_remove(surface_hash, data, false);
821 static void surface_destroy(mrp_glm_window_manager_t *wm, ctrl_surface_t *sf)
826 if (wm && wm->surfaces && sf) {
827 mrp_debug("surface %s going to be destroyed",
828 surface_id_print(sf->id, buf, sizeof(buf)));
830 if (!(d = mrp_htbl_remove(wm->surfaces, &sf->id, false)) || sf != d) {
831 mrp_log_error("system-controller: confused with data structures "
832 "(surface hashtable entry mismatch)");
835 mrp_del_timer(sf->timer.title);
838 mrp_wayland_window_destroy(sf->win);
847 static ctrl_surface_t *surface_find(mrp_glm_window_manager_t *wm,
852 if (!wm || !wm->surfaces)
855 sf = mrp_htbl_lookup(wm->surfaces, &id_surface);
861 static void surface_visibility_callback(void *data,
862 struct ivi_controller_surface *ctrl_surface,
867 mrp_glm_window_manager_t *wm;
868 mrp_wayland_window_update_t u;
871 if (!(sf = mrp_htbl_lookup(surface_hash, data))) {
872 mrp_log_error("system-controller: visibility callback "
873 "for non-existent surface");
877 MRP_ASSERT(sf->wl, "invalid argument");
878 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
879 "confused with data structures");
882 wm = (mrp_glm_window_manager_t *)wl->wm;
884 MRP_ASSERT(wm, "data inconsitency");
886 mrp_debug("ctrl_surface=%p (id=%s) visibility=%d", ctrl_surface,
887 surface_id_print(sf->id, buf, sizeof(buf)), visibility);
889 sf->visible = visibility ? true : false;
891 if (surface_is_ready(wm, sf)) {
892 memset(&u, 0, sizeof(u));
893 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
894 MRP_WAYLAND_WINDOW_VISIBLE_MASK;
895 u.surfaceid = sf->id;
896 u.visible = sf->visible;
898 mrp_wayland_window_update(sf->win, MRP_WAYLAND_WINDOW_VISIBLE, &u);
902 static void surface_opacity_callback(void *data,
903 struct ivi_controller_surface *ctrl_surface,
908 mrp_glm_window_manager_t *wm;
909 mrp_wayland_window_update_t u;
912 if (!(sf = mrp_htbl_lookup(surface_hash, data))) {
913 mrp_log_error("system-controller: opacity callback "
914 "for non-existent surface");
918 MRP_ASSERT(sf->wl, "invalid argument");
919 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
920 "confused with data structures");
923 wm = (mrp_glm_window_manager_t *)wl->wm;
925 MRP_ASSERT(wm, "data inconsitency");
926 mrp_debug("ctrl_surface=%p (id=%s) opacity=%d", ctrl_surface,
927 surface_id_print(sf->id, buf, sizeof(buf)), opacity);
929 sf->opacity = wl_fixed_to_double(opacity);
931 if (surface_is_ready(wm, sf)) {
932 memset(&u, 0, sizeof(u));
933 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
934 MRP_WAYLAND_WINDOW_OPACITY_MASK;
935 u.surfaceid = sf->id;
936 u.opacity = sf->opacity;
938 mrp_wayland_window_update(sf->win, MRP_WAYLAND_WINDOW_VISIBLE, &u);
942 static void surface_source_rectangle_callback(void *data,
943 struct ivi_controller_surface *ctrl_surface,
951 mrp_glm_window_manager_t *wm;
954 if (!(sf = mrp_htbl_lookup(surface_hash, data))) {
955 mrp_log_error("system-controller: source_rectangle callback "
956 "for non-existent surface");
960 MRP_ASSERT(sf->wl, "invalid argument");
961 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
962 "confused with data structures");
965 wm = (mrp_glm_window_manager_t *)wl->wm;
967 MRP_ASSERT(wm, "data inconsitency");
969 mrp_debug("ctrl_surface=%p (id=%s) x=%d y=%d width=%d height=%d",
970 ctrl_surface, surface_id_print(sf->id, buf, sizeof(buf)),
971 x, y, width, height);
974 static void surface_destination_rectangle_callback(void *data,
975 struct ivi_controller_surface *ctrl_surface,
983 mrp_glm_window_manager_t *wm;
984 mrp_wayland_window_update_t u;
987 if (!(sf = mrp_htbl_lookup(surface_hash, data))) {
988 mrp_log_error("system-controller: destination_rectangle callback "
989 "for non-existent surface");
993 MRP_ASSERT(sf->wl, "invalid argument");
994 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
995 "confused with data structures");
998 wm = (mrp_glm_window_manager_t *)wl->wm;
1000 MRP_ASSERT(wm, "data inconsitency");
1002 mrp_debug("ctrl_surface=%p (id=%s) x=%d y=%d width=%d height=%d",
1003 ctrl_surface, surface_id_print(sf->id, buf, sizeof(buf)),
1004 x, y, width, height);
1009 sf->height = height;
1011 if (surface_is_ready(wm, sf)) {
1013 * system-controller is the sole authority who manages the
1014 * destination rectangle. So if a rouge app is is fiddling
1015 * with it here we fight back and set it back what it was
1018 * A quick series of legitime requests might result extra
1019 * wayland messages but hopefully will not end up in a infinite
1022 if ((sf->requested_x <= MAX_COORDINATE && x != sf->requested_x ) ||
1023 (sf->requested_y <= MAX_COORDINATE && x != sf->requested_y ) ||
1024 (sf->requested_width > 0 && width != sf->requested_width ) ||
1025 (sf->requested_height > 0 && height != sf->requested_height) )
1027 mrp_debug("calling ivi_controller_surface_set_destination_"
1028 "rectangle(ivi_controller_surface=%p, x=%d, y=%d, "
1029 "width=%d height=%d)", sf->ctrl_surface,
1030 sf->requested_x, sf->requested_y,
1031 sf->requested_width, sf->requested_height);
1033 ivi_controller_surface_set_destination_rectangle(sf->ctrl_surface,
1034 sf->requested_x, sf->requested_y,
1035 sf->requested_width, sf->requested_height);
1038 memset(&u, 0, sizeof(u));
1039 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
1040 MRP_WAYLAND_WINDOW_POSITION_MASK |
1041 MRP_WAYLAND_WINDOW_SIZE_MASK ;
1042 u.surfaceid = sf->id;
1045 u.width = sf->width;
1046 u.height = sf->height;
1048 mrp_wayland_window_update(sf->win, MRP_WAYLAND_WINDOW_CONFIGURE, &u);
1052 static void surface_configuration_callback(void *data,
1053 struct ivi_controller_surface *ctrl_surface,
1059 mrp_glm_window_manager_t *wm;
1062 if (!(sf = mrp_htbl_lookup(surface_hash, data))) {
1063 mrp_log_error("system-controller: configuration callback "
1064 "for non-existent surface");
1068 MRP_ASSERT(sf->wl, "invalid argument");
1069 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1070 "confused with data structures");
1073 wm = (mrp_glm_window_manager_t *)wl->wm;
1075 MRP_ASSERT(wm, "data inconsitency");
1077 mrp_debug("ctrl_surface=%p (id=%s) width=%d height=%d", ctrl_surface,
1078 surface_id_print(sf->id, buf, sizeof(buf)), width, height);
1081 static void surface_orientation_callback(void *data,
1082 struct ivi_controller_surface *ctrl_surface,
1083 int32_t orientation)
1087 mrp_glm_window_manager_t *wm;
1090 if (!(sf = mrp_htbl_lookup(surface_hash, data))) {
1091 mrp_log_error("system-controller: orientation callback "
1092 "for non-existent surface");
1096 MRP_ASSERT(sf->wl, "invalid argument");
1097 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1098 "confused with data structures");
1101 wm = (mrp_glm_window_manager_t *)wl->wm;
1103 MRP_ASSERT(wm, "data inconsitency");
1105 mrp_debug("ctrl_surface=%p (id=%s) orientation=%d", ctrl_surface,
1106 surface_id_print(sf->id, buf, sizeof(buf)), orientation);
1109 static void surface_pixelformat_callback(void *data,
1110 struct ivi_controller_surface *ctrl_surface,
1111 int32_t pixelformat)
1115 mrp_glm_window_manager_t *wm;
1118 if (!(sf = mrp_htbl_lookup(surface_hash, data))) {
1119 mrp_log_error("system-controller: pixelformat callback "
1120 "for non-existent surface");
1124 MRP_ASSERT(sf->wl, "invalid argument");
1125 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1126 "confused with data structures");
1129 wm = (mrp_glm_window_manager_t *)wl->wm;
1131 MRP_ASSERT(wm, "data inconsitency");
1133 mrp_debug("ctrl_surface=%p (id=%s) pixelformat=%d", ctrl_surface,
1134 surface_id_print(sf->id, buf, sizeof(buf)), pixelformat);
1137 static int surface_layer_iterator_cb(void *key, void *object, void *user_data)
1139 ctrl_layer_t *ly = (ctrl_layer_t *)object;
1140 surface_layer_iterator_t *it = (surface_layer_iterator_t *)user_data;
1144 if (it->ctrl_layer == ly->ctrl_layer) {
1146 return MRP_HTBL_ITER_STOP;
1149 return MRP_HTBL_ITER_MORE;
1152 static void surface_added_to_layer_callback(void *data,
1153 struct ivi_controller_surface *ctrl_surface,
1154 struct ivi_controller_layer *ctrl_layer)
1158 mrp_glm_window_manager_t *wm;
1159 mrp_wayland_layer_t *layer;
1160 surface_layer_iterator_t it;
1162 mrp_wayland_window_update_t u;
1165 if (!(sf = mrp_htbl_lookup(surface_hash, data))) {
1166 mrp_log_error("system-controller: added_to_layer callback "
1167 "for non-existent surface");
1171 MRP_ASSERT(sf->wl, "invalid argument");
1172 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1173 "confused with data structures");
1176 wm = (mrp_glm_window_manager_t *)wl->wm;
1178 MRP_ASSERT(wm, "data inconsitency");
1180 surface_id_print(sf->id, id_str, sizeof(id_str));
1182 mrp_debug("ctrl_surface=%p (id=%s) ctrl_layer=%p", ctrl_surface,
1183 id_str, ctrl_layer);
1186 /* surface is removed from a layer */
1187 #if 0 /* silently ignore the removal */
1190 return; /* do not send notification of removal for the time being */
1193 /* surface is added/moved to a layer */
1194 memset(&it, 0, sizeof(it));
1195 it.ctrl_layer = ctrl_layer;
1197 mrp_htbl_foreach(wm->layers, surface_layer_iterator_cb, &it);
1199 if (!(ly = it.ly)) {
1200 mrp_log_error("system-controller: can't update layer of surface %s"
1201 "(ctrl_layer not found)", id_str);
1205 if (!(layer = mrp_wayland_layer_find_by_id(wl, ly->id))) {
1206 mrp_log_error("system-controller: can't update layer of surface %s"
1207 "(layer %d not found)", id_str, ly->id);
1211 if (!surface_is_ready(wm, sf)) {
1212 mrp_log_error("system-controller: attempt to update layer "
1213 "of non-ready surface %s", id_str);
1218 memset(&u, 0, sizeof(u));
1219 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK | MRP_WAYLAND_WINDOW_LAYER_MASK;
1220 u.surfaceid = sf->id;
1223 mrp_wayland_window_update(sf->win, MRP_WAYLAND_WINDOW_CONFIGURE, &u);
1226 static void surface_stats_callback(void *data,
1227 struct ivi_controller_surface *ctrl_surface,
1228 uint32_t redraw_count,
1229 uint32_t frame_count,
1230 uint32_t update_count,
1232 const char *process_name)
1236 mrp_glm_window_manager_t *wm;
1239 if (!(sf = mrp_htbl_lookup(surface_hash, data))) {
1240 mrp_log_error("system-controller: stats callback "
1241 "for non-existent surface");
1245 MRP_ASSERT(sf->wl, "invalid argument");
1246 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1247 "confused with data structures");
1250 wm = (mrp_glm_window_manager_t *)wl->wm;
1252 MRP_ASSERT(wm, "data inconsitency");
1254 mrp_debug("ctrl_surface=%p (id=%s)"
1255 "redraw_count=%u frame_count=%u update_count=%u "
1256 "pid=%u process_name='%s'",
1257 ctrl_surface, surface_id_print(sf->id, buf, sizeof(buf)),
1258 redraw_count, frame_count, update_count, pid,
1259 process_name ? process_name : "<null>");
1261 if (sf->pid != (int32_t)pid) {
1262 mrp_debug("confused with data structures (mismatching pids)");
1268 static void surface_destroyed_callback(void *data,
1269 struct ivi_controller_surface *ctrl_surface)
1273 mrp_glm_window_manager_t *wm;
1277 if (!(sf = mrp_htbl_remove(surface_hash, data, false))) {
1278 mrp_log_error("system-controller: attempt to destroy a nonexistent "
1283 MRP_ASSERT(sf && sf->wl, "invalid argument");
1284 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1285 "confused with data structures");
1288 wm = (mrp_glm_window_manager_t *)wl->wm;
1290 MRP_ASSERT(wm, "data inconsitency");
1292 mrp_debug("ctrl_surface=%p (id=%s)", ctrl_surface,
1293 surface_id_print(sf->id, buf, sizeof(buf)));
1295 if (sf->layerid >= 0 && (ly = layer_find(wm, sf->layerid))) {
1296 layer_remove_surface(ly, sf);
1298 mrp_debug("calling ivi_controller_commit_changes()");
1299 ivi_controller_commit_changes((struct ivi_controller *)wm->proxy);
1301 mrp_wayland_flush(wl);
1304 surface_destroy(wm, sf);
1307 static void surface_content_callback(void *data,
1308 struct ivi_controller_surface *ctrl_surface,
1309 int32_t content_state)
1313 mrp_glm_window_manager_t *wm;
1316 if (!(sf = mrp_htbl_lookup(surface_hash, data))) {
1317 mrp_log_error("system-controller: content callback "
1318 "for non-existent surface");
1322 MRP_ASSERT(sf->wl, "invalid argument");
1323 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1324 "confused with data structures");
1327 wm = (mrp_glm_window_manager_t *)wl->wm;
1329 MRP_ASSERT(wm, "data inconsitency");
1331 mrp_debug("ctrl_surface=%p (id=%s) content_state=%d", ctrl_surface,
1332 surface_id_print(sf->id, buf, sizeof(buf)), content_state);
1336 static void surface_input_focus_callback(void *data,
1337 struct ivi_controller_surface *ctrl_surface,
1343 mrp_glm_window_manager_t *wm;
1346 if (!(sf = mrp_htbl_lookup(surface_hash, data))) {
1347 mrp_log_error("system-controller: input_focus callback "
1348 "for non-existent surface");
1352 MRP_ASSERT(sf->wl, "invalid argument");
1353 MRP_ASSERT(ctrl_surface == sf->ctrl_surface,
1354 "confused with data structures");
1357 wm = (mrp_glm_window_manager_t *)wl->wm;
1359 MRP_ASSERT(wm, "data inconsitency");
1361 mrp_debug("ctrl_surface=%p (id=%s) device=%u enabled=%d", ctrl_surface,
1362 surface_id_print(sf->id, buf, sizeof(buf)), device, enabled);
1365 static bool surface_is_ready(mrp_glm_window_manager_t *wm, ctrl_surface_t *sf)
1368 mrp_wayland_window_update_t u;
1371 ready = sf->win ? true : false;
1373 if (!ready && wm->interface && wm->interface->wl) {
1374 wl = wm->interface->wl;
1383 memset(&u, 0, sizeof(u));
1384 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
1385 MRP_WAYLAND_WINDOW_NAME_MASK |
1386 MRP_WAYLAND_WINDOW_APPID_MASK |
1387 MRP_WAYLAND_WINDOW_PID_MASK |
1388 MRP_WAYLAND_WINDOW_NODEID_MASK |
1389 MRP_WAYLAND_WINDOW_POSITION_MASK |
1390 MRP_WAYLAND_WINDOW_SIZE_MASK ;
1391 u.surfaceid = sf->id;
1393 u.appid = sf->appid;
1395 u.nodeid = sf->nodeid;
1398 u.width = sf->width;
1399 u.height = sf->height;
1401 sf->win = mrp_wayland_window_create(wl, &u);
1403 if (sf->visible || sf->opacity >= 0) {
1404 memset(&u, 0, sizeof(u));
1405 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK;
1406 u.surfaceid = sf->id;
1409 u.mask |= MRP_WAYLAND_WINDOW_VISIBLE_MASK;
1410 u.visible = sf->visible;
1413 if (sf->opacity >= 0) {
1414 u.mask |= MRP_WAYLAND_WINDOW_OPACITY_MASK;
1415 u.opacity = sf->opacity;
1418 mrp_wayland_window_update(sf->win, MRP_WAYLAND_WINDOW_VISIBLE,
1427 static void surface_set_title(mrp_glm_window_manager_t *wm,
1431 mrp_wayland_window_update_t u;
1433 mrp_debug("title='%s'", title);
1435 mrp_del_timer(sf->timer.title);
1436 sf->timer.title = NULL;
1438 if (sf->title && !strcmp(title, sf->title))
1439 mrp_debug("nothing to do (same title)");
1441 mrp_free(sf->title);
1442 sf->title = mrp_strdup(title ? title : "");
1444 if (surface_is_ready(wm, sf)) {
1445 memset(&u, 0, sizeof(u));
1446 u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
1447 MRP_WAYLAND_WINDOW_NAME_MASK;
1448 u.surfaceid = sf->id;
1451 mrp_wayland_window_update(sf->win,MRP_WAYLAND_WINDOW_NAMECHANGE,&u);
1456 static void surface_titleless(mrp_timer_t *timer, void *user_data)
1458 ctrl_surface_t *sf = (ctrl_surface_t *)user_data;
1459 mrp_glm_window_manager_t *wm;
1461 MRP_ASSERT(timer && sf && sf->wl && sf->wl->wm, "invalid argument");
1462 MRP_ASSERT(timer == sf->timer.title, "confused with data structures");
1464 wm = (mrp_glm_window_manager_t *)sf->wl->wm;
1466 mrp_debug("id=%u pid=%d appid='%s'", sf->id, sf->pid, sf->appid);
1468 mrp_del_timer(sf->timer.title);
1469 sf->timer.title = NULL;
1471 surface_set_title(wm, sf, "");
1475 static ctrl_layer_t *layer_create(mrp_glm_window_manager_t *wm,
1476 mrp_wayland_layer_t *layer,
1479 static struct ivi_controller_layer_listener listener = {
1480 .visibility = layer_visibility_callback,
1481 .opacity = layer_opacity_callback,
1482 .source_rectangle = layer_source_rectangle_callback,
1483 .destination_rectangle = layer_destination_rectangle_callback,
1484 .configuration = layer_configuration_callback,
1485 .orientation = layer_orientation_callback,
1486 .screen = layer_added_to_screen_callback,
1487 .destroyed = layer_destroyed_callback
1490 struct ivi_controller_layer *ctrl_layer;
1492 layer_defaults_t *def;
1495 mrp_debug("create and link layer %s (id=0x%08x size=%dx%d) to screen %d",
1496 layer->name, layer->layerid, s->width, s->height, s->id);
1498 ctrl_layer = ivi_controller_layer_create((struct ivi_controller*)wm->proxy,
1500 s->width, s->height);
1502 mrp_log_error("system-controller: can't create controller layer for "
1503 "%s layer (0x%08x)", layer->name, layer->layerid);
1507 if (layer->type < 0 || layer->type >= MRP_WAYLAND_LAYER_TYPE_MAX)
1508 def = layer_defaults;
1510 def = layer_defaults + layer->type;
1512 if (!(ly = mrp_allocz(sizeof(ctrl_layer_t)))) {
1513 mrp_log_error("system-controller: can't allocate memory for layer "
1514 "%s (0x%08x)", layer->name, layer->layerid);
1519 ly->ctrl_layer = ctrl_layer;
1520 ly->id = layer->layerid;
1521 ly->name = mrp_strdup(layer->name);
1523 if (!mrp_htbl_insert(wm->layers, &ly->id, ly)) {
1524 mrp_log_error("system-controller: failed to instantiate layer %s "
1525 "(0x%08x): already exists", layer->name, layer->layerid);
1530 if (ivi_controller_layer_add_listener(ctrl_layer, &listener, ly) < 0) {
1531 mrp_debug("can't listen to layer %s (0x%08x)",
1532 layer->name, layer->layerid);
1533 mrp_htbl_remove(wm->layers, &ly->id, false);
1538 ivi_controller_screen_add_layer(s->ctrl_screen, ctrl_layer);
1541 opacity = wl_fixed_from_double(def->opacity);
1542 mrp_debug("calling ivi_controller_layer_set_opacity"
1543 "(struct ivi_controller_layer=%p, opacity=%d)",
1544 ctrl_layer, opacity);
1545 ivi_controller_layer_set_opacity(ctrl_layer, opacity);
1548 mrp_debug("calling ivi_controller_layer_set_visibility"
1549 "(ivi_controller_layer=%p, visibility=%d)",
1550 ctrl_layer, def->visibility);
1551 ivi_controller_layer_set_visibility(ctrl_layer, def->visibility);
1558 static void layer_destroy(mrp_glm_window_manager_t *wm, ctrl_layer_t *ly)
1562 if (wm && wm->layers && ly) {
1563 mrp_debug("layer %s 0x%08x going to be destroyed", ly->name, ly->id);
1565 if (!(d = mrp_htbl_remove(wm->layers, &ly->id, false)) || ly != d) {
1566 mrp_log_error("system-controller: confused with data structures "
1567 "(layer hashtable mismatch)");
1570 wl_array_release(&ly->surfaces);
1578 static void layer_visibility_callback(void *data,
1579 struct ivi_controller_layer *ctrl_layer,
1582 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1584 mrp_glm_window_manager_t *wm;
1586 MRP_ASSERT(ly && ly->wl, "invalid argument");
1587 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1588 "confused with data structures");
1591 wm = (mrp_glm_window_manager_t *)wl->wm;
1593 MRP_ASSERT(wm, "data inconsitency");
1595 mrp_debug("ctrl_layer=%p (%s %d) visibility=%d", ctrl_layer,
1596 ly->name, ly->id, visibility);
1599 static void layer_opacity_callback(void *data,
1600 struct ivi_controller_layer *ctrl_layer,
1603 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1605 mrp_glm_window_manager_t *wm;
1607 MRP_ASSERT(ly && ly->wl, "invalid argument");
1608 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1609 "confused with data structures");
1612 wm = (mrp_glm_window_manager_t *)wl->wm;
1614 MRP_ASSERT(wm, "data inconsitency");
1616 mrp_debug("ctrl_layer=%p (%s %d) opacity=%d", ctrl_layer,
1617 ly->name, ly->id, opacity);
1620 static void layer_source_rectangle_callback(void *data,
1621 struct ivi_controller_layer *ctrl_layer,
1627 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1629 mrp_glm_window_manager_t *wm;
1631 MRP_ASSERT(ly && ly->wl, "invalid argument");
1632 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1633 "confused with data structures");
1636 wm = (mrp_glm_window_manager_t *)wl->wm;
1638 MRP_ASSERT(wm, "data inconsitency");
1640 mrp_debug("ctrl_layer=%p (%s %d) x=%d y=%d width=%d height=%d", ctrl_layer,
1641 ly->name, ly->id, x,y, width,height);
1644 static void layer_destination_rectangle_callback(void *data,
1645 struct ivi_controller_layer *ctrl_layer,
1651 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1653 mrp_glm_window_manager_t *wm;
1655 MRP_ASSERT(ly && ly->wl, "invalid argument");
1656 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1657 "confused with data structures");
1660 wm = (mrp_glm_window_manager_t *)wl->wm;
1662 MRP_ASSERT(wm, "data inconsitency");
1664 mrp_debug("ctrl_layer=%p (%s %d) x=%d y=%d width=%d height=%d", ctrl_layer,
1665 ly->name, ly->id, x,y, width,height);
1668 static void layer_configuration_callback(void *data,
1669 struct ivi_controller_layer *ctrl_layer,
1673 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1675 mrp_glm_window_manager_t *wm;
1677 MRP_ASSERT(ly && ly->wl, "invalid argument");
1678 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1679 "confused with data structures");
1682 wm = (mrp_glm_window_manager_t *)wl->wm;
1684 MRP_ASSERT(wm, "data inconsitency");
1686 mrp_debug("ctrl_layer=%p (%s %d) width=%d height=%d", ctrl_layer,
1687 ly->name, ly->id, width,height);
1690 static void layer_orientation_callback(void *data,
1691 struct ivi_controller_layer *ctrl_layer,
1692 int32_t orientation)
1694 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1696 mrp_glm_window_manager_t *wm;
1698 MRP_ASSERT(ly && ly->wl, "invalid argument");
1699 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1700 "confused with data structures");
1703 wm = (mrp_glm_window_manager_t *)wl->wm;
1705 MRP_ASSERT(wm, "data inconsitency");
1707 mrp_debug("ctrl_layer=%p (%s %d) orientation=%d", ctrl_layer,
1708 ly->name, ly->id, orientation);
1711 static void layer_added_to_screen_callback(void *data,
1712 struct ivi_controller_layer *ctrl_layer,
1713 struct wl_output *screen)
1715 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1717 mrp_glm_window_manager_t *wm;
1719 MRP_ASSERT(ly && ly->wl, "invalid argument");
1720 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1721 "confused with data structures");
1724 wm = (mrp_glm_window_manager_t *)wl->wm;
1726 MRP_ASSERT(wm, "data inconsitency");
1728 mrp_debug("ctrl_layer=%p (%s %d) screen=%p", ctrl_layer,
1729 ly->name, ly->id, screen);
1732 static void layer_destroyed_callback(void *data,
1733 struct ivi_controller_layer *ctrl_layer)
1735 ctrl_layer_t *ly = (ctrl_layer_t *)data;
1737 mrp_glm_window_manager_t *wm;
1739 MRP_ASSERT(ly && ly->wl, "invalid argument");
1740 MRP_ASSERT(ctrl_layer == ly->ctrl_layer,
1741 "confused with data structures");
1744 wm = (mrp_glm_window_manager_t *)wl->wm;
1746 MRP_ASSERT(wm, "data inconsitency");
1748 mrp_debug("ctrl_layer=%p (%s %d)", ctrl_layer, ly->name, ly->id);
1752 static bool layer_add_surface_to_bottom(ctrl_layer_t *ly, ctrl_surface_t *sf)
1754 uint32_t *last, *pos;
1757 MRP_ASSERT(ly && sf, "invalid argument");
1758 MRP_ASSERT(ly->id == sf->layerid, "mismatching layer ID's");
1760 surface_id_print(sf->id, id_str, sizeof(id_str));
1762 wl_array_for_each(pos, &ly->surfaces) {
1763 if (*pos == (uint32_t)sf->id) {
1764 mrp_log_error("system-controller: can't add surface %s to the "
1765 "bottom of layer %d (surface already exists)",
1766 id_str, sf->layerid);
1771 if (!(last = wl_array_add(&ly->surfaces, sizeof(uint32_t)))) {
1772 mrp_log_error("system-controller: can't add surface %s to the bottom "
1773 "of layer %d (no memory)", id_str, sf->layerid);
1777 for (pos = last; (void *)pos > ly->surfaces.data; pos--)
1782 mrp_debug("surface %s added to the bottom of layer %d",
1783 id_str, sf->layerid);
1785 layer_send_surfaces(ly);
1791 static bool layer_add_surface_to_top(ctrl_layer_t *ly, ctrl_surface_t *sf)
1793 uint32_t *last, *pos;
1796 MRP_ASSERT(ly && sf, "invalid argument");
1797 MRP_ASSERT(ly->id == sf->layerid, "mismatching layer ID's");
1799 surface_id_print(sf->id, id_str, sizeof(id_str));
1801 wl_array_for_each(pos, &ly->surfaces) {
1802 if (*pos == (uint32_t)sf->id) {
1803 mrp_log_error("system-controller: can't add surface %s to the "
1804 "top of layer %d (surface already exists)",
1805 id_str, sf->layerid);
1810 if (!(last = wl_array_add(&ly->surfaces, sizeof(uint32_t)))) {
1811 mrp_log_error("system-controller: can't add surface %s to the top "
1812 "of layer %d (no memory)", id_str, sf->layerid);
1818 mrp_debug("surface %s added to the top of layer %d", id_str, sf->layerid);
1820 layer_send_surfaces(ly);
1825 static bool layer_move_surface_to_bottom(ctrl_layer_t *ly, ctrl_surface_t *sf)
1827 uint32_t *pos, *first, *last;
1832 MRP_ASSERT(ly && sf, "invalid argument");
1833 MRP_ASSERT(ly->id == sf->layerid, "mismatching layer ID's");
1835 surface_id_print(sf->id, id_str, sizeof(id_str));
1837 dim = ly->surfaces.size / sizeof(uint32_t);
1838 first = (uint32_t *)ly->surfaces.data;
1839 last = first + (dim - 1);
1843 for (pos = last; pos >= first; pos--) {
1844 if (pos[0] == (uint32_t)sf->id)
1851 mrp_debug("failed to move surface %s to bottom of layer %d "
1852 "(can't find surface)", id_str, sf->layerid);
1856 *first = (uint32_t)sf->id;
1858 mrp_debug("surface %s moved to bottom of layer %d", id_str, sf->layerid);
1860 layer_send_surfaces(ly);
1865 static bool layer_move_surface_to_top(ctrl_layer_t *ly, ctrl_surface_t *sf)
1867 uint32_t *pos, *first, *last;
1872 MRP_ASSERT(ly && sf, "invalid argument");
1873 MRP_ASSERT(ly->id == sf->layerid, "mismatching layer ID's");
1875 surface_id_print(sf->id, id_str, sizeof(id_str));
1877 dim = ly->surfaces.size / sizeof(uint32_t);
1878 first = (uint32_t *)ly->surfaces.data;
1879 last = first + (dim - 1);
1883 wl_array_for_each(pos, &ly->surfaces) {
1884 if (pos[0] == (uint32_t)sf->id)
1891 mrp_debug("failed to move surface %s to top of layer %d "
1892 "(can't find surface)", id_str, sf->layerid);
1896 *last = (uint32_t)sf->id;
1898 mrp_debug("surface %s moved to top of layer %d", id_str, sf->layerid);
1900 layer_send_surfaces(ly);
1905 static bool layer_remove_surface(ctrl_layer_t *ly, ctrl_surface_t *sf)
1911 MRP_ASSERT(ly && sf, "invalid argument");
1912 MRP_ASSERT(ly->id == sf->layerid, "mismatching layer ID's");
1914 surface_id_print(sf->id, id_str, sizeof(id_str));
1917 wl_array_for_each(pos, &ly->surfaces) {
1918 if (pos[0] == (uint32_t)sf->id)
1925 mrp_debug("failed to remove surface %s from layer %d "
1926 "(can't find surface)", id_str, sf->layerid);
1930 ly->surfaces.size -= sizeof(uint32_t);
1932 mrp_debug("surface %s removed from layer %d", id_str, sf->layerid);
1934 mrp_debug("calling ivi_controller_layer_remove_surface"
1935 "(ivi_controller_layer=%p, surface=%p)",
1936 ly->ctrl_layer, sf->ctrl_surface);
1937 ivi_controller_layer_remove_surface(ly->ctrl_layer, sf->ctrl_surface);
1939 layer_send_surfaces(ly);
1944 static void layer_send_surfaces(ctrl_layer_t *ly)
1950 e = (p = buf) + sizeof(buf);
1953 wl_array_for_each(id_ptr, &ly->surfaces) {
1957 p += snprintf(p, e-p, "%s%u", s, *id_ptr);
1962 mrp_debug("calling ivi_controller_layer_set_render_order"
1963 "(ivi_controller_layer=%p, id_surfaces=[%s])",
1964 ly->ctrl_layer, buf);
1966 ivi_controller_layer_set_render_order(ly->ctrl_layer, &ly->surfaces);
1970 static bool application_manager_constructor(mrp_wayland_t *wl,
1971 mrp_wayland_object_t *obj)
1973 static struct ivi_application_listener listener = {
1974 .wl_shell_info = shell_info_callback
1977 application_t *app = (application_t *)obj;
1978 mrp_glm_window_manager_t *wm;
1981 MRP_ASSERT(wl && app, "invalid argument");
1983 sts = ivi_application_add_listener((struct ivi_application *)app->proxy,
1988 if ((wm = (mrp_glm_window_manager_t *)wl->wm)) {
1989 mrp_debug("registering application interface to window manager");
1996 static void shell_info_callback(void *data,
1997 struct ivi_application *ivi_application,
2000 uint32_t id_surface)
2002 application_t *app = (application_t *)data;
2004 mrp_glm_window_manager_t *wm;
2006 mrp_list_hook_t *c, *n;
2007 constructor_t *entry, *found;
2008 constructor_state_t state;
2012 MRP_ASSERT(pid > 0 && title, "invalid argument");
2013 MRP_ASSERT(app && app->interface && app->interface->wl,"invalid argument");
2014 MRP_ASSERT(ivi_application == (struct ivi_application *)app->proxy,
2015 "confused with data structures");
2017 wl = app->interface->wl;
2019 mrp_debug("pid=%d title='%s' id_surface=%s",
2020 pid, title ? title : "<null>",
2021 surface_id_print(id_surface, buf, sizeof(buf)));
2023 if (!(wm = (mrp_glm_window_manager_t *)wl->wm)) {
2024 mrp_debug("controller interface is not ready");
2028 has_title = (title && title[0]);
2034 constructor_create(wm, CONSTRUCTOR_INCOMPLETE, pid, NULL, 0);
2036 /* try to find an incomplete constructor with a matching pid */
2039 mrp_list_foreach(&wm->constructors, c, n) {
2040 entry = mrp_list_entry(c, constructor_t, link);
2042 if (pid == entry->pid) {
2043 if ((entry->state == CONSTRUCTOR_INCOMPLETE) ||
2044 (entry->state == CONSTRUCTOR_TITLED &&
2045 !strcmp(title, entry->title) ) )
2054 constructor_create(wm, CONSTRUCTOR_TITLED, pid, title, 0);
2056 constructor_set_title(wm, found, title);
2060 /* we have a surface ID */
2062 if (!(sf = surface_find(wm, id_surface))) {
2063 /* no surface found with the ID */
2065 /* try to find a matching constructor */
2066 found = constructor_find_surface(wm, id_surface, pid, title);
2070 state = CONSTRUCTOR_TITLED;
2072 state = CONSTRUCTOR_INCOMPLETE;
2074 constructor_create(wm, state, pid, title, id_surface);
2077 if (id_surface > 0) {
2078 /* found a constructor with the ID */
2079 if (pid != found->pid) {
2080 mrp_log_error("system-controller: confused with "
2081 "surface constructors "
2082 "(mismatching PIDs: %d vs. %d)",
2087 constructor_set_title(wm, found, title);
2091 mrp_debug("found a constructor with matching pid/title. "
2094 found->id_surface = id_surface;
2096 if (found->timer.surfaceless) {
2097 mrp_del_timer(found->timer.surfaceless);
2098 found->timer.surfaceless = NULL;
2102 constructor_set_title(wm, found, title);
2107 /* found a surface with the ID */
2108 if (pid != sf->pid) {
2109 mrp_log_error("system-controller: confused with control "
2110 "surfaces (mismatching PIDs: %d vs. %d)",
2115 surface_set_title(wm, sf, title);
2122 static bool ico_extension_constructor(mrp_wayland_t *wl,
2123 mrp_wayland_object_t *obj)
2125 static struct ico_window_mgr_listener listener = {
2126 .window_active = ico_extension_window_active_callback,
2127 .map_surface = ico_extension_map_surface_callback,
2128 .update_surface = ico_extension_update_surface_callback,
2129 .destroy_surface = ico_extension_destroy_surface_callback
2132 ico_extension_t *ico = (ico_extension_t *)obj;
2133 mrp_glm_window_manager_t *wm;
2136 if (!(wm = (mrp_glm_window_manager_t *)(wl->wm))) {
2137 mrp_log_error("system-controller: phase error in %s(): "
2138 "window manager does not exist", __FUNCTION__);
2142 sts = ico_window_mgr_add_listener((struct ico_window_mgr *)ico->proxy,
2153 static void ico_extension_window_active_callback(void *data,
2154 struct ico_window_mgr *ico_window_mgr,
2158 ico_extension_t *ico = (ico_extension_t *)data;
2160 mrp_glm_window_manager_t *wm;
2162 mrp_wayland_window_t *win;
2163 mrp_wayland_window_update_t u;
2166 MRP_ASSERT(ico && ico->interface && ico->interface->wl,
2167 "invalid argument");
2168 MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)ico->proxy,
2169 "confused with data structures");
2171 wl = ico->interface->wl;
2172 wm = (mrp_glm_window_manager_t *)(wl->wm);
2174 MRP_ASSERT(wm, "data inconsitency");
2176 mrp_debug("surfaceid=%u select=%d", surfaceid, select);
2179 mrp_debug("ignoring select=0 events");
2183 surface_id_print(surfaceid, id_str, sizeof(id_str));
2185 if (!(sf = surface_find(wm, surfaceid))) {
2186 mrp_debug("can't find surface for id=%s", id_str);
2190 if (!(win = sf->win)) {
2191 mrp_debug("can't forward selection event for surface id=%s "
2192 "(no window)", id_str);
2196 memset(&u, 0, sizeof(u));
2197 u.mask = MRP_WAYLAND_WINDOW_ACTIVE_MASK;
2200 if ((select & ICO_WINDOW_MGR_SELECT_POINTER))
2201 u.active |= MRP_WAYLAND_WINDOW_ACTIVE_POINTER;
2202 if ((select & ICO_WINDOW_MGR_SELECT_TOUCH))
2203 u.active |= MRP_WAYLAND_WINDOW_ACTIVE_TOUCH;
2205 mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_ACTIVE, &u);
2209 static void ico_extension_map_surface_callback(void *data,
2210 struct ico_window_mgr *ico_window_mgr,
2219 ico_extension_t *ico = (ico_extension_t *)data;
2221 mrp_glm_window_manager_t *wm;
2223 mrp_wayland_window_t *win;
2224 mrp_wayland_window_update_t u;
2225 mrp_wayland_window_map_t map;
2228 MRP_ASSERT(ico && ico->interface && ico->interface->wl,
2229 "invalid argument");
2230 MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)ico->proxy,
2231 "confused with data structures");
2233 wl = ico->interface->wl;
2234 wm = (mrp_glm_window_manager_t *)(wl->wm);
2236 MRP_ASSERT(wm, "data inconsitency");
2238 mrp_debug("event=%d surfaceid=%u type=%u width=%d height=%d stride=%d "
2240 event, surfaceid, type, width,height, stride, format);
2242 surface_id_print(surfaceid, id_str, sizeof(id_str));
2244 if (!(sf = surface_find(wm, surfaceid))) {
2245 mrp_debug("can't find surface for id=%s", id_str);
2249 if (!(win = sf->win)) {
2250 mrp_debug("can't forward map event for surface id=%s "
2251 "(no window)", id_str);
2255 memset(&map, 0, sizeof(map));
2258 map.height = height;
2259 map.stride = stride;
2260 map.format = format;
2262 memset(&u, 0, sizeof(u));
2263 u.mask = MRP_WAYLAND_WINDOW_MAPPED_MASK | MRP_WAYLAND_WINDOW_MAP_MASK;
2268 case ICO_WINDOW_MGR_MAP_SURFACE_EVENT_CONTENTS:
2269 case ICO_WINDOW_MGR_MAP_SURFACE_EVENT_RESIZE:
2270 case ICO_WINDOW_MGR_MAP_SURFACE_EVENT_MAP:
2274 case ICO_WINDOW_MGR_MAP_SURFACE_EVENT_UNMAP:
2275 case ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR:
2280 mrp_debug("ignoring unknown event type %d event", event);
2284 mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_MAP, &u);
2287 static void ico_extension_update_surface_callback(void *data,
2288 struct ico_window_mgr *ico_window_mgr,
2298 ico_extension_t *ico = (ico_extension_t *)data;
2300 mrp_glm_window_manager_t *wm;
2302 MRP_ASSERT(ico && ico->interface && ico->interface->wl,
2303 "invalid argument");
2304 MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)ico->proxy,
2305 "confused with data structures");
2307 wl = ico->interface->wl;
2308 wm = (mrp_glm_window_manager_t *)(wl->wm);
2310 MRP_ASSERT(wm, "data inconsitency");
2312 mrp_debug("surfaceid=%u visible=%d srcwidth=%d srcheight=%d x=%d y=%d "
2313 "width=%d height=%d",
2314 surfaceid, visible, srcwidth,srcheight, x,y, width,height);
2318 static void ico_extension_destroy_surface_callback(void *data,
2319 struct ico_window_mgr *ico_window_mgr,
2322 ico_extension_t *ico = (ico_extension_t *)data;
2324 mrp_glm_window_manager_t *wm;
2326 MRP_ASSERT(ico && ico->interface && ico->interface->wl,
2327 "invalid argument");
2328 MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)ico->proxy,
2329 "confused with data structures");
2331 wl = ico->interface->wl;
2332 wm = (mrp_glm_window_manager_t *)(wl->wm);
2334 MRP_ASSERT(wm, "data inconsitency");
2336 mrp_debug("surfaceid=%u", surfaceid);
2342 static uint32_t surface_id_generate(void)
2344 #define FIRST_ID (SURFACE_ID_OUR_FLAG | 1)
2345 #define MAX_ID (SURFACE_ID_OUR_FLAG | SURFACE_ID_MAX)
2347 static uint32_t id = FIRST_ID;
2358 static bool surface_id_is_ours(uint32_t id)
2360 return ((id & SURFACE_ID_OUR_FLAG) == SURFACE_ID_OUR_FLAG) ? true : false;
2363 static char *surface_id_print(uint32_t id, char *buf, size_t len)
2366 snprintf(buf, len, "<not set>");
2368 snprintf(buf, len, "%u(%s-id-%u)", id,
2369 surface_id_is_ours(id) ? "our":"native",
2370 (id & SURFACE_ID_MAX));
2376 static constructor_t *constructor_create(mrp_glm_window_manager_t *wm,
2377 constructor_state_t state,
2380 uint32_t id_surface)
2386 MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
2388 wl = wm->interface->wl;
2390 if (!(c = mrp_allocz(sizeof(constructor_t)))) {
2391 mrp_log_error("system-controller: can't allocate memory for surface"
2392 "(pid=%d title='%s' id_surface=%s)",
2393 pid, title ? title : "<null>",
2394 surface_id_print(id_surface, buf, sizeof(buf)));
2398 mrp_list_init(&c->link);
2402 c->title = title ? mrp_strdup(title) : NULL;
2403 c->id_surface = id_surface;
2404 c->timer.timeout = mrp_add_timer(wl->ml, CONSTRUCTOR_TIMEOUT,
2405 constructor_timeout, c);
2408 c->timer.surfaceless = mrp_add_timer(wl->ml, SURFACELESS_TIMEOUT,
2409 constructor_surfaceless, c);
2412 mrp_list_append(&wm->constructors, &c->link);
2414 mrp_debug("constructor created (state=%s, pid=%d, title='%s' "
2415 "id_surface=%u)", constructor_state_str(state), pid,
2416 title ? title: "<null>", id_surface);
2421 static void constructor_destroy(constructor_t *c)
2426 mrp_debug("surface %s of application (pid=%d) destroyed",
2427 surface_id_print(c->id_surface, buf, sizeof(buf)), c->pid);
2429 mrp_del_timer(c->timer.timeout);
2430 mrp_del_timer(c->timer.surfaceless);
2432 mrp_list_delete(&c->link);
2439 static void constructor_timeout(mrp_timer_t *timer, void *user_data)
2441 constructor_t *c = (constructor_t *)user_data;
2442 mrp_glm_window_manager_t *wm;
2445 MRP_ASSERT(timer && c && c->wm, "invalid argument");
2446 MRP_ASSERT(timer == c->timer.timeout, "confused with data structures");
2448 mrp_debug("pid=%d title='%s' id_surface=%s state=%s",
2449 c->pid, c->title ? c->title : "",
2450 surface_id_print(c->id_surface, buf, sizeof(buf)),
2451 constructor_state_str(c->state));
2455 constructor_destroy(c);
2456 constructor_issue_next_request(wm);
2459 static void constructor_surfaceless(mrp_timer_t *timer, void *user_data)
2461 constructor_t *c = (constructor_t *)user_data;
2462 mrp_glm_window_manager_t *wm;
2464 MRP_ASSERT(timer && c && c->wm, "invalid argument");
2465 MRP_ASSERT(timer == c->timer.surfaceless, "confused with data structures");
2467 mrp_debug("pid=%d title='%s' state=%s",
2468 c->pid, c->title ? c->title : "<not set>",
2469 constructor_state_str(c->state));
2473 mrp_del_timer(c->timer.surfaceless);
2474 c->timer.surfaceless = NULL;
2476 c->state = CONSTRUCTOR_SURFACELESS;
2477 constructor_issue_next_request(wm);
2480 static constructor_t *constructor_find_first(mrp_glm_window_manager_t *wm,
2482 constructor_state_t state)
2484 mrp_list_hook_t *c, *n;
2485 constructor_t *entry;
2487 mrp_list_foreach(&wm->constructors, c, n) {
2488 entry = mrp_list_entry(c, constructor_t, link);
2490 if (( match && state == entry->state) ||
2491 (!match && state != entry->state))
2498 static constructor_t *constructor_find_surface(mrp_glm_window_manager_t *wm,
2499 uint32_t id_surface,
2503 mrp_list_hook_t *c, *n;
2504 constructor_t *entry, *candidate;
2505 bool candidate_titleless;
2508 candidate_titleless = false;
2510 mrp_list_foreach(&wm->constructors, c, n) {
2511 entry = mrp_list_entry(c, constructor_t, link);
2513 if (id_surface > 0) {
2514 if (id_surface == entry->id_surface)
2518 if (pid == entry->pid) {
2519 if (entry->state == CONSTRUCTOR_INCOMPLETE) {
2520 if (!title && !candidate)
2524 if (title && !strcmp(title, entry->title)) {
2525 if (!candidate || !candidate_titleless) {
2527 candidate_titleless = false;
2538 static constructor_t *constructor_find_bound(mrp_glm_window_manager_t *wm,
2539 uint32_t id_surface)
2541 mrp_list_hook_t *c, *n;
2542 constructor_t *entry;
2544 if (id_surface > 0) {
2545 mrp_list_foreach(&wm->constructors, c, n) {
2546 entry = mrp_list_entry(c, constructor_t, link);
2548 if (id_surface == entry->id_surface &&
2549 entry->state == CONSTRUCTOR_BOUND)
2558 static void constructor_set_title(mrp_glm_window_manager_t *wm,
2564 if (title && title[0]) {
2565 mrp_free((void *)c->title);
2566 c->title = title ? mrp_strdup(title) : NULL;
2568 mrp_debug("constructor title changed to '%s'", c->title);
2570 if (c->state == CONSTRUCTOR_INCOMPLETE) {
2571 c->state = CONSTRUCTOR_TITLED;
2572 mrp_debug("constructor state changed to %s",
2573 constructor_state_str(c->state));
2578 static void constructor_issue_next_request(mrp_glm_window_manager_t *wm)
2580 mrp_list_hook_t *c, *n;
2581 constructor_t *entry;
2583 mrp_debug("loop through constructors ...");
2585 mrp_list_foreach(&wm->constructors, c, n) {
2586 entry = mrp_list_entry(c, constructor_t, link);
2588 mrp_debug(" state %s", constructor_state_str(entry->state));
2590 if (entry->state == CONSTRUCTOR_SURFACELESS) {
2591 mrp_debug(" call ivi_controller_get_native_handle"
2592 "(pid=%d title='%s')", entry->pid,
2593 entry->title ? entry->title : "<not set>");
2595 ivi_controller_get_native_handle((struct ivi_controller*)wm->proxy,
2596 entry->pid, entry->title);
2598 entry->state = CONSTRUCTOR_REQUESTED;
2600 mrp_wayland_flush(wm->interface->wl);
2605 if (entry->state == CONSTRUCTOR_REQUESTED)
2609 mrp_debug(" do not issue native handle request");
2612 static bool constructor_bind_ivi_surface(mrp_glm_window_manager_t *wm,
2615 struct ivi_surface *ivi_surface;
2619 if (!wm || !(app = wm->app) || !c)
2622 if (!c->id_surface) {
2623 mrp_log_error("system-controller: failed to create ivi-surface "
2624 "(id_surface is not set)");
2628 if (!c->wl_surface) {
2629 mrp_log_error("system-controller: failed to create ivi-surface "
2630 "(wl_surface not set)");
2634 mrp_debug("call ivi_application_surface_create(id_surface=%s surface=%p)",
2635 surface_id_print(c->id_surface, buf,sizeof(buf)), c->wl_surface);
2637 ivi_surface = ivi_application_surface_create(
2638 (struct ivi_application *)app->proxy,
2639 c->id_surface, c->wl_surface);
2641 mrp_log_error("system-controller: failed to create "
2642 "ivi-application-surface (id=%s)",
2643 surface_id_print(c->id_surface, buf, sizeof(buf)));
2650 static char *constructor_state_str(constructor_state_t state)
2653 case CONSTRUCTOR_FAILED: return "failed";
2654 case CONSTRUCTOR_INCOMPLETE: return "incomplete";
2655 case CONSTRUCTOR_TITLED: return "titled";
2656 case CONSTRUCTOR_SURFACELESS: return "surfaceless";
2657 case CONSTRUCTOR_REQUESTED: return "requested";
2658 case CONSTRUCTOR_BOUND: return "bound";
2659 default: return "<unknown>";
2663 static ctrl_layer_t *layer_find(mrp_glm_window_manager_t *wm, int32_t id_layer)
2667 if (!wm || !wm->layers)
2670 ly = mrp_htbl_lookup(wm->layers, &id_layer);
2675 static bool set_layer_visibility(mrp_wayland_layer_t *layer,
2676 mrp_wayland_layer_update_mask_t passthrough,
2677 mrp_wayland_layer_update_t *u)
2679 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)layer->wm;
2681 uint32_t visibility;
2685 if (!(ly = layer_find(wm, layer->layerid))) {
2686 mrp_debug("can't find layer");
2690 visibility = u->visible ? 1 : 0;
2692 mrp_debug("call ivi_controller_layer_set_visibility"
2693 "(ivi_controller_layer=%p, visibility=%u)",
2694 ly->ctrl_layer, visibility);
2696 ivi_controller_layer_set_visibility(ly->ctrl_layer, visibility);
2701 static void layer_request(mrp_wayland_layer_t *layer,
2702 mrp_wayland_layer_update_t *u)
2705 mrp_glm_window_manager_t *wm;
2706 mrp_wayland_layer_update_mask_t mask;
2707 mrp_wayland_layer_update_mask_t passthrough;
2711 MRP_ASSERT(layer && layer->wm && layer->wm->proxy &&
2712 layer->wm->interface && layer->wm->interface->wl,
2713 "invalid argument");
2715 wm = (mrp_glm_window_manager_t *)layer->wm;
2716 wl = wm->interface->wl;
2717 passthrough = wm->passthrough.layer_request;
2721 mrp_wayland_layer_request_print(u, buf, sizeof(buf));
2722 mrp_debug("request for layer %d update:%s", layer->layerid, buf);
2725 if ((mask & MRP_WAYLAND_LAYER_VISIBLE_MASK)) {
2726 changed |= set_layer_visibility(layer, passthrough, u);
2727 mask &= ~MRP_WAYLAND_LAYER_VISIBLE_MASK;
2736 mrp_debug("calling ivi_controller_commit_changes()");
2737 ivi_controller_commit_changes((struct ivi_controller *)wm->proxy);
2740 mrp_wayland_flush(wl);
2744 static void set_window_animation(mrp_wayland_window_t *win,
2745 mrp_wayland_animation_type_t type,
2746 mrp_wayland_animation_t *anims)
2748 static int32_t ico_types[MRP_WAYLAND_ANIMATION_MAX] = {
2749 [MRP_WAYLAND_ANIMATION_HIDE] = ICO_WINDOW_MGR_ANIMATION_TYPE_HIDE,
2750 [MRP_WAYLAND_ANIMATION_SHOW] = ICO_WINDOW_MGR_ANIMATION_TYPE_SHOW,
2751 [MRP_WAYLAND_ANIMATION_MOVE] = ICO_WINDOW_MGR_ANIMATION_TYPE_MOVE,
2752 [MRP_WAYLAND_ANIMATION_RESIZE] = ICO_WINDOW_MGR_ANIMATION_TYPE_RESIZE
2755 mrp_glm_window_manager_t *wm;
2756 ico_extension_t *ico;
2757 struct ico_window_mgr *ico_window_mgr;
2758 mrp_wayland_animation_t *a;
2760 MRP_ASSERT(win && win->wm, "invalid argument");
2762 wm = (mrp_glm_window_manager_t *)(win->wm);
2766 mrp_debug("can't animate on window %u (ico-extension not available)",
2771 ico_window_mgr = (struct ico_window_mgr *)ico->proxy;
2773 if (anims && type >= 0 && type < MRP_WAYLAND_ANIMATION_MAX) {
2776 if (a->name && a->name[0] && a->time > 0) {
2777 mrp_debug("calling ico_window_mgr_set_animation"
2778 "(surfaceid=%d type=%d, animation='%s' time=%d)",
2779 win->surfaceid, ico_types[type], a->name, a->time);
2781 ico_window_mgr_set_animation(ico_window_mgr, win->surfaceid,
2782 ico_types[type], a->name, a->time);
2787 static bool set_window_layer(mrp_wayland_window_t *win,
2788 mrp_wayland_window_update_mask_t passthrough,
2789 mrp_wayland_window_update_t *u)
2791 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
2797 mrp_wayland_window_update_t u2;
2803 mrp_log_error("system-controller: broken request (layer is <null>)");
2807 id_surface = win->surfaceid;
2808 id_layer = u->layer->layerid;
2810 if (!(sf = surface_find(wm, id_surface))) {
2811 mrp_debug("can't find surface %s",
2812 surface_id_print(id_surface, buf, sizeof(buf)));
2816 if (!(ly = layer_find(wm, id_layer))) {
2817 mrp_debug("can't find layer %d", id_layer);
2821 if (sf->layerid == id_layer) {
2822 if ((u->mask & MRP_WAYLAND_WINDOW_RAISE_MASK))
2825 changed = layer_move_surface_to_top(ly, sf);
2828 sf->layerid = id_layer;
2829 changed = layer_add_surface_to_top(ly, sf);
2833 memset(&u2, 0, sizeof(u2));
2834 u2.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
2835 MRP_WAYLAND_WINDOW_RAISE_MASK;
2836 u2.surfaceid = win->surfaceid;
2839 mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_VISIBLE, &u2);
2845 static bool set_window_mapped(mrp_wayland_window_t *win,
2846 mrp_wayland_window_update_mask_t passthrough,
2847 mrp_wayland_window_update_t *u,
2848 mrp_wayland_animation_t *anims,
2851 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
2852 ico_extension_t *ico = wm->ico;
2854 struct ico_window_mgr *ico_window_mgr;
2855 const char *filepath;
2858 ico_window_mgr = ico ? (struct ico_window_mgr *)ico->proxy : NULL;
2859 id_surface = win->surfaceid;
2861 surface_id_print(id_surface, id_str, sizeof(id_str));
2863 if (((u->mapped && win->mapped) || (!u->mapped && !win->mapped)) &&
2864 !(passthrough & MRP_WAYLAND_WINDOW_MAPPED_MASK))
2866 mrp_debug("nothing to do");
2871 if (!anims || !(filepath = anims[MRP_WAYLAND_ANIMATION_MAP].name)) {
2872 mrp_log_error("system-controller: broken map request "
2877 if (!ico_window_mgr) {
2878 mrp_debug("can't map surface %s to file '%s' (ico-extension not "
2879 "available)", id_str, filepath);
2886 mrp_debug("calling ico_window_mgr_map_surface"
2887 "(ico_window_mgr=%p, surfaceid=%u, framerate=%d, "
2889 ico_window_mgr, id_surface, framerate, filepath);
2891 ico_window_mgr_map_surface(ico_window_mgr, id_surface, framerate,
2895 if (!ico_window_mgr) {
2896 mrp_debug("can't unmap surface %s (ico-extension not available)",
2901 mrp_debug("calling ico_window_mgr_unmap_surface"
2902 "(ico_window_mgr=%p, surfaceid=%u)",
2903 ico_window_mgr, id_surface);
2905 ico_window_mgr_unmap_surface(ico_window_mgr, id_surface);
2911 static bool set_window_geometry(mrp_wayland_window_t *win,
2912 mrp_wayland_window_update_mask_t passthrough,
2913 mrp_wayland_window_update_t *u,
2914 mrp_wayland_animation_t *anims)
2916 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
2917 mrp_wayland_window_update_mask_t mask = u->mask;
2918 int32_t id_surface = win->surfaceid;
2919 bool output_changed = false;
2927 if (!output_changed &&
2928 (!(mask & MRP_WAYLAND_WINDOW_POSITION_MASK) ||
2929 (u->x == win->x && u->y == win->y) ) &&
2930 (!(mask & MRP_WAYLAND_WINDOW_SIZE_MASK) ||
2931 (u->width == win->width && u->height == win->height)) )
2933 mrp_debug("nothing to do");
2937 if (!(sf = surface_find(wm, id_surface))) {
2938 mrp_debug("can't find surface %s",
2939 surface_id_print(id_surface, buf, sizeof(buf)));
2943 x = (mask & MRP_WAYLAND_WINDOW_X_MASK ) ? u->x : win->x;
2944 y = (mask & MRP_WAYLAND_WINDOW_Y_MASK ) ? u->y : win->y;
2945 w = (mask & MRP_WAYLAND_WINDOW_WIDTH_MASK ) ? u->width : win->width;
2946 h = (mask & MRP_WAYLAND_WINDOW_HEIGHT_MASK) ? u->height : win->height;
2948 if (x != win->x || y != win->y)
2949 set_window_animation(win, MRP_WAYLAND_ANIMATION_MOVE, anims);
2950 if (w != win->width || h != win->height)
2951 set_window_animation(win, MRP_WAYLAND_ANIMATION_RESIZE, anims);
2954 mrp_debug("calling ivi_controller_surface_set_source_rectangle"
2955 "(ivi_controller_surface=%p, x=0, y=0, width=%d height=%d)",
2956 sf->ctrl_surface, w,h);
2958 ivi_controller_surface_set_source_rectangle(sf->ctrl_surface, 0,0, w,h);
2962 sf->requested_x = x;
2963 sf->requested_y = y;
2964 sf->requested_width = w;
2965 sf->requested_height = h;
2967 mrp_debug("calling ivi_controller_surface_set_destination_rectangle"
2968 "(ivi_controller_surface=%p, x=%d, y=%d, width=%d height=%d)",
2969 sf->ctrl_surface, x,y, w,h);
2971 ivi_controller_surface_set_destination_rectangle(sf->ctrl_surface,
2978 static bool set_window_opacity(mrp_wayland_window_t *win,
2979 mrp_wayland_window_update_mask_t passthrough,
2980 mrp_wayland_window_update_t *u)
2982 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
2983 int32_t id_surface = win->surfaceid;
2988 if (u->opacity == win->opacity &&
2989 !(passthrough & MRP_WAYLAND_WINDOW_OPACITY_MASK))
2991 mrp_debug("nothing to do");
2995 if (!(sf = surface_find(wm, id_surface))) {
2996 mrp_debug("can't find surface %s",
2997 surface_id_print(id_surface, buf, sizeof(buf)));
3001 opacity = wl_fixed_from_double(u->opacity);
3003 mrp_debug("calling ivi_controller_surface_set_opacity"
3004 "(ivi_controller_surface=%p, opacity=%d)",
3005 sf->ctrl_surface, opacity);
3007 ivi_controller_surface_set_opacity(sf->ctrl_surface, opacity);
3013 static bool raise_window(mrp_wayland_window_t *win,
3014 mrp_wayland_window_update_mask_t passthrough,
3015 mrp_wayland_window_update_t *u)
3017 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
3018 mrp_wayland_window_update_t u2;
3019 int32_t id_surface = win->surfaceid;
3027 do { /* not a loop */
3030 if (((u->raise && win->raise) || (!u->raise && !win->raise))) {
3031 mrp_debug("no actual change is needed");
3035 if (!(sf = surface_find(wm, win->surfaceid))) {
3036 mrp_debug("can't find surface %s",
3037 surface_id_print(id_surface, buf, sizeof(buf)));
3042 mrp_debug("layer is not set");
3046 if (!(ly = layer_find(wm, win->layer->layerid))) {
3047 mrp_debug("can't find layer %d", win->layer->layerid);
3052 changed = layer_move_surface_to_top(ly, sf);
3054 changed = layer_move_surface_to_bottom(ly, sf);
3059 memset(&u2, 0, sizeof(u2));
3060 u2.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
3061 MRP_WAYLAND_WINDOW_RAISE_MASK;
3062 u2.surfaceid = win->surfaceid;
3063 u2.raise = u->raise;
3065 mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_VISIBLE, &u2);
3071 static bool set_window_visibility(mrp_wayland_window_t *win,
3072 mrp_wayland_window_update_mask_t passthrough,
3073 mrp_wayland_window_update_t *u,
3074 mrp_wayland_animation_t *anims)
3076 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
3078 uint32_t visibility;
3080 mrp_wayland_animation_type_t anim_type;
3083 if ((((u->visible && win->visible) || (!u->visible && !win->visible)) &&
3084 !(passthrough & MRP_WAYLAND_WINDOW_VISIBLE_MASK)))
3086 mrp_debug("nothing to do");
3090 id_surface = win->surfaceid;
3091 visibility = u->visible ? 1 : 0;
3092 anim_type = visibility ? MRP_WAYLAND_ANIMATION_SHOW :
3093 MRP_WAYLAND_ANIMATION_HIDE;
3095 if (!(sf = surface_find(wm, id_surface))) {
3096 mrp_debug("can't find surface %s",
3097 surface_id_print(id_surface, buf, sizeof(buf)));
3101 set_window_animation(win, anim_type, anims);
3103 mrp_debug("calling ivi_controller_surface_set_visibility"
3104 "(ivi_controller_surface=%p, visibility=%u)",
3105 sf->ctrl_surface, visibility);
3107 ivi_controller_surface_set_visibility(sf->ctrl_surface, visibility);
3112 static bool set_window_active(mrp_wayland_window_t *win,
3113 mrp_wayland_window_update_mask_t passthrough,
3114 mrp_wayland_window_update_t *u)
3116 static mrp_wayland_active_t focus_mask = MRP_WAYLAND_WINDOW_ACTIVE_POINTER|
3117 MRP_WAYLAND_WINDOW_ACTIVE_TOUCH ;
3119 mrp_glm_window_manager_t *wm = (mrp_glm_window_manager_t *)win->wm;
3120 int32_t id_surface = win->surfaceid;
3122 int32_t focus_enabled;
3125 surface_id_print(id_surface, id_str, sizeof(id_str));
3127 if (u->active == win->active &&
3128 !(passthrough & MRP_WAYLAND_WINDOW_ACTIVE_MASK))
3130 mrp_debug("nothing to do");
3134 if (!(sf = surface_find(wm, id_surface))) {
3135 mrp_debug("can't find surface %s", id_str);
3139 focus_enabled = (u->active & focus_mask) ? 1 : 0;
3141 mrp_debug("calling ivi_controller_surface_set_input_focus"
3142 "(struct ivi_controller_surface=%p, enabled=%d)",
3143 sf->ctrl_surface, focus_enabled);
3146 ivi_controller_surface_set_input_focus(sf->ctrl_surface,
3147 IVI_CONTROLLER_SURFACE_INPUT_DEVICE_ALL,
3153 static void window_request(mrp_wayland_window_t *win,
3154 mrp_wayland_window_update_t *u,
3155 mrp_wayland_animation_t *anims,
3159 static mrp_wayland_window_update_mask_t area_mask =
3160 MRP_WAYLAND_WINDOW_AREA_MASK;
3162 static mrp_wayland_window_update_mask_t mapped_mask =
3163 MRP_WAYLAND_WINDOW_MAPPED_MASK;
3164 static mrp_wayland_window_update_mask_t geometry_mask =
3165 /* MRP_WAYLAND_WINDOW_NODEID_MASK | */
3166 MRP_WAYLAND_WINDOW_POSITION_MASK |
3167 MRP_WAYLAND_WINDOW_SIZE_MASK ;
3168 static mrp_wayland_window_update_mask_t opacity_mask =
3169 MRP_WAYLAND_WINDOW_OPACITY_MASK;
3170 static mrp_wayland_window_update_mask_t raise_mask =
3171 MRP_WAYLAND_WINDOW_RAISE_MASK;
3172 static mrp_wayland_window_update_mask_t layer_mask =
3173 MRP_WAYLAND_WINDOW_LAYER_MASK;
3174 static mrp_wayland_window_update_mask_t visible_mask =
3175 MRP_WAYLAND_WINDOW_VISIBLE_MASK;
3176 static mrp_wayland_window_update_mask_t active_mask =
3177 MRP_WAYLAND_WINDOW_ACTIVE_MASK;
3181 mrp_glm_window_manager_t *wm;
3182 mrp_wayland_window_update_mask_t passthrough;
3183 mrp_wayland_window_update_mask_t mask;
3188 MRP_ASSERT(win && win->wm && win->wm->proxy && win->wm->interface &&
3189 win->wm->interface->wl && u, "invalid argument");
3191 wm = (mrp_glm_window_manager_t *)win->wm;
3192 wl = wm->interface->wl;
3193 passthrough = wm->passthrough.window_request;
3197 mrp_wayland_window_request_print(u, wbuf, sizeof(wbuf));
3198 mrp_wayland_animation_print(anims, abuf, sizeof(abuf));
3199 mrp_debug("request for window %d update:%s\n animations:%s",
3200 win->surfaceid, wbuf, abuf);
3203 if ((mask & layer_mask)) {
3204 changed |= set_window_layer(win, passthrough, u);
3205 mask &= ~layer_mask;
3207 else if ((mask & mapped_mask)) {
3208 changed |= set_window_mapped(win, passthrough, u,
3210 mask &= ~(mapped_mask);
3213 else if ((mask & area_mask)) {
3214 changed |= set_window_area(win, passthrough, u, anims);
3215 mask &= ~(area_mask | geometry_mask);
3218 else if ((mask & geometry_mask)) {
3219 changed |= set_window_geometry(win, passthrough, u, anims);
3220 mask &= ~geometry_mask;
3222 else if ((mask & opacity_mask)) {
3223 changed |= set_window_opacity(win, passthrough, u);
3224 mask &= ~opacity_mask;
3226 else if ((mask & raise_mask)) {
3227 changed |= raise_window(win, passthrough, u);
3228 mask &= ~raise_mask;
3230 else if ((mask & visible_mask)) {
3231 changed |= set_window_visibility(win, passthrough, u, anims);
3232 mask &= ~visible_mask;
3234 else if ((mask & active_mask)) {
3235 changed |= set_window_active(win, passthrough, u);
3236 mask &= ~active_mask;
3244 mrp_debug("calling ivi_controller_commit_changes()");
3245 ivi_controller_commit_changes((struct ivi_controller *)wm->proxy);
3248 mrp_wayland_flush(wl);
3252 static void buffer_request(mrp_wayland_window_manager_t *wm,
3253 const char *shmname,
3260 MRP_ASSERT(wm && wm->proxy && shmname, "invalid argument");
3262 mrp_log_warning("system-controller: buffer_request is not supported in "
3263 "Genivi Layer Management");
3266 static uint32_t wid_hash(const void *pkey)
3268 uint32_t key = (uint32_t)(pkey - NULL);
3270 return key % MRP_WAYLAND_WINDOW_BUCKETS;
3273 static uint32_t sid_hash(const void *pkey)
3275 uint32_t key = *(uint32_t *)pkey;
3277 return key % MRP_WAYLAND_WINDOW_BUCKETS;
3280 static uint32_t lid_hash(const void *pkey)
3282 uint32_t key = *(uint32_t *)pkey;
3284 return key % MRP_WAYLAND_LAYER_BUCKETS;
3288 static uint32_t oid_hash(const void *pkey)
3290 uint32_t key = *(uint32_t *)pkey;
3292 return key % MRP_WAYLAND_OUTPUT_BUCKETS;
3296 static int wid_compare(const void *pkey1, const void *pkey2)
3298 return (pkey1 == pkey2) ? 0 : (pkey1 < pkey2 ? -1 : +1);
3302 static int id_compare(const void *pkey1, const void *pkey2)
3304 int32_t key1 = *(int32_t *)pkey1;
3305 int32_t key2 = *(int32_t *)pkey2;
3307 return (key1 == key2) ? 0 : ((key1 < key2) ? -1 : 1);
3310 static int32_t get_parent_pid(int32_t pid)
3316 char *ppid_line, *c, *e;
3319 snprintf(path, sizeof(path), "/proc/%d/status", pid);
3321 if ((fd = open(path, O_RDONLY)) < 0)
3324 while ((size = read(fd, buf, sizeof(buf)-1)) <= 0) {
3325 if (errno != EINTR) {
3335 if ((ppid_line = strstr(buf, "PPid:"))) {
3336 for (c = ppid_line + 5; (*c == ' ' || *c == '\t'); c++)
3339 if ((ppid = strtol(c, &e, 10)) > 0 && e > c && *e == '\n')
3346 static void get_binary_basename(int32_t pid, char *buf, int len)
3354 snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
3358 if ((fd = open(path, O_RDONLY)) < 0)
3361 while ((size = read(fd, cmdline, sizeof(cmdline))) <= 0) {
3362 if (errno != EINTR) {
3371 bnam = basename(cmdline);
3373 strncpy(buf, bnam, len-1);
3377 static void get_appid(int32_t pid, char *buf, int len)
3381 if (!buf || len < 2)
3386 if ((ppid = pid) > 0) {
3387 while (aul_app_get_appid_bypid(ppid, buf, len) != AUL_R_OK) {
3388 if ((ppid = get_parent_pid(ppid)) <= 1) {
3389 get_binary_basename(pid, buf, len);