Corrected build dependencies.
[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-2014 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-21-2014
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/mman.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <fcntl.h>
46 #include <errno.h>
47 #include <limits.h>
48 #include <pixman.h>
49 #include <wayland-server.h>
50 #include <wayland-server.h>
51 #include <dirent.h>
52 #include <aul/aul.h>
53 #include <bundle.h>
54
55 #include <EGL/egl.h>
56 #include <GLES2/gl2.h>
57
58 #include <weston/compositor.h>
59 #include <weston/weston-layout.h>
60
61 /* detail debug log */
62 #define UIFW_DETAIL_OUT 1                   /* 1=detail debug log/0=no detail log   */
63
64 #include <weston/weston-layout.h>
65 #include <weston/ivi-shell-ext.h>
66 #include "ico_ivi_common_private.h"
67 #include "ico_window_mgr_private.h"
68 #include "ico_window_mgr-server-protocol.h"
69
70 /* gl_surface_state (inport from weston-1.4.0/src/gl-renderer.c */
71 enum buffer_type {
72     BUFFER_TYPE_NULL,
73     BUFFER_TYPE_SHM,
74     BUFFER_TYPE_EGL
75 };
76 struct uifw_gl_surface_state {      /* struct gl_surface_state  */
77     GLfloat color[4];
78     struct gl_shader *shader;
79
80     GLuint textures[3];
81     int num_textures;
82     int needs_full_upload;
83     pixman_region32_t texture_damage;
84
85     void *images[3];            /* EGLImageKHR */
86     GLenum target;
87     int num_images;
88
89     struct weston_buffer_reference buffer_ref;
90     enum buffer_type buffer_type;
91     int pitch; /* in pixels */
92     int height; /* in pixels */
93     int y_inverted;         /* add weston 1.3.x */
94 };
95
96 /* SurfaceID                            */
97 #define UIFW_HASH           64              /* Hash value (2's compliment)          */
98 #define SURCAFE_ID_MASK     0x0ffff         /* SurfaceId hash mask pattern          */
99
100 /* Internal fixed value                 */
101 #define ICO_WINDOW_MGR_APPID_FIXCOUNT   5   /* retry count of appid fix             */
102                                             /* show/hide animation with position    */
103 #define ICO_WINDOW_MGR_ANIMATION_POS    0x10000000
104
105 /* Multi Windiw Manager                 */
106 struct ico_win_mgr {
107     struct weston_compositor *compositor;   /* Weston compositor                    */
108     void    *shell;                         /* shell table address                  */
109     int32_t surface_head;                   /* (HostID << 24) | (DisplayNo << 16)   */
110
111     struct wl_list  client_list;            /* Clients                              */
112     struct wl_list  manager_list;           /* Manager(ex.HomeScreen) list          */
113
114     struct wl_list  map_list;               /* surface map list                     */
115     struct uifw_surface_map *free_maptable; /* free maped surface table list        */
116     struct weston_animation map_animation[ICO_IVI_MAX_DISPLAY];
117                                             /* animation for map check              */
118     struct wl_event_source  *wait_mapevent; /* map event send wait timer            */
119
120     char    *pixel_readbuf;                 /* surface pixel image read buffer      */
121     int     pixel_readsize;                 /* surface pixel image read buffer size */
122     struct uifw_win_surface *idhash[UIFW_HASH];  /* UIFW SerfaceID                  */
123     struct uifw_win_surface *wshash[UIFW_HASH];  /* Weston Surface                  */
124
125     char    shell_init;                     /* shell initialize flag                */
126     char    res[3];                         /* (unused)                             */
127 };
128
129 /* Internal macros                      */
130 /* UIFW SurfaceID                       */
131 #define MAKE_IDHASH(v)  (((uint32_t)v) & (UIFW_HASH-1))
132 /* Weston Surface                       */
133 #define MAKE_WSHASH(v)  ((((uint32_t)v) >> 5) & (UIFW_HASH-1))
134
135 /* function prototype                   */
136                                             /* get surface table from weston surface*/
137 static struct uifw_win_surface *find_uifw_win_surface_by_ws(
138                     struct weston_surface *wsurf);
139                                             /* bind shell client                    */
140 static void win_mgr_bind_client(struct wl_client *client, void *shell);
141                                             /* destroy client                       */
142 static void win_mgr_destroy_client(struct wl_listener *listener, void *data);
143 #if 0       /* work around: Walk through child processes until app ID is found  */
144                                             /* get parent pid                       */
145 static pid_t win_mgr_get_ppid(pid_t pid);
146 #endif      /* work around: Walk through child processes until app ID is found  */
147                                             /* get appid from pid                   */
148 static void win_mgr_get_client_appid(struct uifw_client *uclient);
149                                             /* create new surface                   */
150 static void win_mgr_register_surface(uint32_t id_surface, struct weston_surface *surface,
151                                      struct wl_client *client,
152                                      struct weston_layout_surface *ivisurf);
153                                             /* surface destroy                      */
154 static void win_mgr_destroy_surface(struct weston_surface *surface);
155                                             /* read surface pixel                   */
156 static int win_mgr_takeSurfaceScreenshot(const char *filename,
157                                          struct uifw_win_surface *usurf,
158                                          int width, int height);
159                                             /* set surface animation                */
160 static void uifw_set_animation(struct wl_client *client, struct wl_resource *resource,
161                                uint32_t surfaceid, int32_t type,
162                                const char *animation, int32_t time);
163                                             /* check and change all mapped surface  */
164 static void win_mgr_check_mapsurface(struct weston_animation *animation,
165                                      struct weston_output *output, uint32_t msecs);
166                                             /* check timer of mapped surface        */
167 static int win_mgr_timer_mapsurface(void *data);
168                                             /* check and change mapped surface      */
169 static void win_mgr_change_mapsurface(struct uifw_surface_map *sm, int event,
170                                       uint32_t curtime);
171                                             /* map surface to system application    */
172 static void uifw_map_surface(struct wl_client *client, struct wl_resource *resource,
173                              uint32_t surfaceid, int32_t framerate, const char *filepath);
174                                             /* unmap surface                        */
175 static void uifw_unmap_surface(struct wl_client *client, struct wl_resource *resource,
176                                uint32_t surfaceid);
177                                             /* bind manager                         */
178 static void bind_ico_win_mgr(struct wl_client *client,
179                              void *data, uint32_t version, uint32_t id);
180                                             /* unbind manager                       */
181 static void unbind_ico_win_mgr(struct wl_resource *resource);
182                                             /* convert animation name to Id value   */
183 static int ico_get_animation_name(const char *animation);
184                                             /* send event to controller             */
185 static void win_mgr_send_event(int event, uint32_t surfaceid, uint32_t arg1);
186                                             /* touch/click select surface           */
187 static void win_mgr_select_surface(struct weston_seat *seat,
188                                    struct weston_surface *focus, int target);
189 static void win_mgr_click_to_activate(struct weston_seat *seat, uint32_t time,
190                                       uint32_t button, void *data);
191 static void win_mgr_touch_to_activate(struct weston_seat *seat, uint32_t time,
192                                       void *data);
193                                             /* hook for create surface of ivi-shell */
194 static void ico_ivi_surfaceCreateNotification(struct weston_layout_surface *ivisurf,
195                                               void *userdata);
196                                             /* hook for remove surface of ivi-shell */
197 static void ico_ivi_surfaceRemoveNotification(struct weston_layout_surface *ivisurf,
198                                               void *userdata);
199                                             /* hook for property change of ivi-shell*/
200 static void ico_ivi_surfacePropertyNotification(struct weston_layout_surface *ivisurf,
201                                                 struct weston_layout_SurfaceProperties *prop,
202                                                 enum weston_layout_notification_mask mask,
203                                                 void *userdata);
204                                             /* hook for animation                   */
205 static int  (*win_mgr_hook_animation)(const int op, void *data) = NULL;
206                                             /* hook for input region                */
207 static void (*win_mgr_hook_change)(struct uifw_win_surface *usurf) = NULL;
208 static void (*win_mgr_hook_destory)(struct uifw_win_surface *usurf) = NULL;
209 static void (*win_mgr_hook_inputregion)(int set, struct uifw_win_surface *usurf,
210                                         int32_t x, int32_t y, int32_t width,
211                                         int32_t height, int32_t hotspot_x, int32_t hotspot_y,
212                                         int32_t cursor_x, int32_t cursor_y,
213                                         int32_t cursor_width, int32_t cursor_height,
214                                         uint32_t attr) = NULL;
215
216 /* static tables                        */
217 /* Multi Window Manager interface       */
218 static const struct ico_window_mgr_interface ico_window_mgr_implementation = {
219     uifw_set_animation,
220     uifw_map_surface,
221     uifw_unmap_surface
222 };
223
224
225 /* plugin common value(without ico_plugin_loader)   */
226 static int  _ico_ivi_option_flag = 0;           /* option flags                     */
227 static int  _ico_ivi_debug_level = 3;           /* debug Level                      */
228 static char *_ico_ivi_animation_name = NULL;    /* default animation name           */
229 static int  _ico_ivi_animation_time = 500;      /* default animation time           */
230 static int  _ico_ivi_animation_fps = 30;        /* animation frame rate             */
231
232 /* static management table              */
233 static struct ico_win_mgr       *_ico_win_mgr = NULL;
234 static int                      _ico_num_nodes = 0;
235 static struct uifw_node_table   _ico_node_table[ICO_IVI_MAX_DISPLAY];
236 static struct weston_seat       *touch_check_seat = NULL;
237
238
239 /*--------------------------------------------------------------------------*/
240 /**
241  * @brief   ico_ivi_optionflag: get option flags
242  *
243  * @param       None
244  * @return      option flags
245  */
246 /*--------------------------------------------------------------------------*/
247 WL_EXPORT   int
248 ico_ivi_optionflag(void)
249 {
250     return _ico_ivi_option_flag;
251 }
252
253 /*--------------------------------------------------------------------------*/
254 /**
255  * @brief   ico_ivi_debuglevel: answer debug output level.
256  *
257  * @param       none
258  * @return      debug output level
259  * @retval      0       No debug output
260  * @retval      1       Only error output
261  * @retval      2       Error and Warning output
262  * @retval      3       Error, Warning and information output
263  * @retval      4       Error, Warning, information and Debug Trace output
264  * @retval      5       All output with debug write
265  */
266 /*--------------------------------------------------------------------------*/
267 WL_EXPORT   int
268 ico_ivi_debuglevel(void)
269 {
270     return (_ico_ivi_debug_level & 0x0ffff);
271 }
272
273 /*--------------------------------------------------------------------------*/
274 /**
275  * @brief   ico_ivi_debugflag: get debug flags
276  *
277  * @param       None
278  * @return      debug flags
279  */
280 /*--------------------------------------------------------------------------*/
281 WL_EXPORT   int
282 ico_ivi_debugflag(void)
283 {
284     return ((_ico_ivi_debug_level >> 16) & 0x0ffff);
285 }
286
287 /*--------------------------------------------------------------------------*/
288 /**
289  * @brief   ico_ivi_default_animation_name: get default animation name
290  *
291  * @param       None
292  * @return      Default animation name
293  */
294 /*--------------------------------------------------------------------------*/
295 WL_EXPORT   const char *
296 ico_ivi_default_animation_name(void)
297 {
298     return _ico_ivi_animation_name;
299 }
300
301 /*--------------------------------------------------------------------------*/
302 /**
303  * @brief   ico_ivi_default_animation_time: get default animation time
304  *
305  * @param       None
306  * @return      Default animation time(miri sec)
307  */
308 /*--------------------------------------------------------------------------*/
309 WL_EXPORT   int
310 ico_ivi_default_animation_time(void)
311 {
312     return _ico_ivi_animation_time;
313 }
314
315 /*--------------------------------------------------------------------------*/
316 /**
317  * @brief   ico_ivi_default_animation_fps: get default animation frame rate
318  *
319  * @param       None
320  * @return      Default animation frame rate(frames/sec)
321  */
322 /*--------------------------------------------------------------------------*/
323 WL_EXPORT   int
324 ico_ivi_default_animation_fps(void)
325 {
326     return _ico_ivi_animation_fps;
327 }
328
329 /*--------------------------------------------------------------------------*/
330 /**
331  * @brief   ico_ivi_get_mynode: Get my NodeId
332  *
333  * @param       None
334  * @return      NodeId of my node
335  */
336 /*--------------------------------------------------------------------------*/
337 WL_EXPORT   int
338 ico_ivi_get_mynode(void)
339 {
340     /* Reference Platform 0.90 only support 1 ECU   */
341     return 0;
342 }
343
344 /*--------------------------------------------------------------------------*/
345 /**
346  * @brief   ico_ivi_surface_buffer_width: get surface buffer width
347  *
348  * @param[in]   es          weston surface
349  * @return      buffer width(if surface has no buffer, return 0)
350  */
351 /*--------------------------------------------------------------------------*/
352 WL_EXPORT   int
353 ico_ivi_surface_buffer_width(struct weston_surface *es)
354 {
355     int v;
356
357     if (! es->buffer_ref.buffer)    {
358         return 0;
359     }
360     if (es->buffer_viewport.viewport_set)   {
361         return es->buffer_viewport.dst_width;
362     }
363     switch (es->buffer_viewport.transform) {
364     case WL_OUTPUT_TRANSFORM_90:
365     case WL_OUTPUT_TRANSFORM_270:
366     case WL_OUTPUT_TRANSFORM_FLIPPED_90:
367     case WL_OUTPUT_TRANSFORM_FLIPPED_270:
368         v = es->buffer_ref.buffer->height;
369         break;
370     default:
371         v = es->buffer_ref.buffer->width;
372         break;
373     }
374     return (v / es->buffer_viewport.scale);
375 }
376
377 /*--------------------------------------------------------------------------*/
378 /**
379  * @brief   ico_ivi_surface_buffer_height: get surface buffer height
380  *
381  * @param[in]   es          weston surface
382  * @return      buffer height(if surface has no buffer, return 0)
383  */
384 /*--------------------------------------------------------------------------*/
385 WL_EXPORT   int
386 ico_ivi_surface_buffer_height(struct weston_surface *es)
387 {
388     int v;
389
390     if (! es->buffer_ref.buffer)    {
391         return 0;
392     }
393     if (es->buffer_viewport.viewport_set)   {
394         return es->buffer_viewport.dst_height;
395     }
396     switch (es->buffer_viewport.transform) {
397     case WL_OUTPUT_TRANSFORM_90:
398     case WL_OUTPUT_TRANSFORM_270:
399     case WL_OUTPUT_TRANSFORM_FLIPPED_90:
400     case WL_OUTPUT_TRANSFORM_FLIPPED_270:
401         v = es->buffer_ref.buffer->width;
402         break;
403     default:
404         v = es->buffer_ref.buffer->height;
405         break;
406     }
407     return (v / es->buffer_viewport.scale);
408 }
409
410 /*--------------------------------------------------------------------------*/
411 /**
412  * @brief   ico_ivi_surface_buffer_size: get surface buffer size
413  *
414  * @param[in]   es          weston surface
415  * @param[out]  width       buffer width
416  * @param[out]  height      buffer height
417  * @return      nothing
418  */
419 /*--------------------------------------------------------------------------*/
420 WL_EXPORT   void
421 ico_ivi_surface_buffer_size(struct weston_surface *es, int *width, int *height)
422 {
423     if (! es->buffer_ref.buffer)    {
424         *width = 0;
425         *height = 0;
426     }
427     else if (es->buffer_viewport.viewport_set)  {
428         *width = es->buffer_viewport.dst_width;
429         *height = es->buffer_viewport.dst_height;
430     }
431     else    {
432         switch (es->buffer_viewport.transform) {
433         case WL_OUTPUT_TRANSFORM_90:
434         case WL_OUTPUT_TRANSFORM_270:
435         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
436         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
437             *width = es->buffer_ref.buffer->height;
438             *height = es->buffer_ref.buffer->width;
439             break;
440         default:
441             *width = es->buffer_ref.buffer->width;
442             *height = es->buffer_ref.buffer->height;
443             break;
444         }
445         *width = *width / es->buffer_viewport.scale;
446         *height = *height / es->buffer_viewport.scale;
447     }
448 }
449
450 /*--------------------------------------------------------------------------*/
451 /**
452  * @brief   ico_ivi_surface_buffer_size: get surface buffer size
453  *
454  * @param[in]   es          weston surface
455  * @param[out]  width       buffer width
456  * @param[out]  height      buffer height
457  * @return      nothing
458  */
459 /*--------------------------------------------------------------------------*/
460 WL_EXPORT   struct weston_view *
461 ico_ivi_get_primary_view(struct uifw_win_surface *usurf)
462 {
463     struct weston_view  *ev = NULL;
464     struct shell_surface *shsurf;
465
466     if (_ico_win_mgr->compositor->shell_interface.get_primary_view) {
467         shsurf = usurf->surface->configure_private;
468         if (shsurf) {
469             ev = (*_ico_win_mgr->compositor->shell_interface.get_primary_view)(NULL, shsurf);
470         }
471     }
472     if (! ev)   {
473         ev = weston_layout_get_weston_view(usurf->ivisurf);
474     }
475     if (! ev)   {
476         uifw_error("ico_ivi_get_primary_view: usurf=%08x(%x) surface=%08x has no view",
477                    (int)usurf, usurf->surfaceid, (int)usurf->surface);
478     }
479     return ev;
480 }
481
482 /*--------------------------------------------------------------------------*/
483 /**
484  * @brief   ico_window_mgr_set_weston_surface: set weston surface
485  *
486  * @param[in]   usurf       UIFW surface
487  * @param[in]   x           X coordinate on screen
488  * @param[in]   y           Y coordinate on screen
489  * @param[in]   width       width
490  * @param[in]   height      height
491  * @return      none
492  */
493 /*--------------------------------------------------------------------------*/
494 WL_EXPORT   void
495 ico_window_mgr_set_weston_surface(struct uifw_win_surface *usurf,
496                                   int x, int y, int width, int height)
497 {
498     struct weston_surface *es = usurf->surface;
499     struct weston_layout_SurfaceProperties  prop;
500     int     buf_width, buf_height;
501
502     if ((es == NULL) || (usurf->ivisurf == NULL))    {
503         uifw_trace("ico_window_mgr_set_weston_surface: usurf(%08x) has no surface",
504                    (int)usurf);
505         return;
506     }
507
508     if (es->buffer_ref.buffer != NULL)   {
509         ico_ivi_surface_buffer_size(es, &buf_width, &buf_height);
510         if ((width <= 0) || (height <= 0))    {
511             width = buf_width;
512             usurf->width = buf_width;
513             height = buf_height;
514             usurf->height = buf_height;
515         }
516         if (usurf->width > buf_width)   {
517             width = buf_width;
518             x += (usurf->width - buf_width)/2;
519         }
520         if (usurf->height > buf_height) {
521             height = buf_height;
522             y += (usurf->height - buf_height)/2;
523         }
524         if (usurf->visible) {
525             x += usurf->node_tbl->disp_x;
526             y += usurf->node_tbl->disp_y;
527         }
528         else    {
529             x = ICO_IVI_MAX_COORDINATE+1;
530             y = ICO_IVI_MAX_COORDINATE+1;
531         }
532         if (weston_layout_getPropertiesOfSurface(usurf->ivisurf, &prop) == 0)   {
533             if ((prop.destX != x) || (prop.destY != y) ||
534                 (prop.destWidth != (uint32_t)width) ||
535                 (prop.destHeight != (uint32_t)height))  {
536                 if (weston_layout_surfaceSetDestinationRectangle(
537                                         usurf->ivisurf, x, y, width, height) == 0)  {
538                     weston_layout_commitChanges();
539                 }
540             }
541         }
542         weston_surface_damage(es);
543     }
544 }
545
546 /*--------------------------------------------------------------------------*/
547 /**
548  * @brief   ico_window_mgr_get_usurf: find UIFW surface by surface id
549  *
550  * @param[in]   surfaceid   UIFW surface id
551  * @return      UIFW surface table address
552  * @retval      !=NULL      success(surface table address)
553  * @retval      NULL        error(surface id dose not exist)
554  */
555 /*--------------------------------------------------------------------------*/
556 WL_EXPORT   struct uifw_win_surface *
557 ico_window_mgr_get_usurf(const uint32_t surfaceid)
558 {
559     struct uifw_win_surface *usurf;
560
561     usurf = _ico_win_mgr->idhash[MAKE_IDHASH(surfaceid)];
562
563     while (usurf)   {
564         if (usurf->surfaceid == surfaceid) {
565             return usurf;
566         }
567         usurf = usurf->next_idhash;
568     }
569     uifw_trace("ico_window_mgr_get_usurf: NULL");
570     return NULL;
571 }
572
573 /*--------------------------------------------------------------------------*/
574 /**
575  * @brief   ico_window_mgr_get_usurf_client: find UIFW surface by surface id/or client
576  *
577  * @param[in]   surfaceid   UIFW surface id
578  * @param[in]   client      Wayland client
579  * @return      UIFW surface table address
580  * @retval      !=NULL      success(surface table address)
581  * @retval      NULL        error(surface id or client dose not exist)
582  */
583 /*--------------------------------------------------------------------------*/
584 WL_EXPORT   struct uifw_win_surface *
585 ico_window_mgr_get_usurf_client(const uint32_t surfaceid, struct wl_client *client)
586 {
587     struct uifw_win_surface *usurf;
588
589     usurf = ico_window_mgr_get_usurf(surfaceid);
590     return usurf;
591 }
592
593 /*--------------------------------------------------------------------------*/
594 /**
595  * @brief   find_uifw_win_surface_by_ws: find UIFW surface by weston surface
596  *
597  * @param[in]   wsurf       Weston surface
598  * @return      UIFW surface table address
599  * @retval      !=NULL      success(surface table address)
600  * @retval      NULL        error(surface dose not exist)
601  */
602 /*--------------------------------------------------------------------------*/
603 static struct uifw_win_surface *
604 find_uifw_win_surface_by_ws(struct weston_surface *wsurf)
605 {
606     struct uifw_win_surface *usurf;
607
608     usurf = _ico_win_mgr->wshash[MAKE_WSHASH(wsurf)];
609
610     while (usurf)   {
611         if (usurf->surface == wsurf) {
612             return usurf;
613         }
614         usurf = usurf->next_wshash;
615     }
616     uifw_trace("find_uifw_win_surface_by_ws: NULL");
617     return NULL;
618 }
619
620 /*--------------------------------------------------------------------------*/
621 /**
622  * @brief   ico_window_mgr_find_uclient: find UIFW client by wayland client
623  *
624  * @param[in]   client      Wayland client
625  * @return      UIFW client table address
626  * @retval      !=NULL      success(client table address)
627  * @retval      NULL        error(client dose not exist)
628  */
629 /*--------------------------------------------------------------------------*/
630 WL_EXPORT   struct uifw_client*
631 ico_window_mgr_find_uclient(struct wl_client *client)
632 {
633     struct uifw_client  *uclient;
634
635     wl_list_for_each (uclient, &_ico_win_mgr->client_list, link)    {
636         if (uclient->client == client)  {
637             return(uclient);
638         }
639     }
640     uifw_trace("ico_window_mgr_find_uclient: client.%08x is NULL", (int)client);
641     return NULL;
642 }
643
644 /*--------------------------------------------------------------------------*/
645 /**
646  * @brief   ico_window_mgr_get_appid: find application id by wayland client
647  *
648  * @param[in]   client      Wayland client
649  * @return      application id
650  * @retval      !=NULL      success(application id)
651  * @retval      NULL        error(client dose not exist)
652  */
653 /*--------------------------------------------------------------------------*/
654 WL_EXPORT   char *
655 ico_window_mgr_get_appid(struct wl_client* client)
656 {
657     struct uifw_client  *uclient;
658
659     uclient = ico_window_mgr_find_uclient(client);
660
661     if (! uclient)  {
662         return NULL;
663     }
664     return uclient->appid;
665 }
666
667 /*--------------------------------------------------------------------------*/
668 /**
669  * @brief   ico_window_mgr_get_display_coordinate: get display coordinate
670  *
671  * @param[in]   displayno   display number
672  * @param[out]  x           relative X coordinate
673  * @param[out]  y           relative Y coordinate
674  * @return      none
675  */
676 /*--------------------------------------------------------------------------*/
677 WL_EXPORT   void
678 ico_window_mgr_get_display_coordinate(int displayno, int *x, int *y)
679 {
680     if ((displayno <= _ico_num_nodes) || (displayno < 0))   {
681         displayno = 0;
682     }
683     *x = _ico_node_table[displayno].disp_x;
684     *y = _ico_node_table[displayno].disp_y;
685 }
686
687 /*--------------------------------------------------------------------------*/
688 /**
689  * @brief   win_mgr_bind_client: desktop_shell from client
690  *
691  * @param[in]   client          Wayland client
692  * @param[in]   shell           shell table address
693  * @return      none
694  */
695 /*--------------------------------------------------------------------------*/
696 static void
697 win_mgr_bind_client(struct wl_client *client, void *shell)
698 {
699     struct uifw_client  *uclient;
700     int     newclient;
701     pid_t   pid;
702     uid_t   uid;
703     gid_t   gid;
704
705     uifw_trace("win_mgr_bind_client: Enter(client=%08x, shell=%08x)",
706                (int)client, (int)shell);
707
708     /* save shell table address             */
709     if (shell)  {
710         _ico_win_mgr->shell = shell;
711     }
712
713     /* set client                           */
714     uclient = ico_window_mgr_find_uclient(client);
715     if (! uclient)  {
716         /* client not exist, create client management table             */
717         uifw_trace("win_mgr_bind_client: Create Client");
718         uclient = (struct uifw_client *)malloc(sizeof(struct uifw_client));
719         if (!uclient)   {
720             uifw_error("win_mgr_bind_client: Error, No Memory");
721             return;
722         }
723         memset(uclient, 0, sizeof(struct uifw_client));
724         uclient->client = client;
725         wl_list_init(&uclient->surface_link);
726         newclient = 1;
727         uclient->destroy_listener.notify = win_mgr_destroy_client;
728         wl_client_add_destroy_listener(client, &uclient->destroy_listener);
729     }
730     else    {
731         newclient = 0;
732     }
733     wl_client_get_credentials(client, &pid, &uid, &gid);
734     uifw_trace("win_mgr_bind_client: client=%08x pid=%d uid=%d gid=%d",
735                (int)client, (int)pid, (int)uid, (int)gid);
736     if (pid > 0)    {
737         uclient->pid = (int)pid;
738         /* get applicationId from AppCore(AUL)  */
739         win_mgr_get_client_appid(uclient);
740
741         if (newclient > 0)  {
742             wl_list_insert(&_ico_win_mgr->client_list, &uclient->link);
743         }
744     }
745     else    {
746         uifw_trace("win_mgr_bind_client: client=%08x pid dose not exist", (int)client);
747     }
748     uifw_trace("win_mgr_bind_client: Leave");
749 }
750
751 /*--------------------------------------------------------------------------*/
752 /**
753  * @brief   win_mgr_destroy_client: destroy client
754  *
755  * @param[in]   listener    listener
756  * @param[in]   data        listener
757  * @return      none
758  */
759 /*--------------------------------------------------------------------------*/
760 static void
761 win_mgr_destroy_client(struct wl_listener *listener, void *data)
762 {
763     struct uifw_client  *uclient;
764
765     uclient = container_of(listener, struct uifw_client, destroy_listener);
766
767     uifw_trace("win_mgr_destroy_client: Enter(uclient=%08x)", (int)uclient);
768
769     if (uclient)    {
770         /* Client exist, Destory client management table             */
771         wl_list_remove(&uclient->link);
772         free(uclient);
773     }
774     uifw_trace("win_mgr_destroy_client: Leave");
775 }
776
777 #if 0       /* work around: Walk through child processes until app ID is found  */
778 /*--------------------------------------------------------------------------*/
779 /**
780  * @brief   win_mgr_get_ppid: Get parent process ID.
781  *
782  * Similar to getppid(), except that this implementation accepts an
783  * arbitrary process ID.
784  *
785  * @param[in]   pid     Process ID of child process
786  * @return      parent process ID on success, -1 on failure
787  */
788 /*--------------------------------------------------------------------------*/
789 static pid_t
790 win_mgr_get_ppid(pid_t pid)
791 {
792     pid_t ppid = -1;
793     char procpath[PATH_MAX] = { 0 };
794
795     snprintf(procpath, sizeof(procpath)-1, "/proc/%d/status", pid);
796
797     /* We better have read permissions! */
798     int const fd = open(procpath, O_RDONLY);
799
800     if (fd < 0)
801         return ppid;
802
803     char buffer[1024] = { 0 };
804
805     ssize_t const size = read(fd, buffer, sizeof(buffer));
806     close(fd);
807
808     if (size <= 0)
809         return ppid;
810
811     /* Find line containing the parent process ID. */
812     char const * const ppid_line = strstr(buffer, "PPid");
813
814     if (ppid_line != NULL)
815         sscanf(ppid_line, "PPid:    %d", &ppid);
816
817     return ppid;
818 }
819 #endif      /* work around: Walk through child processes until app ID is found  */
820
821 /*--------------------------------------------------------------------------*/
822 /**
823  * @brief   win_mgr_get_client_appid: get applicationId from pid
824  *
825  * @param[in]   uclient     UIFW client management table
826  * @return      none
827  */
828 /*--------------------------------------------------------------------------*/
829 static void
830 win_mgr_get_client_appid(struct uifw_client *uclient)
831 {
832     int status = AUL_R_ERROR;
833
834     memset(uclient->appid, 0, ICO_IVI_APPID_LENGTH);
835
836 #if 0       /* work around: Walk through child processes until app ID is found  */
837     /*
838      * Walk the parent process chain until we find a parent process
839      * with an app ID.
840      */
841     int pid;
842
843     for (pid = uclient->pid;
844          pid > 1 && status != AUL_R_OK;
845          pid = win_mgr_get_ppid(pid)) {
846
847         status = aul_app_get_appid_bypid(pid,
848                                          uclient->appid,
849                                          ICO_IVI_APPID_LENGTH);
850
851         uifw_trace("win_mgr_get_client_appid: aul_app_get_appid_bypid ret=%d "
852                    "pid=%d appid=<%s>", status, pid, uclient->appid);
853     }
854     /*
855      * Walk the child process chain as well since app ID was not yet found
856      */
857     if (status != AUL_R_OK) {
858
859         DIR *dr;
860         struct dirent *de;
861         struct stat ps;
862         pid_t   tpid;
863         uid_t   uid;
864         gid_t   gid;
865
866         dr = opendir("/proc/");
867
868         /* get uid */
869         wl_client_get_credentials(uclient->client, &tpid, &uid, &gid);
870
871         while(((de = readdir(dr)) != NULL) && (status != AUL_R_OK)) {
872
873             char fullpath[PATH_MAX] = { 0 };
874             int is_child = 0;
875             int tmppid;
876
877             snprintf(fullpath, sizeof(fullpath)-1, "/proc/%s", de->d_name);
878
879             if (stat(fullpath, &ps) == -1) {
880                 continue;
881             }
882
883             /* find pid dirs for this user (uid) only */
884             if (ps.st_uid != uid)
885                 continue;
886
887             pid = atoi(de->d_name);
888
889             /* check if it's a valid child */
890             if (pid < uclient->pid)
891                 continue;
892
893             /* scan up to pid to find if a chain exists */
894             for (tmppid = pid; tmppid > uclient->pid;) {
895                 tmppid = win_mgr_get_ppid(tmppid);
896                 if (tmppid == uclient->pid)
897                     is_child = 1;
898             }
899
900             if (is_child) {
901                 status = aul_app_get_appid_bypid(pid, uclient->appid,
902                                                       ICO_IVI_APPID_LENGTH);
903
904                 uifw_debug("win_mgr_get_client_appid: aul_app_get_appid_bypid "
905                            "ret=%d pid=%d appid=<%s>", status, pid,
906                            uclient->appid);
907             }
908         }
909     }
910 #else       /* work around: Walk through child processes until app ID is found  */
911     status = aul_app_get_appid_bypid(uclient->pid, uclient->appid, ICO_IVI_APPID_LENGTH);
912     uifw_trace("win_mgr_get_client_appid: aul_app_get_appid_bypid ret=%d "
913                "pid=%d appid=<%s>", status, uclient->pid, uclient->appid);
914 #endif      /* work around: Walk through child processes until app ID is found  */
915
916     if (uclient->appid[0] != 0) {
917         /* OK, end of get appid         */
918         uclient->fixed_appid = ICO_WINDOW_MGR_APPID_FIXCOUNT;
919     }
920     else    {
921         /* client does not exist in AppCore, search Linux process table */
922
923         int     fd;
924         int     size;
925         int     i;
926         int     j;
927         char    procpath[128];
928
929         uclient->fixed_appid ++;
930         memset(uclient->appid, 0, ICO_IVI_APPID_LENGTH);
931         snprintf(procpath, sizeof(procpath)-1, "/proc/%d/cmdline", uclient->pid);
932         fd = open(procpath, O_RDONLY);
933         if (fd >= 0)    {
934             size = read(fd, procpath, sizeof(procpath));
935             for (; size > 0; size--)    {
936                 if (procpath[size-1])   break;
937             }
938             if (size > 0)   {
939                 /* get program base name    */
940                 i = 0;
941                 for (j = 0; j < size; j++)  {
942                     if (procpath[j] == 0)   break;
943                     if (procpath[j] == '/') i = j + 1;
944                 }
945                 j = 0;
946                 for (; i < size; i++)   {
947                     uclient->appid[j] = procpath[i];
948                     if ((uclient->appid[j] == 0) ||
949                         (j >= (ICO_IVI_APPID_LENGTH-1)))    break;
950                     j++;
951                 }
952                 /* search application number in apprication start option    */
953                 if ((uclient->appid[j] == 0) && (j < (ICO_IVI_APPID_LENGTH-2))) {
954                     for (; i < size; i++)   {
955                         if ((procpath[i] == 0) &&
956                             (procpath[i+1] == '@')) {
957                             strncpy(&uclient->appid[j], &procpath[i+1],
958                                     ICO_IVI_APPID_LENGTH - j - 2);
959                         }
960                     }
961                 }
962             }
963             close(fd);
964         }
965         for (i = strlen(uclient->appid)-1; i >= 0; i--) {
966             if (uclient->appid[i] != ' ')   break;
967         }
968         uclient->appid[i+1] = 0;
969         if (uclient->appid[0])  {
970             uifw_trace("win_mgr_get_client_appid: pid=%d appid=<%s> from "
971                        "Process table(%d)",
972                        uclient->pid, uclient->appid, uclient->fixed_appid );
973         }
974         else    {
975             uifw_trace("win_mgr_get_client_appid: pid=%d dose not exist in Process table",
976                        uclient->pid);
977             sprintf(uclient->appid, "?%d?", uclient->pid);
978         }
979     }
980 }
981
982 /*--------------------------------------------------------------------------*/
983 /**
984  * @brief   ico_get_animation_name: convert animation name to Id value
985  *
986  * @param[in]   animation       animation name
987  * @return      animation Id value
988  */
989 /*--------------------------------------------------------------------------*/
990 static int
991 ico_get_animation_name(const char *animation)
992 {
993     int anima = ICO_WINDOW_MGR_ANIMATION_NONE;
994
995     if (strcasecmp(animation, "none") == 0) {
996         return ICO_WINDOW_MGR_ANIMATION_NONE;
997     }
998
999     if (win_mgr_hook_animation) {
1000         anima = (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_NAME, (void *)animation);
1001     }
1002     if (anima <= 0) {
1003         anima = ICO_WINDOW_MGR_ANIMATION_NONE;
1004     }
1005     return anima;
1006 }
1007
1008 /*--------------------------------------------------------------------------*/
1009 /**
1010  * @brief   win_mgr_send_event: send event to controller
1011  *
1012  * @param[in]   event           event code
1013  * @param[in]   surfaceid       surface id
1014  * @param[in]   arg1            argument 1
1015  * @return      none
1016  */
1017 /*--------------------------------------------------------------------------*/
1018 static void
1019 win_mgr_send_event(int event, uint32_t surfaceid, uint32_t arg1)
1020 {
1021     struct uifw_manager     *mgr;
1022
1023     /* send event to manager     */
1024     wl_list_for_each (mgr, &_ico_win_mgr->manager_list, link)   {
1025         switch (event)  {
1026         case ICO_WINDOW_MGR_WINDOW_ACTIVE:      /* active event             */
1027             uifw_trace("win_mgr_send_event: Send ACTIVE(surf=%08x, select=%x)",
1028                        surfaceid, arg1);
1029             ico_window_mgr_send_window_active(mgr->resource, surfaceid, arg1);
1030             break;
1031         case ICO_WINDOW_MGR_DESTROY_SURFACE:    /* surface destroy event    */
1032             uifw_trace("win_mgr_send_event: Send DESTROY_SURFACE(surf=%08x)", surfaceid);
1033             ico_window_mgr_send_destroy_surface(mgr->resource, surfaceid);
1034             break;
1035         default:
1036             uifw_error("win_mgr_send_event: Unknown event(%d)", event);
1037             break;
1038         }
1039     }
1040 }
1041
1042 /*--------------------------------------------------------------------------*/
1043 /**
1044  * @brief   win_mgr_select_surface: select surface by mouse click
1045  *
1046  * @param[in]   seat            weston seat
1047  * @param[in]   focus           selected surface
1048  * @param[in]   select          selected device
1049  * @return      none
1050  */
1051 /*--------------------------------------------------------------------------*/
1052 static void
1053 win_mgr_select_surface(struct weston_seat *seat, struct weston_surface *focus, int select)
1054 {
1055     struct weston_surface   *surface;
1056     struct uifw_win_surface *usurf;
1057     struct uifw_manager     *mgr;
1058
1059     surface = weston_surface_get_main_surface(focus);
1060
1061     uifw_trace("win_mgr_select_surface: Enter(%08x,%d)", (int)surface, select);
1062
1063     if (! surface)  {
1064         uifw_trace("win_mgr_select_surface: Leave(no surface)");
1065         return;
1066     }
1067     /* find surface         */
1068     usurf = find_uifw_win_surface_by_ws(surface);
1069     if (! usurf) {
1070         uifw_trace("win_mgr_select_surface: Leave(usurf not exist)");
1071         return;
1072     }
1073     /* surface active       */
1074     weston_surface_activate(surface, seat);
1075
1076     /* send active event to manager     */
1077     wl_list_for_each (mgr, &_ico_win_mgr->manager_list, link)   {
1078         uifw_trace("win_mgr_select_surface: Send Manager ACTIVE(surf=%08x)",
1079                    usurf->surfaceid);
1080         ico_window_mgr_send_window_active(mgr->resource, usurf->surfaceid,
1081                                           select);
1082     }
1083     uifw_trace("win_mgr_select_surface: Leave");
1084 }
1085
1086 /*--------------------------------------------------------------------------*/
1087 /**
1088  * @brief   win_mgr_click_to_activate: select surface by mouse click
1089  *
1090  * @param[in]   seat            weston seat
1091  * @param[in]   time            click time(current time)
1092  * @param[in]   button          click button
1093  * @param[in]   data            user data(unused)
1094  * @return      none
1095  */
1096 /*--------------------------------------------------------------------------*/
1097 static void
1098 win_mgr_click_to_activate(struct weston_seat *seat, uint32_t time,
1099                           uint32_t button, void *data)
1100 {
1101     if (seat->pointer->grab != &seat->pointer->default_grab)
1102         return;
1103     if (seat->pointer->focus == NULL)
1104         return;
1105
1106     win_mgr_select_surface(seat, seat->pointer->focus->surface,
1107                            ICO_WINDOW_MGR_SELECT_POINTER);
1108 }
1109
1110 /*--------------------------------------------------------------------------*/
1111 /**
1112  * @brief   win_mgr_touch_to_activate: select surface by touch touch-panel
1113  *
1114  * @param[in]   seat            weston seat
1115  * @param[in]   time            click time(current time)
1116  * @param[in]   data            user data(unused)
1117  * @return      none
1118  */
1119 /*--------------------------------------------------------------------------*/
1120 static void
1121 win_mgr_touch_to_activate(struct weston_seat *seat, uint32_t time, void *data)
1122 {
1123     if (seat->touch->grab != &seat->touch->default_grab)
1124         return;
1125     if (seat->touch->focus == NULL)
1126         return;
1127
1128     win_mgr_select_surface(seat, seat->touch->focus->surface, ICO_WINDOW_MGR_SELECT_TOUCH);
1129 }
1130
1131 /*--------------------------------------------------------------------------*/
1132 /**
1133  * @brief   ico_ivi_surfaceCreateNotification: create ivi-surface
1134  *
1135  * @param[in]   ivisurf         ivi surface
1136  * @param[in]   userdata        User Data(Unused)
1137  * @return      none
1138  */
1139 /*--------------------------------------------------------------------------*/
1140 static void
1141 ico_ivi_surfaceCreateNotification(struct weston_layout_surface *ivisurf, void *userdata)
1142 {
1143     uint32_t                id_surface;
1144     struct weston_view      *ev;
1145     struct weston_surface   *es;
1146     struct wl_client        *client;
1147
1148     id_surface = weston_layout_getIdOfSurface(ivisurf);
1149     uifw_trace("ico_ivi_surfaceCreateNotification: Create %x", id_surface);
1150
1151     /* set property notification    */
1152     if (weston_layout_surfaceAddNotification(ivisurf, ico_ivi_surfacePropertyNotification, NULL) != 0)  {
1153         uifw_error("ico_ivi_surfaceCreateNotification: weston_layout_surfaceAddNotification Error");
1154     }
1155     ev = weston_layout_get_weston_view(ivisurf);
1156     if (! ev)   {
1157         uifw_error("ico_ivi_surfaceCreateNotification: weston_layout_get_weston_view Error");
1158     }
1159     else    {
1160         es = ev->surface;
1161         if (! es)   {
1162             uifw_error("ico_ivi_surfaceCreateNotification: no weston_surface");
1163         }
1164         else    {
1165             client = wl_resource_get_client(es->resource);
1166             if (! client)   {
1167                 uifw_error("ico_ivi_surfaceCreateNotification: no wl_client");
1168             }
1169             else    {
1170                 win_mgr_register_surface(id_surface, es, client, ivisurf);
1171             }
1172         }
1173     }
1174 }
1175
1176 /*--------------------------------------------------------------------------*/
1177 /**
1178  * @brief   ico_ivi_surfaceRemoveNotification: remove ivi-surface
1179  *
1180  * @param[in]   ivisurf         ivi surface
1181  * @param[in]   userdata        User Data(Unused)
1182  * @return      none
1183  */
1184 /*--------------------------------------------------------------------------*/
1185 static void
1186 ico_ivi_surfaceRemoveNotification(struct weston_layout_surface *ivisurf, void *userdata)
1187 {
1188     uint32_t    id_surface;
1189     struct weston_view      *ev;
1190     struct weston_surface   *es;
1191
1192     id_surface = weston_layout_getIdOfSurface(ivisurf);
1193     uifw_trace("ico_ivi_surfaceRemoveNotification: Remove %x", id_surface);
1194
1195     ev = weston_layout_get_weston_view(ivisurf);
1196     if (! ev)   {
1197         uifw_error("ico_ivi_surfaceRemoveNotification: weston_layout_get_weston_view Error");
1198     }
1199     else    {
1200         es = ev->surface;
1201         if (! es)   {
1202             uifw_error("ico_ivi_surfaceRemoveNotification: no weston_surface");
1203         }
1204         else    {
1205             win_mgr_destroy_surface(es);
1206         }
1207     }
1208 }
1209
1210 /*--------------------------------------------------------------------------*/
1211 /**
1212  * @brief   ico_ivi_surfacePropertyNotification: property change ivi-surface
1213  *
1214  * @param[in]   ivisurf         ivi surface
1215  * @param[in]   userdata        User Data(Unused)
1216  * @return      none
1217  */
1218 /*--------------------------------------------------------------------------*/
1219 static void
1220 ico_ivi_surfacePropertyNotification(struct weston_layout_surface *ivisurf,
1221                                     struct weston_layout_SurfaceProperties *prop,
1222                                     enum weston_layout_notification_mask mask,
1223                                     void *userdata)
1224 {
1225     struct uifw_manager *mgr;
1226     uint32_t    id_surface;
1227     int         retanima;
1228     uint32_t    newmask;
1229     struct uifw_win_surface *usurf;
1230     struct weston_view      *ev;
1231
1232     newmask = ((uint32_t)mask) & (~(IVI_NOTIFICATION_OPACITY|IVI_NOTIFICATION_ORIENTATION|
1233                                     IVI_NOTIFICATION_PIXELFORMAT));
1234     id_surface = weston_layout_getIdOfSurface(ivisurf);
1235     usurf = ico_window_mgr_get_usurf(id_surface);
1236
1237     if ((newmask != 0) && (usurf != NULL))  {
1238         uifw_trace("ico_ivi_surfacePropertyNotification: Property %x(%08x) usurf=%08x",
1239                    id_surface, newmask, (int)usurf);
1240         if (newmask & (IVI_NOTIFICATION_SOURCE_RECT|IVI_NOTIFICATION_DEST_RECT|
1241                        IVI_NOTIFICATION_POSITION|IVI_NOTIFICATION_DIMENSION))   {
1242             /* change position or size  */
1243             uifw_trace("ico_ivi_surfacePropertyNotification: %08x x/y=%d/%d->%d/%d "
1244                        "w/h=%d/%d->%d/%d(%d/%d)", id_surface, usurf->x, usurf->y,
1245                        prop->destX, prop->destY, usurf->width, usurf->height,
1246                        prop->destWidth, prop->destHeight,
1247                        prop->sourceWidth, prop->sourceHeight);
1248             if ((usurf->client_width == prop->sourceWidth) &&
1249                 (usurf->client_height == prop->sourceHeight))   {
1250                 newmask &= (~IVI_NOTIFICATION_SOURCE_RECT);
1251             }
1252             else    {
1253                 usurf->client_width = prop->sourceWidth;
1254                 usurf->client_height = prop->sourceHeight;
1255             }
1256             if ((usurf->x == prop->destX) && (usurf->y == prop->destY) &&
1257                 (usurf->width == prop->destWidth) && (usurf->height == prop->destHeight)) {
1258                 newmask &= (~(IVI_NOTIFICATION_DEST_RECT|
1259                               IVI_NOTIFICATION_POSITION|IVI_NOTIFICATION_DIMENSION));
1260             }
1261             else    {
1262                 usurf->x = prop->destX;
1263                 usurf->y = prop->destY;
1264                 usurf->width = prop->destWidth;
1265                 usurf->height = prop->destHeight;
1266                 if ((usurf->width != usurf->configure_width) ||
1267                     (usurf->height != usurf->configure_height)) {
1268                     /* send configure to client(App)        */
1269                     uifw_trace("ico_ivi_surfacePropertyNotification: send configure "
1270                                "%08x(%d,%d->%d,%d)", usurf->surfaceid,
1271                                usurf->configure_width, usurf->configure_height,
1272                                usurf->width, usurf->height);
1273                     usurf->configure_width = usurf->width;
1274                     usurf->configure_height = usurf->height;
1275
1276                     struct wl_array surfaces;
1277                     struct shell_surface;
1278                     void    **shsurf;
1279                     if (! usurf->shsurf_resource)   {
1280                         /* get shell surface if not get */
1281                         ivi_shell_get_shell_surfaces(&surfaces);
1282                         wl_array_for_each(shsurf, &surfaces)    {
1283                             if (shell_surface_get_surface(*shsurf) == usurf->surface)   {
1284                                 usurf->shsurf_resource = *((struct wl_resource **)*shsurf);
1285                                 break;
1286                             }
1287                         }
1288                         wl_array_release(&surfaces);
1289                     }
1290                     if (usurf->shsurf_resource) {
1291                         uifw_trace("ico_ivi_surfacePropertyNotification: surface %08x "
1292                                    "resource=%08x",
1293                                    usurf->surfaceid, (int)usurf->shsurf_resource);
1294                         wl_shell_surface_send_configure(usurf->shsurf_resource,
1295                                         WL_SHELL_SURFACE_RESIZE_RIGHT|
1296                                             WL_SHELL_SURFACE_RESIZE_BOTTOM,
1297                                         usurf->configure_width, usurf->configure_height);
1298                     }
1299                     else    {
1300                         uifw_trace("ico_ivi_surfacePropertyNotification: surface %08x "
1301                                    "shell_surface resource not found", usurf->surfaceid);
1302                     }
1303                 }
1304             }
1305         }
1306         if (newmask & IVI_NOTIFICATION_VISIBILITY)  {
1307             if ((usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_NONE) &&
1308                 (win_mgr_hook_animation != NULL))   {
1309                 /* start animation, save original position of surface   */
1310                 usurf->animation.pos_x = usurf->x;
1311                 usurf->animation.pos_y = usurf->y;
1312                 usurf->animation.pos_width = usurf->width;
1313                 usurf->animation.pos_height = usurf->height;
1314                 ev = weston_layout_get_weston_view(ivisurf);
1315                 if (ev) {
1316                     usurf->animation.alpha = ev->alpha;
1317                 }
1318                 else    {
1319                     usurf->animation.alpha = 1.0;
1320                 }
1321             }
1322             if ((usurf->visible == 0) && (prop->visibility)) {
1323                 uifw_trace("ico_ivi_surfacePropertyNotification: %08x Visible 0=>1",
1324                            id_surface);
1325                 usurf->visible = 1;
1326                 if ((usurf->animation.show_anima != ICO_WINDOW_MGR_ANIMATION_NONE) &&
1327                     (win_mgr_hook_animation != NULL))   {
1328                     /* show with animation      */
1329                     retanima =
1330                         (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_OPSHOW,
1331                                                   (void *)usurf);
1332                     uifw_trace("ico_ivi_surfacePropertyNotification: ret call anima = %d",
1333                                retanima);
1334                 }
1335             }
1336             else if ((usurf->visible != 0) && (! prop->visibility))  {
1337                 uifw_trace("ico_ivi_surfacePropertyNotification: %08x Visible 1=>0",
1338                            id_surface);
1339                 usurf->visible = 0;
1340                 if ((usurf->animation.show_anima != ICO_WINDOW_MGR_ANIMATION_NONE) &&
1341                     (win_mgr_hook_animation != NULL))   {
1342                     /* hide with animation      */
1343                     retanima =
1344                         (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_OPHIDE,
1345                                                   (void *)usurf);
1346                 }
1347                 else    {
1348                     retanima = ICO_WINDOW_MGR_ANIMATION_RET_ANIMA;
1349                 }
1350                 if (retanima != ICO_WINDOW_MGR_ANIMATION_RET_ANIMANOCTL)    {
1351                     usurf->visible = 0;
1352                     uifw_trace("ico_ivi_surfacePropertyNotification: Change to UnVisible");
1353                 }
1354                 else    {
1355                     usurf->visible = 1;
1356                     uifw_trace("ico_ivi_surfacePropertyNotification: Change to Visible");
1357                     weston_layout_surfaceSetVisibility(ivisurf, 1);
1358                     weston_layout_commitChanges();
1359                 }
1360             }
1361             else    {
1362                 uifw_trace("ico_ivi_surfacePropertyNotification: visible no change");
1363                 newmask &= (~IVI_NOTIFICATION_VISIBILITY);
1364             }
1365         }
1366
1367         if (newmask)    {
1368             /* surface changed, send event to controller    */
1369             wl_list_for_each (mgr, &_ico_win_mgr->manager_list, link)   {
1370                 uifw_trace("win_mgr_send_event: Send UPDATE_SURFACE(surf=%08x) "
1371                            "v=%d src=%d/%d dest=%d/%d(%d/%d)", id_surface,
1372                            usurf->visible, usurf->client_width, usurf->client_height,
1373                            usurf->x, usurf->y, usurf->width, usurf->height);
1374                 ico_window_mgr_send_update_surface(mgr->resource, id_surface,
1375                                 usurf->visible, usurf->client_width,
1376                                 usurf->client_height, usurf->x, usurf->y,
1377                                 usurf->width, usurf->height);
1378             }
1379         }
1380     }
1381 }
1382
1383 /*--------------------------------------------------------------------------*/
1384 /**
1385  * @brief   win_mgr_register_surface: create UIFW surface
1386  *
1387  * @param[in]   id_surface      surface id (by ivi-shell)
1388  * @param[in]   surface         Weston surface
1389  * @param[in]   client          Wayland client
1390  * @param[in]   ivisurf         weston layout surface
1391  * @return      none
1392  */
1393 /*--------------------------------------------------------------------------*/
1394 static void
1395 win_mgr_register_surface(uint32_t id_surface, struct weston_surface *surface,
1396                          struct wl_client *client, struct weston_layout_surface *ivisurf)
1397 {
1398     struct weston_layout_SurfaceProperties  prop;
1399     struct uifw_win_surface *usurf;
1400     struct uifw_win_surface *phash;
1401     struct uifw_win_surface *bhash;
1402     uint32_t    hash;
1403
1404     uifw_trace("win_mgr_register_surface: Enter(surf=%x[%08x],client=%08x,ivisurf=%08x)",
1405                id_surface, (int)surface, (int)client, (int)ivisurf);
1406
1407     /* check new surface                    */
1408     if (find_uifw_win_surface_by_ws(surface))   {
1409         /* surface exist, NOP               */
1410         uifw_trace("win_mgr_register_surface: Leave(Already Exist)");
1411         return;
1412     }
1413
1414     /* set default color and shader */
1415     weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
1416
1417     /* create UIFW surface management table */
1418     usurf = malloc(sizeof(struct uifw_win_surface));
1419     if (! usurf)    {
1420         uifw_error("win_mgr_register_surface: No Memory");
1421         return;
1422     }
1423
1424     memset(usurf, 0, sizeof(struct uifw_win_surface));
1425
1426     usurf->surfaceid = id_surface;
1427     usurf->surface = surface;
1428     usurf->ivisurf = ivisurf;
1429     usurf->node_tbl = &_ico_node_table[0];  /* set default node table (display no=0)    */
1430
1431     if (weston_layout_getPropertiesOfSurface(ivisurf, &prop) == 0)  {
1432         usurf->x = prop.destX;
1433         usurf->y = prop.destY;
1434         usurf->width = prop.destWidth;
1435         usurf->height = prop.destHeight;
1436         usurf->client_width = prop.sourceWidth;
1437         usurf->client_height = prop.sourceHeight;
1438         usurf->configure_width = usurf->client_width;
1439         usurf->configure_height = usurf->client_height;
1440     }
1441     wl_list_init(&usurf->client_link);
1442     wl_list_init(&usurf->animation.animation.link);
1443     wl_list_init(&usurf->surf_map);
1444     wl_list_init(&usurf->input_region);
1445     usurf->animation.hide_anima = ico_get_animation_name(ico_ivi_default_animation_name());
1446     usurf->animation.hide_time = ico_ivi_default_animation_time();
1447     usurf->animation.show_anima = usurf->animation.hide_anima;
1448     usurf->animation.show_time = usurf->animation.hide_time;
1449     usurf->animation.move_anima = usurf->animation.hide_anima;
1450     usurf->animation.move_time = usurf->animation.hide_time;
1451     usurf->animation.resize_anima = usurf->animation.hide_anima;
1452     usurf->animation.resize_time = usurf->animation.hide_time;
1453     usurf->visible = 0;
1454
1455     /* set client                           */
1456     usurf->uclient = ico_window_mgr_find_uclient(client);
1457     if (! usurf->uclient)  {
1458         /* client not exist, create client management table */
1459         uifw_trace("win_mgr_register_surface: Create Client");
1460         win_mgr_bind_client(client, NULL);
1461         usurf->uclient = ico_window_mgr_find_uclient(client);
1462         if (! usurf->uclient)  {
1463             uifw_error("win_mgr_register_surface: No Memory");
1464             return;
1465         }
1466     }
1467     wl_list_insert(usurf->uclient->surface_link.prev, &usurf->client_link);
1468
1469     /* make surface id hash table       */
1470     hash = MAKE_IDHASH(usurf->surfaceid);
1471     phash = _ico_win_mgr->idhash[hash];
1472     bhash = NULL;
1473     while (phash)   {
1474         bhash = phash;
1475         phash = phash->next_idhash;
1476     }
1477     if (bhash)  {
1478         bhash->next_idhash = usurf;
1479     }
1480     else    {
1481         _ico_win_mgr->idhash[hash] = usurf;
1482     }
1483
1484     /* make weston surface hash table   */
1485     hash = MAKE_WSHASH(usurf->surface);
1486     phash = _ico_win_mgr->wshash[hash];
1487     bhash = NULL;
1488     while (phash)   {
1489         bhash = phash;
1490         phash = phash->next_wshash;
1491     }
1492     if (bhash)  {
1493         bhash->next_wshash = usurf;
1494     }
1495     else    {
1496         _ico_win_mgr->wshash[hash] = usurf;
1497     }
1498     uifw_trace("win_mgr_register_surface: Leave(surfaceId=%08x)", usurf->surfaceid);
1499 }
1500
1501 /*--------------------------------------------------------------------------*/
1502 /**
1503  * @brief   uifw_set_animation: set animation of surface visible/unvisible
1504  *
1505  * @param[in]   client      Weyland client
1506  * @param[in]   resource    resource of request
1507  * @param[in]   surfaceid   UIFW surface id
1508  * @param[in]   type        how to change surface
1509  * @param[in]   anmation    animation name
1510  * @param[in]   time        animation time(ms), if 0, default time
1511  * @return      none
1512  */
1513 /*--------------------------------------------------------------------------*/
1514 static void
1515 uifw_set_animation(struct wl_client *client, struct wl_resource *resource,
1516                    uint32_t surfaceid, int32_t type, const char *animation, int32_t time)
1517 {
1518     int     animaid;
1519     struct uifw_win_surface *usurf = ico_window_mgr_get_usurf_client(surfaceid, client);
1520
1521     uifw_trace("uifw_set_animation: surf=%08x,type=%x,anim=%s,time=%d",
1522                surfaceid, type, animation, time);
1523
1524     if (usurf) {
1525         if ((*animation != 0) && (*animation != ' '))   {
1526             animaid = ico_get_animation_name(animation);
1527             uifw_trace("uifw_set_animation: Leave(OK) type=%d", animaid);
1528             if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_HIDE)  {
1529                 if ((usurf->animation.type == ICO_WINDOW_MGR_ANIMATION_OPHIDE) ||
1530                     (usurf->animation.type == ICO_WINDOW_MGR_ANIMATION_OPHIDEPOS))  {
1531                     usurf->animation.next_anima = animaid;
1532                 }
1533                 else    {
1534                     usurf->animation.hide_anima = animaid;
1535                 }
1536             }
1537             if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_SHOW)  {
1538                 if ((usurf->animation.type == ICO_WINDOW_MGR_ANIMATION_OPSHOW) ||
1539                     (usurf->animation.type == ICO_WINDOW_MGR_ANIMATION_OPSHOWPOS))  {
1540                     usurf->animation.next_anima = animaid;
1541                 }
1542                 else    {
1543                     usurf->animation.show_anima = animaid;
1544                 }
1545             }
1546             if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_MOVE)  {
1547                 if (usurf->animation.type == ICO_WINDOW_MGR_ANIMATION_OPMOVE)    {
1548                     usurf->animation.next_anima = animaid;
1549                 }
1550                 else    {
1551                     usurf->animation.move_anima = animaid;
1552                 }
1553             }
1554             if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_RESIZE)    {
1555                 if (usurf->animation.type == ICO_WINDOW_MGR_ANIMATION_OPRESIZE)  {
1556                     usurf->animation.next_anima = animaid;
1557                 }
1558                 else    {
1559                     usurf->animation.resize_anima = animaid;
1560                 }
1561             }
1562         }
1563         if ((time > 0) && (time < 10000))   {
1564             if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_HIDE)  {
1565                 usurf->animation.hide_time = time;
1566             }
1567             if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_SHOW)  {
1568                 usurf->animation.show_time = time;
1569             }
1570             if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_MOVE)  {
1571                 usurf->animation.move_time = time;
1572             }
1573             if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_RESIZE)    {
1574                 usurf->animation.resize_time = time;
1575             }
1576         }
1577     }
1578     else    {
1579         uifw_trace("uifw_set_animation: Surface(%08x) Not exist", surfaceid);
1580     }
1581 }
1582
1583 /*--------------------------------------------------------------------------*/
1584 /**
1585  * @brief   win_mgr_check_mapsurface: check and change all surface
1586  *
1587  * @param[in]   animation   weston animation table(unused)
1588  * @param[in]   outout      weston output table(unused)
1589  * @param[in]   mseces      current time(unused)
1590  * @return      none
1591  */
1592 /*--------------------------------------------------------------------------*/
1593 static void
1594 win_mgr_check_mapsurface(struct weston_animation *animation,
1595                          struct weston_output *output, uint32_t msecs)
1596 {
1597     struct uifw_surface_map *sm, *sm_tmp;
1598     uint32_t    curtime;
1599     int         wait = 99999999;
1600
1601     /* check touch down counter     */
1602     if ((touch_check_seat) &&
1603         (touch_check_seat->touch))  {
1604         if (touch_check_seat->touch->num_tp > 10)  {
1605             uifw_trace("win_mgr_check_mapsurface: illegal touch counter(num=%d), reset",
1606                        (int)touch_check_seat->touch->num_tp);
1607             touch_check_seat->touch->num_tp = 0;
1608         }
1609     }
1610
1611     /* check all mapped surfaces    */
1612     curtime = weston_compositor_get_time();
1613     wl_list_for_each_safe (sm, sm_tmp, &_ico_win_mgr->map_list, map_link)   {
1614 #if 0   /* too many log */
1615         uifw_detail("win_mgr_check_mapsurface: sm=%08x surf=%08x",
1616                     (int)sm, sm->usurf->surfaceid);
1617 #endif
1618         win_mgr_change_mapsurface(sm, 0, curtime);
1619         if (sm->eventque)   {
1620             if (sm->interval < wait)    {
1621                 wait = sm->interval;
1622             }
1623         }
1624     }
1625
1626     /* check frame interval         */
1627     if (wait < 2000)    {
1628         wait = wait / 2;
1629     }
1630     else    {
1631         wait = 1000;
1632     }
1633     wl_event_source_timer_update(_ico_win_mgr->wait_mapevent, wait);
1634 }
1635
1636 /*--------------------------------------------------------------------------*/
1637 /**
1638  * @brief   win_mgr_timer_mapsurface: mapped surface check timer
1639  *
1640  * @param[in]   data        user data(unused)
1641  * @return      fixed 1
1642  */
1643 /*--------------------------------------------------------------------------*/
1644 static int
1645 win_mgr_timer_mapsurface(void *data)
1646 {
1647     win_mgr_check_mapsurface(NULL, NULL, 0);
1648     return 1;
1649 }
1650
1651 /*--------------------------------------------------------------------------*/
1652 /**
1653  * @brief   win_mgr_change_mapsurface: check and change mapped surface
1654  *
1655  * @param[in]   sm          map surface table
1656  * @param[in]   event       send event (if 0, send if changed)
1657  * @param[in]   curtime     current time(ms)
1658  * @return      none
1659  */
1660 /*--------------------------------------------------------------------------*/
1661 static void
1662 win_mgr_change_mapsurface(struct uifw_surface_map *sm, int event, uint32_t curtime)
1663 {
1664     struct weston_surface   *es;
1665     struct wl_shm_buffer    *shm_buffer;
1666     int         width;
1667     int         height;
1668     uint32_t    format;
1669     uint32_t    dtime;
1670
1671 #if 0   /* too many log */
1672     uifw_detail("win_mgr_change_mapsurface: surf=%08x event=%d", sm->usurf->surfaceid, event);
1673 #endif
1674     if (event == 0) {
1675         event = ICO_WINDOW_MGR_MAP_SURFACE_EVENT_CONTENTS;
1676     }
1677
1678     /* check if buffered        */
1679     es = sm->usurf->surface;
1680     if ((es == NULL) ||
1681         ((sm->type == ICO_WINDOW_MGR_MAP_TYPE_EGL) &&
1682          ((es->buffer_ref.buffer == NULL) ||
1683           (es->buffer_ref.buffer->width <= 0) || (es->buffer_ref.buffer->height <= 0)))) {
1684         /* surface has no buffer    */
1685         uifw_debug("win_mgr_change_mapsurface: surface(%08x) has no buffer %08x %08x",
1686                    sm->usurf->surfaceid, (int)es,
1687                    es ? (int)es->buffer_ref.buffer : 0);
1688         if (sm->initflag)   {
1689             event = ICO_WINDOW_MGR_MAP_SURFACE_EVENT_UNMAP;
1690         }
1691         else    {
1692             event = 0;
1693         }
1694     }
1695     else if (sm->type == ICO_WINDOW_MGR_MAP_TYPE_EGL)   {
1696         if ((es->buffer_ref.buffer->legacy_buffer != NULL) && (es->renderer_state != NULL)) {
1697             if ((void *)wl_resource_get_user_data(
1698                             (struct wl_resource *)es->buffer_ref.buffer->legacy_buffer)
1699                 == NULL)    {
1700                 /* surface has no buffer    */
1701                 uifw_debug("win_mgr_change_mapsurface: surface(%08x) has no buffer",
1702                            sm->usurf->surfaceid);
1703                 if (sm->initflag)   {
1704                     event = ICO_WINDOW_MGR_MAP_SURFACE_EVENT_UNMAP;
1705                 }
1706                 else    {
1707                     event = 0;
1708                 }
1709             }
1710         }
1711     }
1712     else    {
1713         if (es->buffer_ref.buffer != NULL)  {
1714             shm_buffer = wl_shm_buffer_get(es->buffer_ref.buffer->resource);
1715             if (shm_buffer) {
1716                 format = wl_shm_buffer_get_format(shm_buffer);
1717                 if (format != WL_SHM_FORMAT_ARGB8888)   {
1718                     uifw_trace("win_mgr_change_mapsurface: %08x shm_buffer type %x",
1719                                sm->usurf->surfaceid, format);
1720                     event = ICO_WINDOW_MGR_MAP_SURFACE_EVENT_UNMAP;
1721                 }
1722             }
1723         }
1724     }
1725
1726     if ((event != 0) && (event != ICO_WINDOW_MGR_MAP_SURFACE_EVENT_UNMAP))  {
1727
1728         if (sm->type == ICO_WINDOW_MGR_MAP_TYPE_EGL)    {
1729             format = EGL_TEXTURE_RGBA;          /* currently only support RGBA  */
1730             width = es->buffer_ref.buffer->width;
1731             height = es->buffer_ref.buffer->height;
1732             if ((sm->initflag == 0) && (width > 0) && (height > 0)) {
1733                 sm->initflag = 1;
1734                 event = ICO_WINDOW_MGR_MAP_SURFACE_EVENT_MAP;
1735 #if  PERFORMANCE_EVALUATIONS > 0
1736                 uifw_perf("SWAP_BUFFER appid=%s surface=%08x MAP",
1737                           sm->usurf->uclient->appid, sm->usurf->surfaceid);
1738 #endif /*PERFORMANCE_EVALUATIONS*/
1739             }
1740             else if ((width <= 0) || (height <= 0)) {
1741                 event = 0;
1742             }
1743             else if (event == ICO_WINDOW_MGR_MAP_SURFACE_EVENT_CONTENTS)    {
1744                 if ((sm->width != width) || (sm->height != height) ||
1745                     (format != sm->format)) {
1746                     event = ICO_WINDOW_MGR_MAP_SURFACE_EVENT_RESIZE;
1747 #if  PERFORMANCE_EVALUATIONS > 0
1748                     uifw_perf("SWAP_BUFFER appid=%s surface=%08x RESIZE",
1749                               sm->usurf->uclient->appid, sm->usurf->surfaceid);
1750 #endif /*PERFORMANCE_EVALUATIONS*/
1751                 }
1752                 else    {
1753                     if (es->buffer_ref.buffer->legacy_buffer != sm->curbuf) {
1754 #if  PERFORMANCE_EVALUATIONS > 0
1755                         uifw_perf("SWAP_BUFFER appid=%s surface=%08x CONTENTS",
1756                                   sm->usurf->uclient->appid, sm->usurf->surfaceid);
1757 #endif /*PERFORMANCE_EVALUATIONS*/
1758                         dtime = curtime - sm->lasttime;
1759                         if ((sm->interval > 0) && (dtime < sm->interval))   {
1760                             sm->eventque = 1;
1761                             event = 0;
1762                         }
1763                     }
1764                     else if (sm->eventque)  {
1765                         dtime = curtime - sm->lasttime;
1766                         if ((sm->interval > 0) && (dtime < sm->interval))   {
1767                             event = 0;
1768                         }
1769                     }
1770                     else    {
1771                         event =0;
1772                     }
1773                 }
1774             }
1775             sm->width = width;
1776             sm->height = height;
1777             sm->stride = width * 4;
1778             sm->format = format;
1779             sm->curbuf = es->buffer_ref.buffer->legacy_buffer;
1780         }
1781         else    {
1782             if ((sm->eventque != 0) ||
1783                 (es->buffer_ref.buffer == NULL) || (es->buffer_ref.buffer != sm->curbuf)) {
1784                 sm->curbuf = es->buffer_ref.buffer;
1785                 if (es->buffer_ref.buffer != NULL)  {
1786                     width = es->buffer_ref.buffer->width;
1787                     height = es->buffer_ref.buffer->height;
1788                 }
1789                 else    {
1790                     width = es->width;
1791                     height = es->height;
1792                 }
1793                 if ((sm->initflag == 0) && (width > 0) && (height > 0))    {
1794                     sm->initflag = 1;
1795                     event = ICO_WINDOW_MGR_MAP_SURFACE_EVENT_MAP;
1796                     uifw_detail("win_mgr_change_mapsurface: PIX MAP event %08x",
1797                                 sm->usurf->surfaceid);
1798                 }
1799                 else    {
1800                     if ((width <= 0) || (height <= 0))  {
1801                         event = 0;
1802                         sm->curbuf = NULL;
1803                         uifw_detail("win_mgr_change_mapsurface: PIX %08x w/h=0/0",
1804                                     sm->usurf->surfaceid);
1805                     }
1806                     else if (event == ICO_WINDOW_MGR_MAP_SURFACE_EVENT_CONTENTS)    {
1807 #if  PERFORMANCE_EVALUATIONS > 0
1808                         if (sm->type != ICO_WINDOW_MGR_MAP_TYPE_SHM)    {
1809                             uifw_perf("SWAP_BUFFER appid=%s surface=%08x CONTENTS",
1810                                       sm->usurf->uclient->appid, sm->usurf->surfaceid);
1811                         }
1812 #endif /*PERFORMANCE_EVALUATIONS*/
1813                         if ((sm->width != width) || (sm->height != height)) {
1814                             event = ICO_WINDOW_MGR_MAP_SURFACE_EVENT_RESIZE;
1815                         }
1816                         else    {
1817                             dtime = curtime - sm->lasttime;
1818                             if ((sm->interval > 0) && (dtime < sm->interval))   {
1819                                 sm->eventque = 1;
1820                                 event = 0;
1821                                 uifw_detail("win_mgr_change_mapsurface: PIX %08x new queue",
1822                                             sm->usurf->surfaceid);
1823                             }
1824                             else if (sm->eventque)  {
1825                                 dtime = curtime - sm->lasttime;
1826                                 if ((sm->interval > 0) && (dtime < sm->interval))   {
1827                                     event = 0;
1828                                     uifw_detail("win_mgr_change_mapsurface: PIX %08x queued",
1829                                                 sm->usurf->surfaceid);
1830                                 }
1831                             }
1832                         }
1833                     }
1834                 }
1835                 sm->width = width;
1836                 sm->height = height;
1837                 sm->stride = width * 4;
1838                 sm->format = EGL_TEXTURE_RGBA;
1839             }
1840             else    {
1841                 event = 0;
1842             }
1843         }
1844     }
1845
1846     if (event != 0) {
1847         uifw_detail("win_mgr_change_mapsurface: send MAP event(ev=%d surf=%08x type=%d "
1848                     "w/h/s=%d/%d/%d format=%x file=<%s>",
1849                     event, sm->usurf->surfaceid, sm->type,
1850                     sm->width, sm->height, sm->stride, sm->format, sm->filepath);
1851         sm->lasttime = curtime;
1852         sm->eventque = 0;
1853         if ((event != ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR) &&
1854             (event != ICO_WINDOW_MGR_MAP_SURFACE_EVENT_UNMAP) &&
1855             (sm->filepath[0] != 0)) {
1856 #if 1       /* weston_layout_takeSurfaceScreenshot(GENIVI) is slowly    */
1857             if (win_mgr_takeSurfaceScreenshot(sm->filepath, sm->usurf,
1858                                               sm->width, sm->height) != 0)
1859 #else       /* weston_layout_takeSurfaceScreenshot(GENIVI) is slowly    */
1860             if (weston_layout_takeSurfaceScreenshot(sm->filepath,
1861                                                     sm->usurf->ivisurf) != 0)
1862 #endif      /* weston_layout_takeSurfaceScreenshot(GENIVI) is slowly    */
1863             {
1864                 uifw_warn("win_mgr_change_mapsurface: surface.%08x image read(%s) Error",
1865                           sm->usurf->surfaceid, sm->filepath);
1866                 event = ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR;
1867             }
1868             else    {
1869                 uifw_warn("win_mgr_change_mapsurface: surface.%08x image read(%s) OK",
1870                           sm->usurf->surfaceid, sm->filepath);
1871             }
1872         }
1873         ico_window_mgr_send_map_surface(sm->uclient->mgr->resource, event,
1874                                         sm->usurf->surfaceid, sm->type,
1875                                         sm->width, sm->height, sm->stride, sm->format);
1876         if (event == ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR)    {
1877             /* free map table if error  */
1878             wl_list_remove(&sm->surf_link);
1879             wl_list_remove(&sm->map_link);
1880             sm->usurf = (struct uifw_win_surface *)_ico_win_mgr->free_maptable;
1881             _ico_win_mgr->free_maptable = sm;
1882         }
1883     }
1884 }
1885
1886 /*--------------------------------------------------------------------------*/
1887 /**
1888  * @brief   uifw_map_surface: mapped surface buffer to system application
1889  *
1890  * @param[in]   client      Weyland client
1891  * @param[in]   resource    resource of request
1892  * @param[in]   surfaceid   surface id
1893  * @param[in]   framerate   frame rate of surface update(frame/sec)
1894  * @param[in]   filepath    surface image file path(if NULL, not create file)
1895  * @return      none
1896  */
1897 /*--------------------------------------------------------------------------*/
1898 static void
1899 uifw_map_surface(struct wl_client *client, struct wl_resource *resource,
1900                  uint32_t surfaceid, int32_t framerate, const char *filepath)
1901 {
1902     struct uifw_win_surface     *usurf;
1903     struct weston_surface       *es;
1904     struct uifw_surface_map     *sm;
1905     struct weston_buffer        *buffer;
1906     struct wl_shm_buffer        *shm_buffer;
1907     struct uifw_client          *uclient;
1908     struct uifw_gl_surface_state *gl_state;
1909     int     maptype;
1910     int     format;
1911
1912     uifw_trace("uifw_map_surface: Enter(surface=%08x,fps=%d,file=%s)",
1913                surfaceid, framerate, filepath ? filepath : "(null)");
1914
1915     uclient = ico_window_mgr_find_uclient(client);
1916     usurf = ico_window_mgr_get_usurf(surfaceid);
1917     if (! usurf)    {
1918         /* surface dose not exist, error        */
1919         ico_window_mgr_send_map_surface(resource, ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR,
1920                                         surfaceid, 1, 0, 0, 0, 0);
1921         uifw_trace("uifw_map_surface: Leave(surface=%08x dose not exist)", surfaceid);
1922         return;
1923     }
1924
1925     /* check if buffered        */
1926     es = usurf->surface;
1927     if (es == NULL) {
1928         /* surface has no buffer, error         */
1929         ico_window_mgr_send_map_surface(resource, ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR,
1930                                         surfaceid, 2, 0, 0, 0, 0);
1931         uifw_trace("uifw_map_surface: Leave(surface(%08x) has no surface)", surfaceid);
1932         return;
1933     }
1934     buffer = es->buffer_ref.buffer;
1935
1936     /* check buffer type        */
1937     gl_state = (struct uifw_gl_surface_state *)es->renderer_state;
1938     if (gl_state == NULL)   {
1939         ico_window_mgr_send_map_surface(resource,
1940                                         ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR,
1941                                         surfaceid, 3, 0, 0, 0, 0);
1942         uifw_trace("uifw_map_surface: Leave(surface(%08x) has no gl_state)", surfaceid);
1943         return;
1944     }
1945     else if (gl_state->buffer_type == BUFFER_TYPE_SHM)  {
1946         maptype = -1;
1947         format = 0xff;
1948         if (ico_ivi_optionflag() & ICO_IVI_OPTION_SUPPORT_SHM)  {
1949             if (buffer != NULL) {
1950                 shm_buffer = wl_shm_buffer_get(buffer->resource);
1951                 if (shm_buffer) {
1952                     format = wl_shm_buffer_get_format(shm_buffer);
1953                     uifw_detail("uifw_map_surface: %08x shm_buffer type %x",
1954                                 surfaceid, format);
1955                     if (format == WL_SHM_FORMAT_ARGB8888)   {
1956                         maptype = ICO_WINDOW_MGR_MAP_TYPE_SHM;
1957                     }
1958                 }
1959             }
1960             else    {
1961                 maptype = ICO_WINDOW_MGR_MAP_TYPE_SHM;
1962             }
1963         }
1964         if (maptype < 0)    {
1965             ico_window_mgr_send_map_surface(resource,
1966                                             ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR,
1967                                             surfaceid, 4, 0, 0, 0, 0);
1968             uifw_trace("uifw_map_surface: Leave(surface(%08x) not support shm_buffer(%x))",
1969                        surfaceid, format);
1970             return;
1971         }
1972     }
1973     else    {
1974         maptype = ICO_WINDOW_MGR_MAP_TYPE_EGL;
1975     }
1976
1977     /* maximum framerate        */
1978     if (maptype == ICO_WINDOW_MGR_MAP_TYPE_EGL) {
1979         if ((framerate <= 0) || (framerate > 15))
1980             framerate = 15;
1981     }
1982     else    {
1983         if ((framerate <= 0) || (framerate > 5))
1984             framerate = 5;
1985     }
1986
1987     /* check same surface       */
1988     wl_list_for_each(sm, &usurf->surf_map, surf_link) {
1989         if ((sm->usurf == usurf) && (sm->uclient == uclient))   {
1990             break;
1991         }
1992     }
1993
1994     if (&sm->surf_link == &usurf->surf_map) {
1995         /* create map table         */
1996         sm = _ico_win_mgr->free_maptable;
1997         if (sm) {
1998             _ico_win_mgr->free_maptable = (struct uifw_surface_map *)sm->usurf;
1999         }
2000         else    {
2001             sm = (struct uifw_surface_map *)malloc(sizeof(struct uifw_surface_map));
2002             if (! sm)   {
2003                 ico_window_mgr_send_map_surface(resource,
2004                                                 ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR,
2005                                                 surfaceid, 5, 0, 0, 0, 0);
2006                 uifw_trace("uifw_map_surface: Leave(malloc error)");
2007                 return;
2008             }
2009         }
2010         memset(sm, 0, sizeof(struct uifw_surface_map));
2011
2012         wl_list_init(&sm->map_link);
2013         wl_list_init(&sm->surf_link);
2014         sm->usurf = usurf;
2015         sm->uclient = uclient;
2016         sm->type = maptype;
2017         sm->framerate = framerate;
2018         sm->interval = (1000 / sm->framerate) - 1;
2019         wl_list_insert(_ico_win_mgr->map_list.next, &sm->map_link);
2020         wl_list_insert(usurf->surf_map.prev, &sm->surf_link);
2021     }
2022     else    {
2023         /* change frame rate    */
2024         uifw_trace("uifw_map_surface: Leave(chagne frame rate %d->%d",
2025                    sm->framerate, framerate);
2026         if (sm->framerate != framerate) {
2027             sm->framerate = framerate;
2028             sm->interval = (1000 / sm->framerate) - 1;
2029             win_mgr_change_mapsurface(sm, 0, weston_compositor_get_time());
2030         }
2031         return;
2032     }
2033
2034     memset(sm->filepath, 0, ICO_IVI_FILEPATH_LENGTH);
2035     if ((filepath != NULL) && (*filepath != 0) && (*filepath != ' '))   {
2036         strncpy(sm->filepath, filepath, ICO_IVI_FILEPATH_LENGTH-1);
2037     }
2038
2039     if (buffer != NULL) {
2040         sm->width = buffer->width;
2041         sm->height = buffer->height;
2042         if (maptype != ICO_WINDOW_MGR_MAP_TYPE_EGL) {
2043             sm->stride = sm->width * 4;
2044             sm->format = EGL_TEXTURE_RGBA;
2045             if ((sm->width > 0) && (sm->height > 0))    {
2046                 sm->initflag = 1;
2047             }
2048             uifw_debug("uifw_map_surface: map type=%d,surface=%08x,fps=%d,w/h=%d/%d",
2049                        maptype, surfaceid, framerate, buffer->width, buffer->height);
2050         }
2051         else    {
2052             if (wl_resource_get_user_data((struct wl_resource *)buffer->legacy_buffer)
2053                 != NULL)    {
2054                 sm->format = EGL_TEXTURE_RGBA;
2055                 if ((sm->width > 0) && (sm->height > 0) && (sm->stride > 0) &&
2056                     (gl_state != NULL))  {
2057                     sm->initflag = 1;
2058                 }
2059                 uifw_debug("uifw_map_surface: map EGL surface=%08x,fps=%d,w/h=%d/%d",
2060                            surfaceid, framerate, buffer->width, buffer->height);
2061             }
2062             else    {
2063                 uifw_debug("uifw_map_surface: map EGL but no buffer surface=%08x,fps=%d",
2064                            surfaceid, framerate);
2065             }
2066         }
2067     }
2068     else if (maptype != ICO_WINDOW_MGR_MAP_TYPE_EGL)    {
2069         sm->width = es->width;
2070         sm->height = es->height;
2071         sm->stride = sm->width * 4;
2072         sm->format = EGL_TEXTURE_RGBA;
2073         if ((sm->width > 0) && (sm->height > 0))    {
2074             sm->initflag = 1;
2075         }
2076         uifw_debug("uifw_map_surface: map type=%d,surface=%08x,fps=%d,w/h=%d/%d",
2077                    maptype, surfaceid, framerate, sm->width, sm->height);
2078     }
2079     else    {
2080         uifw_debug("uifw_map_surface: map EGL but no buffer surface=%08x,fps=%d",
2081                    surfaceid, framerate);
2082     }
2083
2084     /* send map event                       */
2085     if (sm->initflag)   {
2086         win_mgr_change_mapsurface(sm, ICO_WINDOW_MGR_MAP_SURFACE_EVENT_MAP,
2087                                   weston_compositor_get_time());
2088     }
2089     uifw_trace("uifw_map_surface: Leave");
2090 }
2091
2092 /*--------------------------------------------------------------------------*/
2093 /**
2094  * @brief   uifw_unmap_surface: unmap surface buffer
2095  *
2096  * @param[in]   client      Weyland client
2097  * @param[in]   resource    resource of request
2098  * @param[in]   surfaceid   surface id
2099  * @return      none
2100  */
2101 /*--------------------------------------------------------------------------*/
2102 static void
2103 uifw_unmap_surface(struct wl_client *client, struct wl_resource *resource,
2104                    uint32_t surfaceid)
2105 {
2106     struct uifw_win_surface *usurf;
2107     struct uifw_surface_map *sm, *sm_tmp;
2108     struct uifw_client      *uclient;
2109
2110     uifw_trace("uifw_unmap_surface: Enter(surface=%08x)", surfaceid);
2111
2112     usurf = ico_window_mgr_get_usurf(surfaceid);
2113     if (! usurf)    {
2114         /* surface dose not exist, error        */
2115         uifw_trace("uifw_unmap_surface: Leave(surface=%08x dose not exist)", surfaceid);
2116         return;
2117     }
2118     if (client) {
2119         uclient = ico_window_mgr_find_uclient(client);
2120         if ((! uclient) || (! uclient->mgr))    {
2121             /* client dose not exist, error         */
2122             uifw_trace("uifw_unmap_surface: Leave(client=%08x dose not exist)", (int)client);
2123             return;
2124         }
2125     }
2126     else    {
2127         uclient = NULL;
2128         wl_list_for_each (sm, &usurf->surf_map, surf_link) {
2129             if (sm->uclient->mgr != NULL) {
2130                 uifw_trace("uifw_unmap_surface: send UNMAP event(ev=%d surf=%08x "
2131                            "w/h/s=%d/%d/%d format=%x",
2132                            ICO_WINDOW_MGR_MAP_SURFACE_EVENT_UNMAP, surfaceid,
2133                            sm->width, sm->height, sm->stride, sm->format);
2134                 ico_window_mgr_send_map_surface(sm->uclient->mgr->resource,
2135                                                 ICO_WINDOW_MGR_MAP_SURFACE_EVENT_UNMAP,
2136                                                 surfaceid, sm->type, sm->width,
2137                                                 sm->height, sm->stride, sm->format);
2138             }
2139         }
2140     }
2141     wl_list_for_each_safe (sm, sm_tmp, &usurf->surf_map, surf_link) {
2142         if (((uclient != NULL) && (sm->uclient != uclient)))   continue;
2143         wl_list_remove(&sm->surf_link);
2144         wl_list_remove(&sm->map_link);
2145         if (sm->filepath[0])    {
2146             unlink(sm->filepath);
2147         }
2148         sm->usurf = (struct uifw_win_surface *)_ico_win_mgr->free_maptable;
2149         _ico_win_mgr->free_maptable = sm;
2150     }
2151     uifw_trace("uifw_unmap_surface: Leave");
2152 }
2153
2154 /*--------------------------------------------------------------------------*/
2155 /**
2156  * @brief   win_mgr_destroy_surface: surface destroy
2157  *
2158  * @param[in]   surface     Weston surface
2159  * @return      none
2160  */
2161 /*--------------------------------------------------------------------------*/
2162 static void
2163 win_mgr_destroy_surface(struct weston_surface *surface)
2164 {
2165     struct uifw_win_surface *usurf;
2166     struct uifw_win_surface *phash;
2167     struct uifw_win_surface *bhash;
2168     uint32_t    hash;
2169
2170     usurf = find_uifw_win_surface_by_ws(surface);
2171     if (! usurf) {
2172         uifw_trace("win_mgr_destroy_surface: UIFW surface Not Exist");
2173         return;
2174     }
2175     uifw_trace("win_mgr_destroy_surface: Enter(%08x) %08x", (int)surface, usurf->surfaceid);
2176
2177     /* destory input region         */
2178     if (win_mgr_hook_destory)   {
2179         (*win_mgr_hook_destory)(usurf);
2180     }
2181
2182     /* unmap surface                */
2183     if (&usurf->surf_map != usurf->surf_map.next)   {
2184         uifw_unmap_surface(NULL, NULL, usurf->surfaceid);
2185     }
2186
2187     /* destroy animation extenson   */
2188     if (win_mgr_hook_animation) {
2189         (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_DESTROY, (void *)usurf);
2190     }
2191
2192     /* send destroy event to controller */
2193     win_mgr_send_event(ICO_WINDOW_MGR_DESTROY_SURFACE, usurf->surfaceid, 0);
2194
2195     /* delete from cleint list      */
2196     wl_list_remove(&usurf->client_link);
2197
2198     /* delete from hash table       */
2199     hash = MAKE_IDHASH(usurf->surfaceid);
2200     phash = _ico_win_mgr->idhash[hash];
2201     bhash = NULL;
2202     while ((phash) && (phash != usurf)) {
2203         bhash = phash;
2204         phash = phash->next_idhash;
2205     }
2206     if (bhash)  {
2207         bhash->next_idhash = usurf->next_idhash;
2208     }
2209     else    {
2210         _ico_win_mgr->idhash[hash] = usurf->next_idhash;
2211     }
2212
2213     hash = MAKE_WSHASH(usurf->surface);
2214     phash = _ico_win_mgr->wshash[hash];
2215     bhash = NULL;
2216     while ((phash) && (phash != usurf)) {
2217         bhash = phash;
2218         phash = phash->next_wshash;
2219     }
2220     if (bhash)  {
2221         bhash->next_wshash = usurf->next_wshash;
2222     }
2223     else    {
2224         _ico_win_mgr->wshash[hash] = usurf->next_wshash;
2225     }
2226
2227     free(usurf);
2228     uifw_trace("win_mgr_destroy_surface: Leave(OK)");
2229 }
2230
2231 /*--------------------------------------------------------------------------*/
2232 /**
2233  * @brief   win_mgr_takeSurfaceScreenshot: take screen image pixel
2234  *
2235  * @param[in]   filename    output file path
2236  * @param[in]   usurf       UIFW surface
2237  * @param[in]   width       surface width
2238  * @param[in]   height      surface height
2239  * @return      result
2240  * @retval      0           success
2241  * @retval      -1          error
2242  */
2243 /*--------------------------------------------------------------------------*/
2244 static int
2245 win_mgr_takeSurfaceScreenshot(const char *filename, struct uifw_win_surface *usurf,
2246                               int width, int height)
2247 {
2248     int     datasize;
2249     int     bufsize;
2250     int     bitperpixel;
2251     int     bmphead_size;
2252     int     fd;
2253     int     pathlen;
2254     int     linesize;
2255     char    *sp, *dp;
2256     char    *wkbuf = NULL;
2257 #pragma pack(push, 1)
2258     struct _bmphead {
2259         short   magic;
2260         uint32_t fullsize;
2261         short   res1;
2262         short   res2;
2263         int     offset;
2264         int     headsize;
2265         int     width;
2266         int     height;
2267         short   planes;
2268         short   bitperpixel;
2269         int     compress;
2270         int     datasize;
2271         int     xp;
2272         int     yp;
2273         int     colors;
2274         int     colors2;
2275     }       *bmphead;
2276 #pragma pack(pop)
2277
2278     uifw_trace("win_mgr_takeSurfaceScreenshot: Enter(%08x) <%s>",
2279                usurf->surfaceid, filename);
2280
2281     if (! _ico_win_mgr->compositor->renderer->read_surface_pixels)  {
2282         uifw_trace("win_mgr_takeSurfaceScreenshot: Leave(no read_surface_pixels)");
2283         return -1;
2284     }
2285     bitperpixel = PIXMAN_FORMAT_BPP(_ico_win_mgr->compositor->read_format);
2286     bmphead_size = ((sizeof(struct _bmphead) + 31) / 32) * 32;
2287     datasize = (width * bitperpixel / 8) * height;
2288     bufsize = datasize + bmphead_size;
2289     if ((_ico_win_mgr->pixel_readbuf != NULL) &&
2290         (bufsize > _ico_win_mgr->pixel_readsize))   {
2291         free(_ico_win_mgr->pixel_readbuf);
2292         _ico_win_mgr->pixel_readbuf = NULL;
2293     }
2294     if (_ico_win_mgr->pixel_readbuf == NULL)    {
2295         _ico_win_mgr->pixel_readbuf = malloc(bufsize);
2296         if (! _ico_win_mgr->pixel_readbuf)  {
2297             uifw_error("win_mgr_takeSurfaceScreenshot: Leave(can not allocate buffer)");
2298             return -1;
2299         }
2300         _ico_win_mgr->pixel_readsize = bufsize;
2301     }
2302     pathlen = strlen(filename);
2303     if ((pathlen >= 4) && (strcmp(&filename[pathlen-4], ".bmp") == 0))  {
2304         /* BMP format   */
2305         wkbuf = malloc(datasize);
2306         if (! wkbuf)    {
2307             uifw_error("win_mgr_takeSurfaceScreenshot: Leave(can not allocate buffer)");
2308             return -1;
2309         }
2310     }
2311     fd = open(filename, O_WRONLY|O_CREAT, 0644);
2312     if (fd < 0) {
2313         uifw_warn("win_mgr_takeSurfaceScreenshot: Leave(file<%s> open Error<%d>)",
2314                   filename, errno);
2315         if (wkbuf)  free(wkbuf);
2316         return -1;
2317     }
2318
2319     uifw_detail("win_mgr_takeSurfaceScreenshot: call read_surface_pixels(%d,%d)",
2320                 width, height);
2321     if ((*(_ico_win_mgr->compositor->
2322             renderer->read_surface_pixels))(usurf->surface, PIXMAN_a8r8g8b8,
2323                                             wkbuf ? wkbuf :
2324                                               (_ico_win_mgr->pixel_readbuf + bmphead_size),
2325                                             0, 0, width, height) != 0)  {
2326         close(fd);
2327         uifw_warn("win_mgr_takeSurfaceScreenshot: Leave(read_surface_pixels Error)");
2328         if (wkbuf)  free(wkbuf);
2329         return -1;
2330     }
2331     uifw_detail("win_mgr_takeSurfaceScreenshot: end  read_surface_pixels");
2332
2333     if (wkbuf)  {
2334         /* BMP format   */
2335         bmphead = (struct _bmphead *)(_ico_win_mgr->pixel_readbuf +
2336                                       (bmphead_size - sizeof(struct _bmphead)));
2337         memset(bmphead, 0, sizeof(struct _bmphead));
2338         bmphead->magic = 0x4d42;
2339         bmphead->fullsize = sizeof(struct _bmphead) + datasize;
2340         bmphead->offset = 54;
2341         bmphead->headsize = 40;
2342         bmphead->width = width;
2343         bmphead->height = height;
2344         bmphead->planes = 1;
2345         bmphead->bitperpixel = bitperpixel;
2346         bmphead->compress = 0;
2347         bmphead->datasize = datasize;
2348         bmphead->xp = 100000;
2349         bmphead->yp = 100000;
2350
2351         /* invert Y     */
2352         linesize = width * bitperpixel / 8;
2353         sp = wkbuf;
2354         dp = _ico_win_mgr->pixel_readbuf + bmphead_size + (linesize * (height-1));
2355         for (pathlen = 0; pathlen < height; pathlen++)  {
2356             memcpy(dp, sp, linesize);
2357             sp += linesize;
2358             dp -= linesize;
2359         }
2360         free(wkbuf);
2361
2362         if (write(fd, bmphead, sizeof(struct _bmphead) + datasize) < 0) {
2363             uifw_warn("win_mgr_takeSurfaceScreenshot: Leave(file<%s> write Error<%d>)",
2364                       filename, errno);
2365             close(fd);
2366             if (wkbuf)  free(wkbuf);
2367             return -1;
2368         }
2369     }
2370     else    {
2371         /* Binary format    */
2372         if (write(fd, _ico_win_mgr->pixel_readbuf + bmphead_size, datasize) < 0)    {
2373             uifw_warn("win_mgr_takeSurfaceScreenshot: Leave(file<%s> write Error<%d>)",
2374                       filename, errno);
2375             close(fd);
2376             return -1;
2377         }
2378     }
2379     close(fd);
2380
2381     uifw_trace("win_mgr_takeSurfaceScreenshot: Leave");
2382     return 0;
2383 }
2384
2385 /*--------------------------------------------------------------------------*/
2386 /**
2387  * @brief   bind_ico_win_mgr: bind Multi Window Manager from client
2388  *
2389  * @param[in]   client      client
2390  * @param[in]   data        user data(unused)
2391  * @param[in]   version     protocol version(unused)
2392  * @param[in]   id          client object id
2393  * @return      none
2394  */
2395 /*--------------------------------------------------------------------------*/
2396 static void
2397 bind_ico_win_mgr(struct wl_client *client,
2398                  void *data, uint32_t version, uint32_t id)
2399 {
2400     struct wl_resource  *add_resource;
2401     struct uifw_manager *mgr;
2402     struct uifw_client  *uclient;
2403
2404     uifw_trace("bind_ico_win_mgr: Enter(client=%08x, id=%x)", (int)client, (int)id);
2405
2406     add_resource = wl_resource_create(client, &ico_window_mgr_interface, 1, id);
2407     if (add_resource)   {
2408         wl_resource_set_implementation(add_resource, &ico_window_mgr_implementation,
2409                                        _ico_win_mgr, unbind_ico_win_mgr);
2410     }
2411
2412     /* Create client management tabel       */
2413     uclient = ico_window_mgr_find_uclient(client);
2414     if (! uclient)  {
2415         win_mgr_bind_client(client, NULL);
2416         uclient = ico_window_mgr_find_uclient(client);
2417     }
2418
2419     /* Manager                              */
2420     mgr = (struct uifw_manager *)malloc(sizeof(struct uifw_manager));
2421     if (! mgr)  {
2422         uifw_error("bind_ico_win_mgr: Error, No Memory");
2423         return;
2424     }
2425     memset(mgr, 0, sizeof(struct uifw_manager));
2426     mgr->resource = add_resource;
2427     if (uclient)    {
2428         uclient->mgr = mgr;
2429     }
2430     wl_list_insert(&_ico_win_mgr->manager_list, &mgr->link);
2431
2432     uifw_trace("bind_ico_win_mgr: Leave");
2433 }
2434
2435 /*--------------------------------------------------------------------------*/
2436 /**
2437  * @brief   unbind_ico_win_mgr: unbind Multi Window Manager from client
2438  *
2439  * @param[in]   resource    client resource
2440  * @return      none
2441  */
2442 /*--------------------------------------------------------------------------*/
2443 static void
2444 unbind_ico_win_mgr(struct wl_resource *resource)
2445 {
2446     struct uifw_manager *mgr, *itmp;
2447
2448     uifw_trace("unbind_ico_win_mgr: Enter");
2449
2450     /* Remove manager from manager list */
2451     wl_list_for_each_safe (mgr, itmp, &_ico_win_mgr->manager_list, link)    {
2452         if (mgr->resource == resource) {
2453             wl_list_remove(&mgr->link);
2454             free(mgr);
2455         }
2456     }
2457     uifw_trace("unbind_ico_win_mgr: Leave");
2458 }
2459
2460 /*--------------------------------------------------------------------------*/
2461 /**
2462  * @brief   ico_window_mgr_get_uclient: get UIFW client table
2463  *
2464  * @param[in]   appid       application Id
2465  * @return      UIFW client table
2466  * @retval      !=NULL      success(UIFW client table address)
2467  * @retval      = NULL      error(appid not exist)
2468  */
2469 /*--------------------------------------------------------------------------*/
2470 WL_EXPORT   struct uifw_client *
2471 ico_window_mgr_get_uclient(const char *appid)
2472 {
2473     struct uifw_client *uclient;
2474
2475     wl_list_for_each (uclient, &_ico_win_mgr->client_list, link)    {
2476         if (strcmp(uclient->appid, appid) == 0) {
2477             return uclient;
2478         }
2479     }
2480     return NULL;
2481 }
2482
2483 /*--------------------------------------------------------------------------*/
2484 /**
2485  * @brief   ico_window_mgr_get_client_usurf: get client UIFW surface table
2486  *
2487  * @param[in]   target      surface window name and application Id(winname@appid)
2488  * @return      UIFW surface table
2489  * @retval      !=NULL      success(UIFW surface table address)
2490  * @retval      = NULL      error(appid or winname not exist)
2491  */
2492 /*--------------------------------------------------------------------------*/
2493 WL_EXPORT   struct uifw_win_surface *
2494 ico_window_mgr_get_client_usurf(const char *target)
2495 {
2496     struct uifw_client      *uclient;
2497     struct uifw_win_surface *usurf;
2498     int     i, j;
2499     char    winname[ICO_IVI_WINNAME_LENGTH];
2500     char    appid[ICO_IVI_APPID_LENGTH];
2501
2502     /* get window name and application id   */
2503     j = 0;
2504     for (i = 0; target[i]; i++) {
2505         if (target[i] == '@')   {
2506             if (target[i+1] != '@') break;
2507             i ++;
2508         }
2509         if (j < (ICO_IVI_WINNAME_LENGTH-1)) {
2510             winname[j++] = target[i];
2511         }
2512     }
2513     winname[j] = 0;
2514     if (target[i] == '@')   {
2515         i ++;
2516     }
2517     else    {
2518         winname[0] = 0;
2519         i = 0;
2520     }
2521     j = 0;
2522     for ( ; target[i]; i++) {
2523         if ((target[i] == '@') && (target[i+1] == '@')) i ++;
2524         if (j < (ICO_IVI_APPID_LENGTH-1))  {
2525             appid[j++] = target[i];
2526         }
2527     }
2528     appid[j] = 0;
2529     uifw_debug("ico_window_mgr_get_client_usurf: target=<%s> appid=<%s> win=<%s>",
2530                target, appid, winname);
2531
2532     wl_list_for_each (uclient, &_ico_win_mgr->client_list, link)    {
2533         if (strcmp(uclient->appid, appid) == 0) {
2534             wl_list_for_each (usurf, &uclient->surface_link, client_link)   {
2535                 if ((winname[0] == 0) ||
2536                     (strcmp(winname, usurf->winname) == 0)) {
2537                     return usurf;
2538                 }
2539             }
2540         }
2541     }
2542     return NULL;
2543 }
2544
2545 /*--------------------------------------------------------------------------*/
2546 /**
2547  * @brief   ico_window_mgr_set_hook_animation: set animation hook routine
2548  *
2549  * @param[in]   hook_animation  hook routine
2550  * @return      none
2551  */
2552 /*--------------------------------------------------------------------------*/
2553 WL_EXPORT   void
2554 ico_window_mgr_set_hook_animation(int (*hook_animation)(const int op, void *data))
2555 {
2556     win_mgr_hook_animation = hook_animation;
2557 }
2558
2559 /*--------------------------------------------------------------------------*/
2560 /**
2561  * @brief   ico_window_mgr_set_hook_change: set input region hook routine
2562  *
2563  * @param[in]   hook_change     hook routine
2564  * @return      none
2565  */
2566 /*--------------------------------------------------------------------------*/
2567 WL_EXPORT   void
2568 ico_window_mgr_set_hook_change(void (*hook_change)(struct uifw_win_surface *usurf))
2569 {
2570     win_mgr_hook_change = hook_change;
2571 }
2572
2573 /*--------------------------------------------------------------------------*/
2574 /**
2575  * @brief   ico_window_mgr_set_hook_destory: set input region hook routine
2576  *
2577  * @param[in]   hook_destroy    hook routine
2578  * @return      none
2579  */
2580 /*--------------------------------------------------------------------------*/
2581 WL_EXPORT   void
2582 ico_window_mgr_set_hook_destory(void (*hook_destroy)(struct uifw_win_surface *usurf))
2583 {
2584     win_mgr_hook_destory = hook_destroy;
2585 }
2586
2587 /*--------------------------------------------------------------------------*/
2588 /**
2589  * @brief   ico_window_mgr_set_hook_inputregion: set input region hook routine
2590  *
2591  * @param[in]   hook_inputregion    hook routine
2592  * @return      none
2593  */
2594 /*--------------------------------------------------------------------------*/
2595 WL_EXPORT   void
2596 ico_window_mgr_set_hook_inputregion(
2597         void (*hook_inputregion)(int set, struct uifw_win_surface *usurf,
2598                                  int32_t x, int32_t y, int32_t width,
2599                                  int32_t height, int32_t hotspot_x, int32_t hotspot_y,
2600                                  int32_t cursor_x, int32_t cursor_y, int32_t cursor_width,
2601                                  int32_t cursor_height, uint32_t attr))
2602 {
2603     win_mgr_hook_inputregion = hook_inputregion;
2604 }
2605
2606 /*--------------------------------------------------------------------------*/
2607 /**
2608  * @brief   module_init: initialize ico_window_mgr
2609  *                       this function called from ico_pluign_loader
2610  *
2611  * @param[in]   es          weston compositor
2612  * @param[in]   argc        number of arguments(unused)
2613  * @param[in]   argv        argument list(unused)
2614  * @return      result
2615  * @retval      0           sccess
2616  * @retval      -1          error
2617  */
2618 /*--------------------------------------------------------------------------*/
2619 WL_EXPORT   int
2620 module_init(struct weston_compositor *ec, int *argc, char *argv[])
2621 {
2622     int     nodeId;
2623     int     i;
2624     int     idx;
2625     struct weston_output *output;
2626     struct weston_config_section *section;
2627     char    *displayno = NULL;
2628     char    *p;
2629     struct wl_event_loop *loop;
2630
2631     uifw_info("ico_window_mgr: Enter(module_init)");
2632
2633     /* get ivi debug level                      */
2634     section = weston_config_get_section(ec->config, "ivi-option", NULL, NULL);
2635     if (section)    {
2636         weston_config_section_get_int(section, "flag", &_ico_ivi_option_flag, 0);
2637         weston_config_section_get_int(section, "log", &_ico_ivi_debug_level, 3);
2638     }
2639
2640     /* get display number                       */
2641     section = weston_config_get_section(ec->config, "ivi-display", NULL, NULL);
2642     if (section)    {
2643         weston_config_section_get_string(section, "displayno", &displayno, NULL);
2644     }
2645
2646     /* get animation default                    */
2647     section = weston_config_get_section(ec->config, "ivi-animation", NULL, NULL);
2648     if (section)    {
2649         weston_config_section_get_string(section, "default", &_ico_ivi_animation_name, NULL);
2650         weston_config_section_get_int(section, "time", &_ico_ivi_animation_time, 500);
2651         weston_config_section_get_int(section, "fps", &_ico_ivi_animation_fps, 30);
2652     }
2653     if (_ico_ivi_animation_name == NULL)
2654         _ico_ivi_animation_name = (char *)"fade";
2655     if (_ico_ivi_animation_time < 100)  _ico_ivi_animation_time = 500;
2656     if (_ico_ivi_animation_fps < 3)     _ico_ivi_animation_fps = 30;
2657
2658     /* create ico_window_mgr management table   */
2659     _ico_win_mgr = (struct ico_win_mgr *)malloc(sizeof(struct ico_win_mgr));
2660     if (_ico_win_mgr == NULL)   {
2661         uifw_error("ico_window_mgr: malloc failed");
2662         return -1;
2663     }
2664
2665     memset(_ico_win_mgr, 0, sizeof(struct ico_win_mgr));
2666
2667     _ico_win_mgr->compositor = ec;
2668
2669     uifw_trace("ico_window_mgr: wl_global_create(bind_ico_win_mgr)");
2670     if (wl_global_create(ec->wl_display, &ico_window_mgr_interface, 1,
2671                          _ico_win_mgr, bind_ico_win_mgr) == NULL)  {
2672         uifw_error("ico_window_mgr: Error(wl_global_create)");
2673         return -1;
2674     }
2675
2676     wl_list_init(&_ico_win_mgr->client_list);
2677     wl_list_init(&_ico_win_mgr->manager_list);
2678     wl_list_init(&_ico_win_mgr->map_list);
2679     _ico_win_mgr->free_maptable = NULL;
2680
2681     /* create display list                  */
2682     if (displayno != NULL)   {
2683         p = displayno;
2684     }
2685     else    {
2686         p = NULL;
2687     }
2688     _ico_num_nodes = 0;
2689     wl_list_for_each (output, &ec->output_list, link) {
2690         wl_list_init(&_ico_win_mgr->map_animation[_ico_num_nodes].link);
2691         _ico_win_mgr->map_animation[_ico_num_nodes].frame = win_mgr_check_mapsurface;
2692         wl_list_insert(output->animation_list.prev,
2693                        &_ico_win_mgr->map_animation[_ico_num_nodes].link);
2694         _ico_num_nodes++;
2695         if (_ico_num_nodes >= ICO_IVI_MAX_DISPLAY)   break;
2696     }
2697     memset(&_ico_node_table[0], 0, sizeof(_ico_node_table));
2698     i = 0;
2699     wl_list_for_each (output, &ec->output_list, link) {
2700         p = strtok(p, ",");
2701         if (p)  {
2702             idx = strtol(p, (char **)0, 0);
2703             uifw_trace("ico_window_mgr: config Display.%d is weston display.%d", i, idx);
2704             p = NULL;
2705             if ((idx < 0) || (idx >= _ico_num_nodes))   {
2706                 idx = i;
2707             }
2708         }
2709         else    {
2710             idx = i;
2711         }
2712         if (_ico_node_table[idx].node)  {
2713             for (idx = 0; idx < _ico_num_nodes; idx++)  {
2714                 if (_ico_node_table[idx].node == 0) break;
2715             }
2716             if (idx >= _ico_num_nodes)  {
2717                 uifw_error("ico_window_mgr: number of display overflow");
2718                 idx = 0;
2719             }
2720         }
2721         _ico_node_table[idx].node = idx + 0x100;
2722         _ico_node_table[idx].displayno = i;
2723         _ico_node_table[idx].output = output;
2724         _ico_node_table[idx].disp_x = output->x;
2725         _ico_node_table[idx].disp_y = output->y;
2726         _ico_node_table[idx].disp_width = output->width;
2727         _ico_node_table[idx].disp_height = output->height;
2728         i ++;
2729         if (i >= _ico_num_nodes) break;
2730     }
2731     idx = 0;
2732     for (i = 0; i < _ico_num_nodes; i++)    {
2733         _ico_node_table[i].node &= 0x0ff;
2734         uifw_info("ico_window_mgr: Display.%d no=%d x/y=%d/%d w/h=%d/%d",
2735                   i, _ico_node_table[i].displayno,
2736                   _ico_node_table[i].disp_x, _ico_node_table[i].disp_y,
2737                   _ico_node_table[i].disp_width, _ico_node_table[i].disp_height);
2738     }
2739     if (displayno)  free(displayno);
2740
2741     /* my node Id ... this version fixed 0  */
2742     nodeId = ico_ivi_get_mynode();
2743
2744     _ico_win_mgr->surface_head = ICO_IVI_SURFACEID_BASE(nodeId);
2745     uifw_trace("ico_window_mgr: NoedId=%04x SurfaceIdBase=%08x",
2746                 nodeId, _ico_win_mgr->surface_head);
2747
2748     /* get seat for touch down counter check    */
2749     touch_check_seat = container_of(ec->seat_list.next, struct weston_seat, link);
2750     loop = wl_display_get_event_loop(ec->wl_display);
2751     _ico_win_mgr->wait_mapevent =
2752             wl_event_loop_add_timer(loop, win_mgr_timer_mapsurface, NULL);
2753     wl_event_source_timer_update(_ico_win_mgr->wait_mapevent, 1000);
2754
2755     uifw_info("ico_window_mgr: animation name=%s time=%d fps=%d",
2756               _ico_ivi_animation_name, _ico_ivi_animation_time, _ico_ivi_animation_fps);
2757     uifw_info("ico_window_mgr: option flag=0x%04x log level=%d debug flag=0x%04x",
2758               _ico_ivi_option_flag, _ico_ivi_debug_level & 0x0ffff,
2759               (_ico_ivi_debug_level >> 16) & 0x0ffff);
2760
2761     /* touch/click binding for select surface           */
2762     weston_compositor_add_button_binding(ec, BTN_LEFT, 0, win_mgr_click_to_activate, NULL);
2763     weston_compositor_add_touch_binding(ec, 0, win_mgr_touch_to_activate, NULL);
2764
2765     /* set Notification function for GENIVI ivi-shell   */
2766     if (weston_layout_setNotificationCreateSurface(ico_ivi_surfaceCreateNotification, NULL) != 0)   {
2767         uifw_error("ico_window_mgr: weston_layout_setNotificationCreateSurface Error");
2768     }
2769     if (weston_layout_setNotificationRemoveSurface(ico_ivi_surfaceRemoveNotification, NULL) != 0)   {
2770         uifw_error("ico_window_mgr: weston_layout_setNotificationRemoveSurface Error");
2771     }
2772     uifw_info("ico_window_mgr: Leave(module_init)");
2773
2774     return 0;
2775 }