Port ico-uxf-weston-plugin to use Weston 1.0.6 plugin API.
[profile/ivi/ico-uxf-weston-plugin.git] / src / ico_window_mgr.c
1 /*
2  * Copyright © 2010-2011 Intel Corporation
3  * Copyright © 2008-2011 Kristian Høgsberg
4  * Copyright © 2013 TOYOTA MOTOR CORPORATION.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and
7  * its documentation for any purpose is hereby granted without fee, provided
8  * that the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of the copyright holders not be used in
11  * advertising or publicity pertaining to distribution of the software
12  * without specific, written prior permission.  The copyright holders make
13  * no representations about the suitability of this software for any
14  * purpose.  It is provided "as is" without express or implied warranty.
15  *
16  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
21  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  */
24 /**
25  * @brief   Multi Window Manager (Weston(Wayland) PlugIn)
26  *
27  * @date    Feb-08-2013
28  */
29
30 #define _GNU_SOURCE
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <stdbool.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <linux/input.h>
38 #include <assert.h>
39 #include <signal.h>
40 #include <math.h>
41 #include <time.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <fcntl.h>
45 #include <wayland-server.h>
46 #include <aul/aul.h>
47 #include <bundle.h>
48
49 #include <weston/compositor.h>
50 #include "ico_ivi_common.h"
51 #include "ico_ivi_shell.h"
52 #include "ico_window_mgr.h"
53 #include "ico_ivi_shell-server-protocol.h"
54 #include "ico_window_mgr-server-protocol.h"
55
56 /* SurfaceID                        */
57 #define INIT_SURFACE_IDS    1024            /* SurfaceId table initiale size        */
58 #define ADD_SURFACE_IDS     512             /* SurfaceId table additional size      */
59 #define SURCAFE_ID_MASK     0x0ffff         /* SurfaceId bit mask pattern           */
60 #define UIFW_HASH    64                     /* Hash value (2's compliment)          */
61
62 /* Cleint management table          */
63 struct uifw_client  {
64     struct wl_client *client;               /* Wayland client                       */
65     int     pid;                            /* ProcessId (pid)                      */
66     char    appid[ICO_IVI_APPID_LENGTH];    /* ApplicationId(from AppCore AUL)      */
67     int     manager;                        /* Manager flag (Need send event)       */
68     struct wl_resource *resource;
69     struct wl_list  link;
70 };
71
72 /* UIFW Surface                     */
73 struct shell_surface;
74 struct uifw_win_surface {
75     uint32_t id;                            /* UIFW SurfaceId                       */
76     int     layer;                          /* LayerId                              */
77     struct weston_surface *surface;         /* Weston surface                       */
78     struct shell_surface  *shsurf;          /* Shell(IVI-Shell) surface             */
79     struct uifw_client    *uclient;         /* Client                               */
80     int     x;                              /* X-axis                               */
81     int     y;                              /* Y-axis                               */
82     int     width;                          /* Width                                */
83     int     height;                         /* Height                               */
84     int     transition;                     /* Transition                           */
85     struct wl_list link;                    /*                                      */
86     struct uifw_win_surface *next_idhash;   /* UIFW SurfaceId hash list             */
87     struct uifw_win_surface *next_wshash;   /* Weston SurfaceId hash list           */
88 };
89
90 /* Manager table                    */
91 struct uifw_manager {
92     struct wl_resource *resource;           /* Manager resource                     */
93     int     eventcb;                        /* Event send flag                      */
94     struct wl_list link;                    /* link to next manager                 */
95 };
96
97 /* Multi Windiw Manager                           */
98 struct ico_win_mgr {
99     struct weston_compositor *compositor;   /* Weston compositor                    */
100     int32_t surface_head;                   /* (HostID << 24) | (DisplayNo << 16)   */
101
102     struct wl_list  client_list;            /* Clients                              */
103     struct wl_list  manager_list;           /* Manager(ex.HomeScreen) list          */
104     int             num_manager;            /* Number of managers                   */
105     struct wl_list  surface_list;           /* Surface list                         */
106     struct uifw_win_surface *active_surface;/* Active Surface                       */
107
108     struct uifw_win_surface *idhash[UIFW_HASH];  /* UIFW SerfaceID                  */
109     struct uifw_win_surface *wshash[UIFW_HASH];  /* Weston Surface                  */
110
111     uint32_t surfaceid_count;               /* Number of surface id                 */
112     uint32_t surfaceid_max;                 /* Maximum number of surface id         */
113     uint16_t *surfaceid_map;                /* SurfaceId assign bit map             */
114 };
115
116 /* Internal macros                      */
117 /* UIFW SurfaceID                       */
118 #define MAKE_IDHASH(v)  (((uint32_t)v) & (UIFW_HASH-1))
119 /* Weston Surface                       */
120 #define MAKE_WSHASH(v)  ((((uint32_t)v) >> 5) & (UIFW_HASH-1))
121
122 /* function prototype                   */
123                                             /* weston compositor interface          */
124 int module_init(struct weston_compositor *ec);
125                                             /* get surface table from surfece id    */
126 static struct uifw_win_surface* find_uifw_win_surface_by_id(uint32_t surfaceid);
127                                             /* get surface table from weston surface*/
128 static struct uifw_win_surface* find_uifw_win_surface_by_ws(
129                     struct weston_surface *wsurf);
130                                             /* get client table from weston client  */
131 static struct uifw_client* find_client_from_client(struct wl_client* client);
132                                             /* assign new surface id                */
133 static uint32_t generate_id(void);
134                                             /* bind shell client                    */
135 static void bind_shell_client(struct wl_client *client);
136                                             /* unind shell client                   */
137 static void unbind_shell_client(struct wl_client *client);
138                                             /* create new surface                   */
139 static void client_register_surface(
140                     struct wl_client *client, struct wl_resource *resource,
141                     struct weston_surface *surface, struct shell_surface *shsurf);
142                                             /* map new surface                      */
143 static void win_mgr_map_surface(struct weston_surface *surface, int32_t *width,
144                                 int32_t *height, int32_t *sx, int32_t *sy);
145                                             /* set applicationId for RemoteUI       */
146 static void uifw_set_user(struct wl_client *client, struct wl_resource *resource,
147                           int pid, const char *appid);
148                                             /* set/reset event flag                 */
149 static void uifw_set_eventcb(struct wl_client *client, struct wl_resource *resource,
150                              int eventcb);
151                                             /* set window layer                     */
152 static void uifw_set_window_layer(struct wl_client *client,
153                                   struct wl_resource *resource,
154                                   uint32_t surfaceid, int layer);
155                                             /* set surface size and position        */
156 static void uifw_set_positionsize(struct wl_client *client,
157                                   struct wl_resource *resource, uint32_t surfaceid,
158                                   int32_t x, int32_t y, int32_t width, int32_t height);
159                                             /* show/hide and raise/lower surface    */
160 static void uifw_set_visible(struct wl_client *client, struct wl_resource *resource,
161                              uint32_t surfaceid, int32_t visible, int32_t raise);
162                                             /* set surface transition               */
163 static void uifw_set_transition(struct wl_client *client, struct wl_resource *resource,
164                                 uint32_t surfaceid, int32_t transition);
165                                             /* set active surface (form HomeScreen) */
166 static void uifw_set_active(struct wl_client *client, struct wl_resource *resource,
167                             uint32_t surfaceid);
168                                             /* layer visibility control             */
169 static void uifw_set_layer_visible(struct wl_client *client, struct wl_resource *resource,
170                                    int32_t layer, int32_t visible);
171                                             /* send surface change event to manager */
172 static void win_mgr_surface_change(struct weston_surface *surface,
173                                    const int to, const int manager);
174                                             /* surface change from manager          */
175 static int win_mgr_surface_change_mgr(struct weston_surface *surface, const int x,
176                                       const int y, const int width, const int height);
177                                             /* surface destory                      */
178 static void win_mgr_surface_destroy(struct weston_surface *surface);
179                                             /* bind manager                         */
180 static void bind_ico_win_mgr(struct wl_client *client,
181                              void *data, uint32_t version, uint32_t id);
182                                             /* unbind manager                       */
183 static void unbind_ico_win_mgr(struct wl_resource *resource);
184                                             /* convert surfaceId to nodeId          */
185 static int ico_winmgr_usurf_2_node(const int surfaceid);
186                                             /* send event to manager                */
187 static int ico_win_mgr_send_to_mgr(const int event, const int surfaceid,
188                                    const char *appid, const int param1,
189                                    const int param2, const int param3, const int param4,
190                                    const int param5, const int param6);
191                                             /* hook for set user                    */
192 static void (*win_mgr_hook_set_user)
193                 (struct wl_client *client, const char *appid) = NULL;
194                                             /* hook for surface create              */
195 static void (*win_mgr_hook_create)
196                 (struct wl_client *client, struct weston_surface *surface,
197                  int surfaceId, const char *appid) = NULL;
198                                             /* hook for surface destory             */
199 static void (*win_mgr_hook_destroy)(struct weston_surface *surface) = NULL;
200
201 /* static tables                        */
202 /* Multi Window Manager interface       */
203 static const struct ico_window_mgr_interface ico_window_mgr_implementation = {
204     uifw_set_user,
205     uifw_set_eventcb,
206     uifw_set_window_layer,
207     uifw_set_positionsize,
208     uifw_set_visible,
209     uifw_set_transition,
210     uifw_set_active,
211     uifw_set_layer_visible
212 };
213
214 /* static management table              */
215 static struct ico_win_mgr *_ico_win_mgr = NULL;
216
217
218 /*--------------------------------------------------------------------------*/
219 /**
220  * @brief   find_uifw_win_surface_by_id: find UIFW surface by surface id
221  *
222  * @param[in]   surfaceid   UIFW surface id
223  * @return      UIFW surface table address
224  * @retval      !=NULL      success(surface table address)
225  * @retval      NULL        error(surface id dose not exist)
226  */
227 /*--------------------------------------------------------------------------*/
228 static struct uifw_win_surface*
229 find_uifw_win_surface_by_id(uint32_t surfaceid)
230 {
231     struct uifw_win_surface* usurf;
232
233     usurf = _ico_win_mgr->idhash[MAKE_IDHASH(surfaceid)];
234
235     while (usurf)   {
236         if (usurf->id == surfaceid) {
237             return usurf;
238         }
239         usurf = usurf->next_idhash;
240     }
241     uifw_trace("find_uifw_win_surface_by_id: NULL");
242     return NULL;
243 }
244
245
246 /*--------------------------------------------------------------------------*/
247 /**
248  * @brief   find_uifw_win_surface_by_ws: find UIFW srurace by weston surface
249  *
250  * @param[in]   wsurf       Weston surface
251  * @return      UIFW surface table address
252  * @retval      !=NULL      success(surface table address)
253  * @retval      NULL        error(surface dose not exist)
254  */
255 /*--------------------------------------------------------------------------*/
256 static struct uifw_win_surface*
257 find_uifw_win_surface_by_ws(struct weston_surface *wsurf)
258 {
259     struct uifw_win_surface* usurf;
260
261     usurf = _ico_win_mgr->wshash[MAKE_WSHASH(wsurf)];
262
263     while (usurf)   {
264         if (usurf->surface == wsurf) {
265             return usurf;
266         }
267         usurf = usurf->next_wshash;
268     }
269     uifw_trace("find_uifw_win_surface_by_ws: NULL");
270     return NULL;
271 }
272
273 /*--------------------------------------------------------------------------*/
274 /**
275  * @brief   find_client_from_client: find UIFW client by wayland client
276  *
277  * @param[in]   client      Wayland client
278  * @return      UIFW client table address
279  * @retval      !=NULL      success(client table address)
280  * @retval      NULL        error(client dose not exist)
281  */
282 /*--------------------------------------------------------------------------*/
283 static struct uifw_client*
284 find_client_from_client(struct wl_client* client)
285 {
286     struct uifw_client  *uclient;
287
288     wl_list_for_each (uclient, &_ico_win_mgr->client_list, link)    {
289         if (uclient->client == client)  {
290             return(uclient);
291         }
292     }
293     uifw_trace("find_client_from_client: NULL");
294     return NULL;
295 }
296
297 /*--------------------------------------------------------------------------*/
298 /**
299  * @brief   ico_window_mgr_appid: find application id by wayland client
300  *
301  * @param[in]   client      Wayland client
302  * @return      application id
303  * @retval      !=NULL      success(application id)
304  * @retval      NULL        error(client dose not exist)
305  */
306 /*--------------------------------------------------------------------------*/
307 WL_EXPORT   char *
308 ico_window_mgr_appid(struct wl_client* client)
309 {
310     struct uifw_client  *uclient;
311
312     uclient = find_client_from_client(client);
313
314     if (! uclient)  {
315         return NULL;
316     }
317     return uclient->appid;
318 }
319
320 /*--------------------------------------------------------------------------*/
321 /**
322  * @brief   generate_id: generate uniq id for UIFW surface id
323  *
324  * @param       none
325  * @return      uniq id for UIFW surface id
326  */
327 /*--------------------------------------------------------------------------*/
328 static uint32_t
329 generate_id(void)
330 {
331     int     rep;
332     int     i;
333     int     map;
334     uint16_t *new_map;
335     uint32_t surfaceId;
336
337     /* next assign id                           */
338     _ico_win_mgr->surfaceid_count ++;
339
340     /* serach free id from bitmap               */
341     for (rep = 0; rep < (int)(_ico_win_mgr->surfaceid_max/16); rep++)   {
342         if (_ico_win_mgr->surfaceid_count >= _ico_win_mgr->surfaceid_max)   {
343             _ico_win_mgr->surfaceid_count = 0;
344         }
345         if (_ico_win_mgr->surfaceid_map[_ico_win_mgr->surfaceid_count/16] != 0xffff)    {
346             /* find free id from bitmap         */
347             map = 1 << (_ico_win_mgr->surfaceid_count % 16);
348             for (i = (_ico_win_mgr->surfaceid_count % 16); i < 16; i++) {
349                 if ((_ico_win_mgr->surfaceid_map[_ico_win_mgr->surfaceid_count/16] & map)
350                         == 0) {
351                     _ico_win_mgr->surfaceid_map[_ico_win_mgr->surfaceid_count/16] |= map;
352                     _ico_win_mgr->surfaceid_count
353                         = (_ico_win_mgr->surfaceid_count/16)*16 + i;
354
355                     surfaceId = (_ico_win_mgr->surfaceid_count + 1)
356                                 | _ico_win_mgr->surface_head;
357                     uifw_trace("generate_id: SurfaceId=%08x", surfaceId);
358                     return(surfaceId);
359                 }
360                 map = map << 1;
361             }
362         }
363         _ico_win_mgr->surfaceid_count += 16;
364     }
365
366     /* no free id in bitmap, extend bitmap      */
367     if ((_ico_win_mgr->surfaceid_max + ADD_SURFACE_IDS) > SURCAFE_ID_MASK)  {
368         /* too many surfaces, system error      */
369         uifw_trace("generate_id: SurffaceId Overflow(%d, Max=%d), Abort",
370                    _ico_win_mgr->surfaceid_max + ADD_SURFACE_IDS, SURCAFE_ID_MASK);
371         fprintf(stderr, "generate_id: SurffaceId Overflow(%d, Max=%d), Abort\n",
372                 _ico_win_mgr->surfaceid_max + ADD_SURFACE_IDS, SURCAFE_ID_MASK);
373         abort();
374     }
375
376     new_map = (uint16_t *) malloc((_ico_win_mgr->surfaceid_max + ADD_SURFACE_IDS) / 8);
377     memcpy(new_map, _ico_win_mgr->surfaceid_map, _ico_win_mgr->surfaceid_max/8);
378     memset(&new_map[_ico_win_mgr->surfaceid_max/16], 0, ADD_SURFACE_IDS/8);
379     _ico_win_mgr->surfaceid_count = _ico_win_mgr->surfaceid_max;
380     new_map[_ico_win_mgr->surfaceid_count/16] |= 1;
381     _ico_win_mgr->surfaceid_max += ADD_SURFACE_IDS;
382     free(_ico_win_mgr->surfaceid_map);
383     _ico_win_mgr->surfaceid_map = new_map;
384
385     uifw_trace("generate_id: Extent SurfaceId=%d(Max.%d)",
386                _ico_win_mgr->surfaceid_count+1, _ico_win_mgr->surfaceid_max);
387     surfaceId = (_ico_win_mgr->surfaceid_count + 1) | _ico_win_mgr->surface_head;
388
389     uifw_trace("generate_id: SurfaceId=%08x", surfaceId);
390     return(surfaceId);
391 }
392
393 /*--------------------------------------------------------------------------*/
394 /**
395  * @brief   bind_shell_client: ico_ivi_shell from client
396  *
397  * @param[in]   client          Wayland client
398  * @return      none
399  */
400 /*--------------------------------------------------------------------------*/
401 static void
402 bind_shell_client(struct wl_client *client)
403 {
404     struct uifw_client  *uclient;
405     pid_t   pid;
406     uid_t   uid;
407     gid_t   gid;
408     int     fd;
409     int     size;
410     int     i;
411     int     j;
412     char    procpath[128];
413
414     uifw_trace("bind_shell_client: Enter(client=%08x)", (int)client);
415
416     /* set client                           */
417     uclient = find_client_from_client(client);
418     if (! uclient)  {
419         /* client not exist, create client management table             */
420         uifw_trace("bind_shell_client: Create Client");
421         uclient = (struct uifw_client *)malloc(sizeof(struct uifw_client));
422         if (!uclient)   {
423             uifw_error("bind_shell_client: Error, No Memory");
424             return;
425         }
426         memset(uclient, 0, sizeof(struct uifw_client));
427         uclient->client = client;
428         wl_list_insert(&_ico_win_mgr->client_list, &uclient->link);
429     }
430     wl_client_get_credentials(client, &pid, &uid, &gid);
431     uifw_trace("bind_shell_client: client=%08x pid=%d uid=%d gid=%d",
432                (int)client, (int)pid, (int)uid, (int)gid);
433     if (pid > 0)    {
434         uclient->pid = (int)pid;
435         /* get applicationId from AppCore(AUL)  */
436         if (aul_app_get_appid_bypid(uclient->pid, uclient->appid, ICO_IVI_APPID_LENGTH)
437                         == AUL_R_OK)    {
438             uifw_trace("bind_shell_client: client=%08x pid=%d appid=<%s>",
439                        (int)client, uclient->pid, uclient->appid);
440         }
441         else    {
442             /* client dose not exist in AppCore, search Linux process table */
443             uifw_trace("bind_shell_client: pid=%d dose not exist in AppCore(AUL)",
444                        uclient->pid);
445
446             memset(uclient->appid, 0, ICO_IVI_APPID_LENGTH);
447             snprintf(procpath, sizeof(procpath)-1, "/proc/%d/cmdline", uclient->pid);
448             fd = open(procpath, O_RDONLY);
449             if (fd >= 0)    {
450                 size = read(fd, procpath, sizeof(procpath));
451                 for (; size > 0; size--)    {
452                     if (procpath[size-1])   break;
453                 }
454                 if (size > 0)   {
455                     /* get program base name    */
456                     i = 0;
457                     for (j = 0; j < size; j++)  {
458                         if (procpath[j] == 0)   break;
459                         if (procpath[j] == '/') i = j + 1;
460                     }
461                     j = 0;
462                     for (; i < size; i++)   {
463                         uclient->appid[j] = procpath[i];
464                         if ((uclient->appid[j] == 0) ||
465                             (j >= (ICO_IVI_APPID_LENGTH-1)))    break;
466                         j++;
467                     }
468                     /* search application number in apprication start option    */
469                     if ((uclient->appid[j] == 0) && (j < (ICO_IVI_APPID_LENGTH-2))) {
470                         for (; i < size; i++)   {
471                             if ((procpath[i] == 0) &&
472                                 (procpath[i+1] == '@')) {
473                                 strncpy(&uclient->appid[j], &procpath[i+1],
474                                         ICO_IVI_APPID_LENGTH - j - 2);
475                             }
476                         }
477                     }
478                 }
479                 close(fd);
480             }
481             if (uclient->appid[0])  {
482                 uifw_trace("bind_shell_client: client=%08x pid=%d appid=<%s> from "
483                            "Process table", (int)client, uclient->pid, uclient->appid);
484             }
485             else    {
486                 uifw_trace("bind_shell_client: pid=%d dose not exist in Process table",
487                            uclient->pid);
488                 sprintf(uclient->appid, "?%d?", uclient->pid);
489             }
490         }
491     }
492     else    {
493         uifw_trace("bind_shell_client: client=%08x pid dose not exist", (int)client);
494     }
495     uifw_trace("bind_shell_client: Leave");
496 }
497
498 /*--------------------------------------------------------------------------*/
499 /**
500  * @brief   unbind_shell_client: unbind ico_ivi_shell from client
501  *
502  * @param[in]   client          Wayland client
503  * @return      none
504  */
505 /*--------------------------------------------------------------------------*/
506 static void
507 unbind_shell_client(struct wl_client *client)
508 {
509     struct uifw_client  *uclient;
510
511     uifw_trace("unbind_shell_client: Enter(client=%08x)", (int)client);
512
513     uclient = find_client_from_client(client);
514     if (uclient)    {
515         /* Client exist, Destory client management table             */
516         wl_list_remove(&uclient->link);
517         free(uclient);
518     }
519     uifw_trace("unbind_shell_client: Leave");
520 }
521
522 /*--------------------------------------------------------------------------*/
523 /**
524  * @brief   client_register_surface: create UIFW surface
525  *
526  * @param[in]   client          Wayland client
527  * @param[in]   resource        client resource
528  * @param[in]   surface         Weston surface
529  * @param[in]   shsurf          shell surface
530  * @return      none
531  */
532 /*--------------------------------------------------------------------------*/
533 static void
534 client_register_surface(struct wl_client *client, struct wl_resource *resource,
535                         struct weston_surface *surface, struct shell_surface *shsurf)
536 {
537     struct uifw_win_surface *us;
538     struct uifw_win_surface *phash;
539     struct uifw_win_surface *bhash;
540     uint32_t    hash;
541
542     uifw_trace("client_register_surface: Enter(surf=%08x,client=%08x,res=%08x)",
543                (int)surface, (int)client, (int)resource);
544
545     /* check new surface                    */
546     if (find_uifw_win_surface_by_ws(surface))   {
547         /* surface exist, NOP               */
548         uifw_trace("client_register_surface: Leave(Already Exist)");
549         return;
550     }
551
552     /* create UIFW surface management table */
553     us = malloc(sizeof(struct uifw_win_surface));
554     if (!us)    {
555         uifw_error("client_register_surface: No Memory");
556         return;
557     }
558
559     memset(us, 0, sizeof(struct uifw_win_surface));
560
561     us->id = generate_id();
562     us->surface = surface;
563     us->shsurf = shsurf;
564     if (_ico_win_mgr->num_manager <= 0) {
565         uifw_trace("client_register_surface: No Manager, Force visible");
566         ivi_shell_set_visible(shsurf, 1);   /* NOT exist HomeScreen     */
567     }
568     else    {
569         uifw_trace("client_register_surface: Manager exist, Not visible");
570         ivi_shell_set_visible(shsurf, -1);  /* Exist HomeScreen         */
571     }
572
573     /* set client                           */
574     us->uclient = find_client_from_client(client);
575     if (! us->uclient)  {
576         /* client not exist, create client management table */
577         uifw_trace("client_register_surface: Create Client");
578         bind_shell_client(client);
579         us->uclient = find_client_from_client(client);
580         if (! us->uclient)  {
581             uifw_error("client_register_surface: No Memory");
582             return;
583         }
584     }
585     wl_list_insert(&_ico_win_mgr->surface_list, &us->link);
586
587     /* make surface id hash table       */
588     hash = MAKE_IDHASH(us->id);
589     phash = _ico_win_mgr->idhash[hash];
590     bhash = NULL;
591     while (phash)   {
592         bhash = phash;
593         phash = phash->next_idhash;
594     }
595     if (bhash)  {
596         bhash->next_idhash = us;
597     }
598     else    {
599         _ico_win_mgr->idhash[hash] = us;
600     }
601
602     /* make weston surface hash table   */
603     hash = MAKE_WSHASH(us->surface);
604     phash = _ico_win_mgr->wshash[hash];
605     bhash = NULL;
606     while (phash)   {
607         bhash = phash;
608         phash = phash->next_wshash;
609     }
610     if (bhash)  {
611         bhash->next_wshash = us;
612     }
613     else    {
614         _ico_win_mgr->wshash[hash] = us;
615     }
616     /* set default layer id             */
617     ivi_shell_set_layer(shsurf, 0);
618
619     /* send event to manager            */
620     ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_CREATED,
621                             us->id, us->uclient->appid, us->uclient->pid, 0,0,0,0,0);
622
623     if (win_mgr_hook_create) {
624         /* call surface create hook for ico_window_mgr  */
625         (void) (*win_mgr_hook_create)(client, surface, us->id, us->uclient->appid);
626     }
627     uifw_trace("client_register_surface: Leave(surfaceId=%08x)", us->id);
628 }
629
630 /*--------------------------------------------------------------------------*/
631 /**
632  * @brief   win_mgr_map_surface: map surface
633  *
634  * @param[in]   surface         Weston surface
635  * @param[in]   width           surface width
636  * @param[in]   height          surface height
637  * @param[in]   sx              X coordinate on screen
638  * @param[in]   sy              Y coordinate on screen
639  * @return      none
640  */
641 /*--------------------------------------------------------------------------*/
642 static void
643 win_mgr_map_surface(struct weston_surface *surface, int32_t *width, int32_t *height,
644                     int32_t *sx, int32_t *sy)
645 {
646     struct uifw_win_surface *usurf;
647
648     uifw_trace("win_mgr_map_surface: Enter(%08x, x/y=%d/%d w/h=%d/%d)",
649                (int)surface, *sx, *sy, *width, *height);
650
651     usurf = find_uifw_win_surface_by_ws(surface);
652
653     if (usurf) {
654         uifw_trace("win_mgr_map_surface: surf=%08x w/h=%d/%d vis=%d",
655                    usurf->id, usurf->width, usurf->height,
656                    ivi_shell_is_visible(usurf->shsurf));
657
658         if ((usurf->width > 0) && (usurf->height > 0)) {
659             uifw_trace("win_mgr_map_surface: HomeScreen registed, PositionSize"
660                        "(surf=%08x x/y=%d/%d w/h=%d/%d vis=%d",
661                        usurf->id, usurf->x, usurf->y, usurf->width, usurf->height,
662                        ivi_shell_is_visible(usurf->shsurf));
663             *width = usurf->width;
664             *height = usurf->height;
665             surface->geometry.x = usurf->x;
666             surface->geometry.y = usurf->y;
667         }
668         else    {
669             uifw_trace("win_mgr_map_surface: HomeScreen not regist Surface, "
670                        "Change PositionSize(surf=%08x x/y=%d/%d w/h=%d/%d)",
671                        usurf->id, *sx, *sy, *width, *height);
672             usurf->width = *width;
673             usurf->height = *height;
674             usurf->x = *sx;
675             usurf->y = *sy;
676             if (usurf->x < 0)   usurf->x = 0;
677             if (usurf->y < 0)   usurf->y = 0;
678
679             if (_ico_win_mgr->num_manager > 0)  {
680                 /* HomeScreen exist, coodinate set by HomeScreen                */
681                 surface->geometry.x = 0;
682                 surface->geometry.y = 0;
683
684                 /* change surface size, because HomeScreen change surface size  */
685                 *width = 1;
686                 *height = 1;
687                 uifw_trace("win_mgr_map_surface: Change size and position");
688             }
689             else    {
690                 uifw_trace("win_mgr_map_surface: Np HomeScreen, chaneg to Visible");
691                 ivi_shell_set_visible(usurf->shsurf, 1);
692             }
693         }
694         ivi_shell_set_positionsize(usurf->shsurf,
695                                    usurf->x, usurf->y, usurf->width, usurf->height);
696         uifw_trace("win_mgr_map_surface: Leave");
697     }
698     else    {
699         uifw_trace("win_mgr_map_surface: Leave(No Window Manager Surface)");
700     }
701 }
702
703 /*--------------------------------------------------------------------------*/
704 /**
705  * @briefdwi    uifw_set_user: set user id (for RemoteUI)
706  *
707  * @param[in]   client      Weyland client
708  * @param[in]   resource    resource of request
709  * @param[in]   pid         client process id
710  * @param[in]   appid       application id
711  * @return      none
712  */
713 /*--------------------------------------------------------------------------*/
714 static void
715 uifw_set_user(struct wl_client *client, struct wl_resource *resource,
716               int pid, const char *appid)
717 {
718     struct uifw_client  *uclient;
719
720     uifw_trace("uifw_set_user: Enter(client=%08x pid=%d appid=%s)",
721                 (int)client, pid, appid);
722
723     uclient = find_client_from_client(client);
724     if (uclient)    {
725         uclient->pid = pid;
726         memset(uclient->appid, 0, ICO_IVI_APPID_LENGTH);
727         strncpy(uclient->appid, appid, ICO_IVI_APPID_LENGTH-1);
728         uclient->resource = resource;
729         uifw_trace("uifw_set_user: Leave(Client Exist, change PID/AppId)");
730         return;
731     }
732
733     uclient = (struct uifw_client *)malloc(sizeof(struct uifw_client));
734     if (! uclient)  {
735         uifw_trace("uifw_set_user: Leave(Error, No Memory)");
736         return;
737     }
738
739     memset(uclient, 0, sizeof(struct uifw_client));
740     uclient->client = client;
741     uclient->pid = pid;
742     memset(uclient->appid, 0, ICO_IVI_APPID_LENGTH);
743     strncpy(uclient->appid, appid, ICO_IVI_APPID_LENGTH-1);
744     uclient->resource = resource;
745
746     wl_list_insert(&_ico_win_mgr->client_list, &uclient->link);
747
748     if (win_mgr_hook_set_user) {
749         (void) (*win_mgr_hook_set_user) (client, uclient->appid);
750     }
751     uifw_trace("uifw_set_user: Leave");
752 }
753
754 /*--------------------------------------------------------------------------*/
755 /**
756  * @brief   uifw_set_eventcb: set event callback flag for HomeScreen
757  *
758  * @param[in]   client      Weyland client
759  * @param[in]   resource    resource of request
760  * @param[in]   eventcb     event callback flag(1=callback, 0=no callback)
761  * @return      none
762  */
763 /*--------------------------------------------------------------------------*/
764 static void
765 uifw_set_eventcb(struct wl_client *client, struct wl_resource *resource, int eventcb)
766 {
767     struct uifw_manager* mgr;
768     struct uifw_win_surface *usurf;
769     struct uifw_client *uclient;
770
771     uifw_trace("uifw_set_eventcb: Enter client=%08x eventcb=%d",
772                (int)client, eventcb);
773
774     uclient = find_client_from_client(client);
775     if (uclient)    {
776         uclient->manager = eventcb;
777     }
778
779     /* client set to manager            */
780     _ico_win_mgr->num_manager = 0;
781     wl_list_for_each (mgr, &_ico_win_mgr->manager_list, link)   {
782         if (mgr->resource == resource)  {
783             if (mgr->eventcb != eventcb)    {
784                 uifw_trace("uifw_set_eventcb: Event Callback %d=>%d",
785                            mgr->eventcb, eventcb);
786                 mgr->eventcb = eventcb;
787
788                 if (eventcb)    {
789                     wl_list_for_each (usurf, &_ico_win_mgr->surface_list, link) {
790                         /* send window create event to manager  */
791                         uifw_trace("uifw_set_eventcb: Send manager(%08x) WINDOW_CREATED"
792                                    "(surf=%08x,pid=%d,appid=%s)", (int)resource, usurf->id,
793                                    usurf->uclient->pid, usurf->uclient->appid);
794                         ico_window_mgr_send_window_created(resource,
795                             usurf->id, usurf->uclient->pid, usurf->uclient->appid);
796                     }
797                 }
798             }
799         }
800         if (mgr->eventcb)   {
801             _ico_win_mgr->num_manager++;
802         }
803     }
804     uifw_trace("uifw_set_eventcb: Leave(managers=%d)", _ico_win_mgr->num_manager);
805 }
806
807 /*--------------------------------------------------------------------------*/
808 /**
809  * @brief   uifw_set_window_layer: set layer id to surface
810  *
811  * @param[in]   client      Weyland client
812  * @param[in]   resource    resource of request
813  * @param[in]   surfaceid   UIFW surface id
814  * @param[in]   layer       layer id
815  * @return      none
816  */
817 /*--------------------------------------------------------------------------*/
818 static void
819 uifw_set_window_layer(struct wl_client *client, struct wl_resource *resource,
820                       uint32_t surfaceid, int32_t layer)
821 {
822     uifw_trace("uifw_set_window_layer: Enter res=%08x surfaceid=%08x layer=%d",
823                (int)resource, surfaceid, layer);
824
825     struct uifw_win_surface *usurf = find_uifw_win_surface_by_id(surfaceid);
826
827     if (! usurf)    {
828         uifw_trace("uifw_set_window_layer: Leave(No Surface(id=%08x)", surfaceid);
829         return;
830     }
831     else if (usurf->layer != layer) {
832         usurf->layer = layer;
833         uifw_trace("uifw_set_window_layer: Set Layer(%d) to Shell Surface", layer);
834         ivi_shell_set_layer(usurf->shsurf, layer);
835
836         win_mgr_surface_change(usurf->surface, 1, 1);
837     }
838     uifw_trace("uifw_set_window_layer: Leave");
839 }
840
841 /*--------------------------------------------------------------------------*/
842 /**
843  * @brief   uifw_set_weston_surface: set weston surface from UIFW surface
844  *
845  * @param[in]   usurf       UIFW surface
846  * @return      none
847  */
848 /*--------------------------------------------------------------------------*/
849 static void
850 uifw_set_weston_surface(struct uifw_win_surface *usurf)
851 {
852     struct weston_surface *es = usurf->surface;
853     int     width = usurf->width;
854     int     height = usurf->height;
855     int     x = usurf->x;
856     int     y = usurf->y;
857
858     if ((es != NULL) && (es->buffer != NULL))   {
859         if (usurf->width > es->buffer->width)   {
860             width = es->buffer->width;
861             x += (usurf->width - es->buffer->width)/2;
862         }
863         if (usurf->height > es->buffer->height) {
864             height = es->buffer->height;
865             y += (usurf->height - es->buffer->height)/2;
866         }
867     }
868     ivi_shell_set_positionsize(usurf->shsurf,
869                                usurf->x, usurf->y, usurf->width, usurf->height);
870     uifw_trace("uifw_set_weston_surface: w/h=%d/%d->%d/%d x/y=%d/%d->%d/%d",
871                usurf->width, usurf->height, width, height, usurf->x, usurf->y, x, y);
872     ivi_shell_surface_configure(usurf->shsurf, x, y, width, height);
873 }
874
875 /*--------------------------------------------------------------------------*/
876 /**
877  * @brief   uifw_set_positionsize: set surface position and size
878  *
879  * @param[in]   client      Weyland client
880  * @param[in]   resource    resource of request
881  * @param[in]   surfaceid   UIFW surface id
882  * @param[in]   x           X coordinate on screen(if bigger than 16383, no change)
883  * @param[in]   y           Y coordinate on screen(if bigger than 16383, no change)
884  * @param[in]   width       surface width(if bigger than 16383, no change)
885  * @param[in]   height      surface height(if bigger than 16383, no change)
886  * @return      none
887  */
888 /*--------------------------------------------------------------------------*/
889 static void
890 uifw_set_positionsize(struct wl_client *client, struct wl_resource *resource,
891                       uint32_t surfaceid,
892                       int32_t x, int32_t y, int32_t width, int32_t height)
893 {
894     struct uifw_client *uclient;
895
896     uifw_trace("uifw_set_positionsize: Enter res=%08x surf=%08x x/y/w/h=%d/%d/%d/%d",
897                (int)resource, surfaceid, x, y, width, height);
898
899     struct uifw_win_surface* usurf = find_uifw_win_surface_by_id(surfaceid);
900
901     if (usurf && (usurf->surface))  {
902         /* weston surface exist             */
903         struct weston_surface *es = usurf->surface;
904
905         /* if x,y,width,height bigger then ICO_IVI_MAX_COORDINATE, no change    */
906         if (x > ICO_IVI_MAX_COORDINATE)         x = usurf->x;
907         if (y > ICO_IVI_MAX_COORDINATE)         y = usurf->y;
908         if (width > ICO_IVI_MAX_COORDINATE)     width = usurf->width;
909         if (height > ICO_IVI_MAX_COORDINATE)    height = usurf->height;
910
911         uclient = find_client_from_client(client);
912         if (uclient)    {
913             if (! uclient->manager) uclient = NULL;
914         }
915         if (! uclient)  {
916             if ((usurf->width > 0) && (usurf->height > 0))  {
917                 win_mgr_surface_change_mgr(es, x, y, width, height);
918                 uifw_trace("uifw_set_positionsize: Leave(Request from App)");
919                 return;
920             }
921
922             uifw_trace("uifw_set_positionsize: Initial Position/Size visible=%d",
923                        ivi_shell_is_visible(usurf->shsurf));
924             /* Initiale position is (0,0)   */
925             es->geometry.x = 0;
926             es->geometry.y = 0;
927         }
928
929         uifw_trace("uifw_set_positionsize: Old geometry x/y=%d/%d,w/h=%d/%d",
930                    (int)es->geometry.x, (int)es->geometry.y,
931                    (int)es->geometry.width, (int)es->geometry.height);
932
933         usurf->x = x;
934         usurf->y = y;
935         usurf->width = width;
936         usurf->height = height;
937         ivi_shell_set_positionsize(usurf->shsurf, x, y, width, height);
938         if (_ico_win_mgr->num_manager <= 0) {
939             /* no manager(HomeScreen), set geometory    */
940             es->geometry.x = x;
941             es->geometry.y = y;
942         }
943         if ((es->output) && (es->buffer) &&
944             (es->geometry.width > 0) && (es->geometry.height > 0)) {
945             uifw_trace("uifw_set_positionsize: Fixed Geometry, Change(Vis=%d)",
946                        ivi_shell_is_visible(usurf->shsurf));
947             uifw_set_weston_surface(usurf);
948             weston_surface_damage_below(es);
949             weston_surface_damage(es);
950             weston_compositor_schedule_repaint(_ico_win_mgr->compositor);
951         }
952         win_mgr_surface_change(es, 0, 1);
953
954         uifw_trace("uifw_set_positionsize: Leave(OK,output=%x)", (int)es->output);
955     }
956     else    {
957         uifw_trace("uifw_set_positionsize: Leave(surf=%08x NOT Found)", surfaceid);
958     }
959 }
960
961 /*--------------------------------------------------------------------------*/
962 /**
963  * @brief   uifw_set_visible: surface visible/raise control
964  *
965  * @param[in]   client      Weyland client
966  * @param[in]   resource    resource of request
967  * @param[in]   surfaceid   UIFW surface id
968  * @param[in]   visible     visible(1=show/0=hide/other=no change)
969  * @param[in]   raise       raise(1=raise/0=lower/other=no change)
970  * @return      none
971  */
972 /*--------------------------------------------------------------------------*/
973 static void
974 uifw_set_visible(struct wl_client *client, struct wl_resource *resource,
975                  uint32_t surfaceid, int32_t visible, int32_t raise)
976 {
977     struct uifw_win_surface* usurf;
978     struct uifw_client *uclient;
979
980     uifw_trace("uifw_set_visible: Enter(surf=%08x,%d,%d)", surfaceid, visible, raise);
981
982     uclient = find_client_from_client(client);
983     if (uclient)    {
984         if (! uclient->manager) {
985             uifw_trace("uifw_set_visible: Request from App(%s), not Manager",
986                        uclient->appid);
987             uclient = NULL;
988         }
989         else    {
990             uifw_trace("uifw_set_visible: Request from Manager(%s)", uclient->appid);
991         }
992     }
993     else    {
994         uifw_trace("uifw_set_visible: Request from Unknown App, not Manager");
995     }
996
997     usurf = find_uifw_win_surface_by_id(surfaceid);
998
999     if ((! usurf) || (! usurf->surface))    {
1000         uifw_trace("uifw_set_visible: Leave(Surface Not Exist)");
1001         return;
1002     }
1003
1004     if (visible == 1) {
1005         if ((usurf->width <= 0) || (usurf->height <= 0))    {
1006             /* not declare surface geometry, initialize     */
1007             usurf->width = usurf->surface->geometry.width;
1008             usurf->height = usurf->surface->geometry.height;
1009             uifw_trace("uifw_set_visible: Set w/h=%d/%d", usurf->width, usurf->height);
1010         }
1011         if (! ivi_shell_is_visible(usurf->shsurf))  {
1012             if (uclient)    {
1013                 /* manager exist, change to visible         */
1014                 ivi_shell_set_visible(usurf->shsurf, 1);
1015             }
1016             uifw_trace("uifw_set_visible: Change to Visible");
1017
1018             ivi_shell_set_toplevel(usurf->shsurf);
1019
1020             /* Weston surface configure                     */
1021             uifw_trace("uifw_set_visible: Visible to Weston WSurf=%08x,%d/%d/%d/%d",
1022                        (int)usurf->surface, usurf->x, usurf->y,
1023                        usurf->width, usurf->height);
1024             uifw_set_weston_surface(usurf);
1025             ivi_shell_set_surface_type(usurf->shsurf);
1026         }
1027         else if ((raise != 0) && (raise != 1))  {
1028             uifw_trace("uifw_set_visible: Leave(No Change)");
1029             return;
1030         }
1031     }
1032     else if (visible == 0)  {
1033
1034         if (ivi_shell_is_visible(usurf->shsurf))    {
1035             ivi_shell_set_visible(usurf->shsurf, 0);
1036             uifw_trace("uifw_set_visible: Change to UnVisible");
1037
1038             /* Weston surface configure                     */
1039             uifw_set_weston_surface(usurf);
1040         }
1041         else if ((raise != 0) && (raise != 1))  {
1042             uifw_trace("uifw_set_visible: Leave(No Change)");
1043             return;
1044         }
1045     }
1046     else if ((raise != 0) && (raise != 1))  {
1047         uifw_trace("uifw_set_visible: Leave(No Change)");
1048         return;
1049     }
1050
1051     /* raise/lower                              */
1052     if ((raise == 1) || (raise == 0))   {
1053         ivi_shell_set_raise(usurf->shsurf, raise);
1054     }
1055
1056     if ((usurf->surface) && (usurf->surface->buffer) && (usurf->surface->output))   {
1057         weston_surface_damage_below(usurf->surface);
1058         weston_surface_damage(usurf->surface);
1059         weston_compositor_schedule_repaint(_ico_win_mgr->compositor);
1060     }
1061     /* send event(VISIBLE) to manager           */
1062     ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_VISIBLE,
1063                             surfaceid, NULL, visible, raise, uclient ? 0 : 1, 0,0,0);
1064
1065     uifw_trace("uifw_set_visible: Leave(OK)");
1066 }
1067
1068 /*--------------------------------------------------------------------------*/
1069 /**
1070  * @brief   uifw_set_transition: set transition of surface visible/unvisible
1071  *
1072  * @param[in]   client      Weyland client
1073  * @param[in]   resource    resource of request
1074  * @param[in]   surfaceid   UIFW surface id
1075  * @param[in]   transition  transiton id
1076  * @return      none
1077  */
1078 /*--------------------------------------------------------------------------*/
1079 static void
1080 uifw_set_transition(struct wl_client *client, struct wl_resource *resource,
1081                     uint32_t surfaceid, int32_t transition)
1082 {
1083     struct uifw_win_surface* usurf = find_uifw_win_surface_by_id(surfaceid);
1084
1085     uifw_trace("uifw_set_transition: Enter(surf=%08x, transition=%d)",
1086                 surfaceid, transition);
1087
1088     if (usurf) {
1089         usurf->transition = transition;
1090         uifw_trace("uifw_set_transition: Leave(OK)");
1091     }
1092     else    {
1093         uifw_trace("uifw_set_transition: Leave(Surface(%08x) Not exist)", surfaceid);
1094     }
1095 }
1096
1097 /*--------------------------------------------------------------------------*/
1098 /**
1099  * @brief   uifw_set_active: set active surface
1100  *
1101  * @param[in]   client      Weyland client
1102  * @param[in]   resource    resource of request
1103  * @param[in]   surfaceid   UIFW surface id
1104  * @return      none
1105  */
1106 /*--------------------------------------------------------------------------*/
1107 static void
1108 uifw_set_active(struct wl_client *client, struct wl_resource *resource, uint32_t surfaceid)
1109 {
1110     struct uifw_win_surface* usurf = find_uifw_win_surface_by_id(surfaceid);
1111
1112     uifw_trace("uifw_set_active: Enter(surf=%08x)", surfaceid);
1113
1114     if (usurf) {
1115         if (usurf != _ico_win_mgr->active_surface)  {
1116             if (_ico_win_mgr->active_surface)   {
1117                 ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_ACTIVE,
1118                                         surfaceid, NULL, ICO_WINDOW_MGR_ACTIVE_INACTIVE,
1119                                         0,0,0,0,0);
1120             }
1121             _ico_win_mgr->active_surface = usurf;
1122             ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_ACTIVE,
1123                                     surfaceid, NULL, ICO_WINDOW_MGR_ACTIVE_ACTIVE,
1124                                     0,0,0,0,0);
1125         }
1126         uifw_trace("uifw_set_active: Leave(Change Active)");
1127     }
1128     else    {
1129         uifw_trace("uifw_set_active: Leave(Surface(%08x) Not exist)", surfaceid);
1130     }
1131 }
1132
1133 /*--------------------------------------------------------------------------*/
1134 /**
1135  * @brief   uifw_set_layer_visible: layer visible control
1136  *
1137  * @param[in]   client      Weyland client
1138  * @param[in]   resource    resource of request
1139  * @param[in]   layer       layer id
1140  * @param[in]   visible     visible(1=show/0=hide)
1141  * @return      none
1142  */
1143 /*--------------------------------------------------------------------------*/
1144 static void
1145 uifw_set_layer_visible(struct wl_client *client, struct wl_resource *resource,
1146                        int32_t layer, int32_t visible)
1147 {
1148     uifw_trace("uifw_set_layer_visible: Enter(layer=%d, visilbe=%d)", layer, visible);
1149
1150     ivi_shell_set_layer_visible(layer, visible);
1151
1152     uifw_trace("uifw_set_layer_visible: Leave");
1153 }
1154
1155 /*--------------------------------------------------------------------------*/
1156 /**
1157  * @brief   win_mgr_surface_change_mgr: surface chagen from manager(HomeScreen)
1158  *
1159  * @param[in]   surface     Weston surface
1160  * @param[in]   x           X coordinate on screen
1161  * @param[in]   y           Y coordinate on screen
1162  * @param[in]   width       surface width
1163  * @param[in]   height      surface height
1164  * @return      number of managers
1165  * @retval      > 0         number of managers
1166  * @retval      0           manager not exist
1167  */
1168 /*--------------------------------------------------------------------------*/
1169 static int
1170 win_mgr_surface_change_mgr(struct weston_surface *surface,
1171                            const int x, const int y, const int width, const int height)
1172 {
1173     int     num_mgr;
1174     struct uifw_win_surface *usurf;
1175
1176     uifw_trace("win_mgr_surface_change_mgr: Enter(%08x,x/y=%d/%d,w/h=%d/%d)",
1177                (int)surface, x, y, width, height);
1178
1179     usurf = find_uifw_win_surface_by_ws(surface);
1180     if (! usurf) {
1181         uifw_trace("win_mgr_surface_change_mgr: Leave(Not Exist)");
1182         return 0;
1183     }
1184
1185     num_mgr = ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_CONFIGURE,
1186                                       usurf->id, usurf->uclient->appid, usurf->layer,
1187                                       x, y, width, height, 1);
1188
1189     uifw_trace("win_mgr_surface_change_mgr: Leave(%d)", num_mgr);
1190     return num_mgr;
1191 }
1192
1193 /*--------------------------------------------------------------------------*/
1194 /**
1195  * @brief   win_mgr_surface_change: surface change
1196  *
1197  * @param[in]   surface     Weston surface
1198  * @param[in]   to          destination(0=Client&Manager,1=Client,-1=Manager)
1199  * @param[in]   manager     request from manager(0=Client,1=Manager)
1200  * @return      none
1201  */
1202 /*--------------------------------------------------------------------------*/
1203 static void
1204 win_mgr_surface_change(struct weston_surface *surface, const int to, const int manager)
1205 {
1206     struct uifw_win_surface *usurf;
1207
1208     uifw_trace("win_mgr_surface_change: Enter(%08x,%d,%d)", (int)surface, to, manager);
1209
1210     /* Find surface         */
1211     usurf = find_uifw_win_surface_by_ws(surface);
1212     if (! usurf) {
1213         uifw_trace("win_mgr_surface_change: Leave(Not Exist)");
1214         return;
1215     }
1216
1217     /* send wayland event to client     */
1218     if ((to >= 0) && (usurf->shsurf != NULL) && (manager !=0))    {
1219         uifw_trace("win_mgr_surface_change: Send SHELL_SURFACE_CONFIGURE(%08x,w/h=%d/%d)",
1220                    usurf->id, usurf->width, usurf->height);
1221         ivi_shell_send_configure(usurf->shsurf, usurf->id,
1222                                  (WL_SHELL_SURFACE_RESIZE_RIGHT |
1223                                   WL_SHELL_SURFACE_RESIZE_BOTTOM),
1224                                  usurf->width, usurf->height);
1225     }
1226
1227     /* send manager event to HomeScreen */
1228     if (to <= 0)    {
1229         ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_CONFIGURE,
1230                                 usurf->id, usurf->uclient->appid, usurf->layer,
1231                                 usurf->x, usurf->y, usurf->width, usurf->height,
1232                                 (manager != 0) ? 0 : 1);
1233     }
1234     uifw_trace("win_mgr_surface_change: Leave(OK)");
1235 }
1236
1237 /*--------------------------------------------------------------------------*/
1238 /**
1239  * @brief   win_mgr_surface_select: select surface by Bottun/Touch
1240  *
1241  * @param[in]   surface     Weston surface
1242  * @return      none
1243  */
1244 /*--------------------------------------------------------------------------*/
1245 static void
1246 win_mgr_surface_select(struct weston_surface *surface)
1247 {
1248     struct uifw_win_surface *usurf;
1249
1250     uifw_trace("win_mgr_surface_select: Enter(%08x)", (int)surface);
1251
1252     /* find surface         */
1253     usurf = find_uifw_win_surface_by_ws(surface);
1254     if (! usurf) {
1255         uifw_trace("win_mgr_surface_select: Leave(Not Exist)");
1256         return;
1257     }
1258
1259     /* send active event to manager     */
1260     ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_ACTIVE,
1261                     usurf->id, NULL, ICO_WINDOW_MGR_ACTIVE_SELECT, 0,0,0,0,0);
1262
1263     uifw_trace("win_mgr_surface_select: Leave(OK)");
1264 }
1265
1266 /*--------------------------------------------------------------------------*/
1267 /**
1268  * @brief   win_mgr_surface_destroy: surface destroy
1269  *
1270  * @param[in]   surface     Weston surface
1271  * @return      none
1272  */
1273 /*--------------------------------------------------------------------------*/
1274 static void
1275 win_mgr_surface_destroy(struct weston_surface *surface)
1276 {
1277     struct uifw_win_surface *usurf;
1278     struct uifw_win_surface *phash;
1279     struct uifw_win_surface *bhash;
1280     uint32_t    hash;
1281
1282     uifw_trace("win_mgr_surface_destroy: Enter(%08x)", (int)surface);
1283
1284     usurf = find_uifw_win_surface_by_ws(surface);
1285     if (! usurf) {
1286         uifw_trace("win_mgr_surface_destroy: Leave(Not Exist)");
1287         return;
1288     }
1289
1290     hash = MAKE_IDHASH(usurf->id);
1291     phash = _ico_win_mgr->idhash[hash];
1292     bhash = NULL;
1293     while ((phash) && (phash != usurf)) {
1294         bhash = phash;
1295         phash = phash->next_idhash;
1296     }
1297     if (bhash)  {
1298         bhash->next_idhash = usurf->next_idhash;
1299     }
1300     else    {
1301         _ico_win_mgr->idhash[hash] = usurf->next_idhash;
1302     }
1303
1304     hash = MAKE_WSHASH(usurf->surface);
1305     phash = _ico_win_mgr->wshash[hash];
1306     bhash = NULL;
1307     while ((phash) && (phash != usurf)) {
1308         bhash = phash;
1309         phash = phash->next_wshash;
1310     }
1311     if (bhash)  {
1312         bhash->next_wshash = usurf->next_wshash;
1313     }
1314     else    {
1315         _ico_win_mgr->wshash[hash] = usurf->next_wshash;
1316     }
1317
1318     wl_list_remove(&usurf->link);
1319     wl_list_init(&usurf->link);
1320
1321     ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_DESTROYED,
1322                            usurf->id, NULL, 0,0,0,0,0,0);
1323
1324     hash = usurf->id & SURCAFE_ID_MASK;
1325     _ico_win_mgr->surfaceid_map[(hash - 1)/16] &= ~(1 << ((hash - 1) % 16));
1326
1327     free(usurf);
1328
1329     if (win_mgr_hook_destroy) {
1330         (void) (*win_mgr_hook_destroy) (surface);
1331     }
1332     uifw_trace("win_mgr_surface_destroy: Leave(OK)");
1333 }
1334
1335 /*--------------------------------------------------------------------------*/
1336 /**
1337  * @brief   bind_ico_win_mgr: bind Multi Window Manager from client
1338  *
1339  * @param[in]   client      client
1340  * @param[in]   data        user data(unused)
1341  * @param[in]   version     protocol version(unused)
1342  * @param[in]   id          client object id
1343  * @return      none
1344  */
1345 /*--------------------------------------------------------------------------*/
1346 static void
1347 bind_ico_win_mgr(struct wl_client *client,
1348                void *data, uint32_t version, uint32_t id)
1349 {
1350     struct wl_resource *add_resource;
1351     struct uifw_manager *nm;
1352
1353     uifw_trace("bind_ico_win_mgr: Enter(client=%08x, id=%x)", (int)client, (int)id);
1354
1355     add_resource = wl_client_add_object(client, &ico_window_mgr_interface,
1356                                         &ico_window_mgr_implementation, id, _ico_win_mgr);
1357     add_resource->destroy = unbind_ico_win_mgr;
1358
1359     /* Manager                                      */
1360     nm = (struct uifw_manager *)malloc(sizeof(struct uifw_manager));
1361     memset(nm, 0, sizeof(struct uifw_manager));
1362     nm->resource = add_resource;
1363     wl_list_insert(&_ico_win_mgr->manager_list, &nm->link);
1364
1365     uifw_trace("bind_ico_win_mgr: Leave");
1366 }
1367
1368 /*--------------------------------------------------------------------------*/
1369 /**
1370  * @brief   unbind_ico_win_mgr: unbind Multi Window Manager from client
1371  *
1372  * @param[in]   resource    client resource
1373  * @return      none
1374  */
1375 /*--------------------------------------------------------------------------*/
1376 static void
1377 unbind_ico_win_mgr(struct wl_resource *resource)
1378 {
1379     struct uifw_manager *mgr, *itmp;
1380
1381     uifw_trace("unbind_ico_win_mgr: Enter");
1382
1383     /* Remove manager from manager list */
1384     _ico_win_mgr->num_manager = 0;
1385     wl_list_for_each_safe (mgr, itmp, &_ico_win_mgr->manager_list, link)    {
1386         if (mgr->resource == resource) {
1387             wl_list_remove(&mgr->link);
1388             free(mgr);
1389         }
1390         else    {
1391             if (mgr->eventcb)   {
1392                 _ico_win_mgr->num_manager++;
1393             }
1394         }
1395     }
1396
1397     free(resource);
1398     uifw_trace("unbind_ico_win_mgr: Leave");
1399 }
1400
1401 /*--------------------------------------------------------------------------*/
1402 /**
1403  * @brief   ico_winmgr_usurf_2_node: get surface nodeId
1404  *
1405  * @param[in]   surfaceid   UIFW surface id
1406  * @return      node id
1407  * @retval      >= 0        success(surface node id)
1408  * @retval      < 0         error(surface id dose not exist)
1409  */
1410 /*--------------------------------------------------------------------------*/
1411 static  int
1412 ico_winmgr_usurf_2_node(const int surfaceid)
1413 {
1414     /* currently support single ECU system  */
1415     return(ICO_IVI_SURFACEID_2_NODEID(surfaceid));
1416 }
1417
1418 /*--------------------------------------------------------------------------*/
1419 /**
1420  * @brief   ico_win_mgr_send_to_mgr: send event to manager(HomeScreen)
1421  *
1422  * @param[in]   event       event code(if -1, not send event)
1423  * @param[in]   surfaceid   UIFW surface id
1424  * @param[in]   appid       applicationId
1425  * @param[in]   param1      parameter 1
1426  * @param[in]      :             :
1427  * @param[in]   param6      parameter 6
1428  * @return      number of managers
1429  * @retval      > 0         number of managers
1430  * @retval      0           manager not exist
1431  */
1432 /*--------------------------------------------------------------------------*/
1433 static int
1434 ico_win_mgr_send_to_mgr(const int event, const int surfaceid, const char *appid,
1435                         const int param1, const int param2, const int param3,
1436                         const int param4, const int param5, const int param6)
1437 {
1438     int     num_mgr = 0;
1439     struct uifw_manager* mgr;
1440
1441     wl_list_for_each (mgr, &_ico_win_mgr->manager_list, link)   {
1442         if (mgr->eventcb)   {
1443             num_mgr ++;
1444             switch(event)   {
1445             case ICO_WINDOW_MGR_WINDOW_CREATED:
1446                 uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) WINDOW_CREATED"
1447                            "(surf=%08x,pid=%d,appid=%s)",
1448                            (int)mgr->resource, surfaceid, param1, appid);
1449                 ico_window_mgr_send_window_created(mgr->resource, surfaceid, param1, appid);
1450                 break;
1451
1452             case ICO_WINDOW_MGR_WINDOW_VISIBLE:
1453                 uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) VISIBLE"
1454                            "(surf=%08x,vis=%d,raise=%d,hint=%d)",
1455                            (int)mgr->resource, surfaceid, param1, param2, param3);
1456                 ico_window_mgr_send_window_visible(mgr->resource,
1457                                                    surfaceid, param1, param2, param3);
1458                 break;
1459
1460             case ICO_WINDOW_MGR_WINDOW_CONFIGURE:
1461                 uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) CONFIGURE"
1462                            "(surf=%08x,app=%s,layer=%d,x/y=%d/%d,w/h=%d/%d,hint=%d)",
1463                            (int)mgr->resource, surfaceid, appid,
1464                            param1, param2, param3, param4, param5, param6);
1465                 ico_window_mgr_send_window_configure(mgr->resource, surfaceid, appid,
1466                                                      param1, param2, param3, param4,
1467                                                      param5, param6);
1468                 break;
1469
1470             case ICO_WINDOW_MGR_WINDOW_DESTROYED:
1471                 uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) DESTROYED "
1472                            "surf=%08x", (int)mgr->resource, surfaceid);
1473                 ico_window_mgr_send_window_destroyed(mgr->resource, surfaceid);
1474                 break;
1475
1476             case ICO_WINDOW_MGR_WINDOW_ACTIVE:
1477                 uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) ACTIVE surf=%08x "
1478                            "active=%d", (int)mgr->resource, surfaceid, param1);
1479                 ico_window_mgr_send_window_active(mgr->resource, surfaceid,
1480                                                   (uint32_t)param1);
1481                 break;
1482
1483             default:
1484                 break;
1485             }
1486         }
1487     }
1488     return num_mgr;
1489 }
1490
1491 /*--------------------------------------------------------------------------*/
1492 /**
1493  * @brief   ico_win_mgr_hook_set_user: set hook function for set user
1494  *
1495  * @param[in]   hook_set_user   hook function
1496  * @return      none
1497  */
1498 /*--------------------------------------------------------------------------*/
1499 WL_EXPORT void
1500 ico_win_mgr_hook_set_user(void (*hook_set_user)(struct wl_client *client,
1501                                                 const char *appid))
1502 {
1503     uifw_trace("ico_win_mgr_hook_set_user: Hook %08x", (int)hook_set_user);
1504     win_mgr_hook_set_user = hook_set_user;
1505 }
1506
1507 /*--------------------------------------------------------------------------*/
1508 /**
1509  * @brief   ico_win_mgr_hook_create: set hook function for create surface
1510  *
1511  * @param[in]   hook_create     hook function
1512  * @return      none
1513  */
1514 /*--------------------------------------------------------------------------*/
1515 WL_EXPORT void
1516 ico_win_mgr_hook_create(void (*hook_create)(struct wl_client *client,
1517                                             struct weston_surface *surface,
1518                                             int surfaceId, const char *appid))
1519 {
1520     uifw_trace("ico_win_mgr_hook_create: Hook %08x", (int)hook_create);
1521     win_mgr_hook_create = hook_create;
1522 }
1523
1524 /*--------------------------------------------------------------------------*/
1525 /**
1526  * @brief   ico_win_mgr_hook_destroy: set hook function for destroy surface
1527  *
1528  * @param[in]   hook_destroy        hook function
1529  * @return      none
1530  */
1531 /*--------------------------------------------------------------------------*/
1532 WL_EXPORT void
1533 ico_win_mgr_hook_destroy(void (*hook_destroy)(struct weston_surface *surface))
1534 {
1535     uifw_trace("ico_win_mgr_hook_destroy: Hook %08x", (int)hook_destroy);
1536     win_mgr_hook_destroy = hook_destroy;
1537 }
1538
1539
1540 /*--------------------------------------------------------------------------*/
1541 /**
1542  * @brief   module_init: initialize ico_window_mgr
1543  *                       this function called from ico_pluign_loader
1544  *
1545  * @param[in]   es          weston compositor
1546  * @return      result
1547  * @retval      0           sccess
1548  * @retval      -1          error
1549  */
1550 /*--------------------------------------------------------------------------*/
1551 WL_EXPORT int
1552 module_init(struct weston_compositor *ec)
1553 {
1554     int     nodeId;
1555
1556     uifw_info("ico_window_mgr: Enter(module_init)");
1557
1558     _ico_win_mgr = (struct ico_win_mgr *)malloc(sizeof(struct ico_win_mgr));
1559     if (_ico_win_mgr == NULL)   {
1560         uifw_error("ico_window_mgr: malloc failed");
1561         return -1;
1562     }
1563
1564     memset(_ico_win_mgr, 0, sizeof(struct ico_win_mgr));
1565     _ico_win_mgr->surfaceid_map = (uint16_t *) malloc(INIT_SURFACE_IDS/8);
1566     if (! _ico_win_mgr->surfaceid_map)  {
1567         uifw_error("ico_window_mgr: malloc failed");
1568         return -1;
1569     }
1570     uifw_trace("ico_window_mgr: sh=%08x", (int)_ico_win_mgr);
1571     memset(_ico_win_mgr->surfaceid_map, 0, INIT_SURFACE_IDS/8);
1572
1573     _ico_win_mgr->compositor = ec;
1574
1575     _ico_win_mgr->surfaceid_max = INIT_SURFACE_IDS;
1576     _ico_win_mgr->surfaceid_count = INIT_SURFACE_IDS;
1577
1578     uifw_trace("ico_window_mgr: wl_display_add_global(bind_ico_win_mgr)");
1579     if (wl_display_add_global(ec->wl_display, &ico_window_mgr_interface,
1580                               _ico_win_mgr, bind_ico_win_mgr) == NULL)  {
1581         uifw_error("ico_window_mgr: Error(wl_display_add_global)");
1582         return -1;
1583     }
1584
1585     wl_list_init(&_ico_win_mgr->surface_list);
1586     wl_list_init(&_ico_win_mgr->client_list);
1587     wl_list_init(&_ico_win_mgr->manager_list);
1588
1589     nodeId = ico_ivi_get_mynode();
1590     _ico_win_mgr->surface_head = ICO_IVI_SURFACEID_BASE(nodeId);
1591     uifw_trace("ico_window_mgr: NoedId=%08x SurfaceIdBase=%08x",
1592                 nodeId, _ico_win_mgr->surface_head);
1593
1594     /* Regist usurf_2_node to ivi_common plugin     */
1595     ico_ivi_set_usurf_2_node(ico_winmgr_usurf_2_node);
1596
1597     /* Regist send_to_mgr to ivi_common plugin      */
1598     ico_ivi_set_send_to_mgr(ico_win_mgr_send_to_mgr);
1599     ico_ivi_set_send_surface_change(win_mgr_surface_change_mgr);
1600
1601     /* Hook to IVI-Shell                            */
1602     ivi_shell_hook_bind(bind_shell_client);
1603     ivi_shell_hook_unbind(unbind_shell_client);
1604     ivi_shell_hook_create(client_register_surface);
1605     ivi_shell_hook_destroy(win_mgr_surface_destroy);
1606     ivi_shell_hook_map(win_mgr_map_surface);
1607     ivi_shell_hook_change(win_mgr_surface_change);
1608     ivi_shell_hook_select(win_mgr_surface_select);
1609
1610     uifw_info("ico_window_mgr: Leave(module_init)");
1611
1612     return 0;
1613 }
1614