• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Codethink Ltd
3  * Copyright (C) 2015 Advanced Driver Information Technology Joint Venture GmbH
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and
6  * its documentation for any purpose is hereby granted without fee, provided
7  * that the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation, and that the name of the copyright holders not be used in
10  * advertising or publicity pertaining to distribution of the software
11  * without specific, written prior permission.  The copyright holders make
12  * no representations about the suitability of this software for any
13  * purpose.  It is provided "as is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  */
23 
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 
32 #include "plugin-registry.h"
33 #include "ilm_types.h"
34 
35 #include "ivi-input-server-protocol.h"
36 #include "ivi-controller.h"
37 #include "libweston-internal.h"
38 #include "ivi-input-export.h"
39 
40 struct seat_ctx {
41     struct input_context *input_ctx;
42     struct weston_keyboard_grab keyboard_grab;
43     struct weston_pointer_grab pointer_grab;
44     struct weston_touch_grab touch_grab;
45     struct weston_seat *west_seat;
46 
47     /* pointer focus can be forced to specific surfaces
48      * when there are no motion events at all. motion
49      * event will re-evaulate the focus. A rotary knob
50      * is one of the examples, where it is used as pointer
51      * axis.*/
52     struct ivisurface *forced_ptr_focus_surf;
53     int32_t  forced_surf_enabled;
54 
55     struct wl_listener updated_caps_listener;
56     struct wl_listener destroy_listener;
57     struct wl_list seat_node;
58 };
59 
60 struct seat_focus {
61     struct seat_ctx *seat_ctx;
62     ilmInputDevice focus;
63     struct wl_list link;
64 };
65 
66 struct input_context {
67     struct wl_list resource_list;
68     struct wl_list seat_list;
69     int successful_init_stage;
70     struct ivishell *ivishell;
71 
72     struct wl_listener surface_created;
73     struct wl_listener surface_destroyed;
74     struct wl_listener compositor_destroy_listener;
75     struct wl_listener seat_create_listener;
76 };
77 
78 enum kbd_events {
79     KEYBOARD_ENTER,
80     KEYBOARD_LEAVE,
81     KEYBOARD_KEY,
82     KEYBOARD_MODIFIER
83 };
84 
85 struct wl_keyboard_data {
86     enum kbd_events kbd_evt;
87     uint32_t time;
88     uint32_t key;
89     uint32_t state;
90     uint32_t mods_depressed;
91     uint32_t mods_latched;
92     uint32_t mods_locked;
93     uint32_t group;
94     uint32_t serial;
95 };
96 
97 static struct input_context *g_ctx = {0};
98 struct input_context *
get_instance(void)99 get_instance(void)
100 {
101     return &g_ctx;
102 }
103 
104 static struct seat_focus *
get_accepted_seat(struct ivisurface * surface,struct seat_ctx * seat_ctx)105 get_accepted_seat(struct ivisurface *surface, struct seat_ctx *seat_ctx)
106 {
107     struct seat_focus *st_focus;
108     struct seat_focus *ret_focus = NULL;
109 
110     wl_list_for_each(st_focus, &surface->accepted_seat_list, link) {
111         if (st_focus->seat_ctx == seat_ctx) {
112             ret_focus = st_focus;
113             break;
114         }
115     }
116     return ret_focus;
117 }
118 
119 static int
add_accepted_seat(struct ivisurface * surface,struct seat_ctx * seat_ctx)120 add_accepted_seat(struct ivisurface *surface, struct seat_ctx *seat_ctx)
121 {
122     const struct ivi_layout_interface *interface =
123         surface->shell->interface;
124     struct seat_focus *st_focus;
125     int ret = 0;
126 
127     st_focus = get_accepted_seat(surface, seat_ctx);
128     if (st_focus == NULL) {
129         st_focus = calloc(1, sizeof(*st_focus));
130 
131         if (NULL != st_focus) {
132             st_focus->seat_ctx = seat_ctx;
133             wl_list_insert(&surface->accepted_seat_list, &st_focus->link);
134             ret = 1;
135        } else {
136             weston_log("%s Failed to allocate memory for seat addition of surface %d",
137                     __FUNCTION__, interface->get_id_of_surface(surface->layout_surface));
138         }
139     } else {
140         weston_log("%s: Warning: seat '%s' is already accepted by surface %d\n",
141                    __FUNCTION__, seat_ctx->west_seat->seat_name,
142                    interface->get_id_of_surface(surface->layout_surface));
143         ret = 1;
144     }
145 
146     return ret;
147 }
148 
149 static int
remove_if_seat_accepted(struct ivisurface * surface,struct seat_ctx * seat_ctx)150 remove_if_seat_accepted(struct ivisurface *surface, struct seat_ctx *seat_ctx)
151 {
152     int ret = 0;
153 
154     struct seat_focus *st_focus = get_accepted_seat(surface, seat_ctx);
155 
156     if (NULL != st_focus) {
157         ret = 1;
158         wl_list_remove(&st_focus->link);
159         free(st_focus);
160 
161     }
162     return ret;
163 }
164 
165 struct seat_ctx*
input_ctrl_get_seat_ctx(struct input_context * ctx,const char * nm_seat)166 input_ctrl_get_seat_ctx(struct input_context *ctx, const char *nm_seat)
167 {
168     struct seat_ctx *ctx_seat;
169     struct seat_ctx *ret_ctx = NULL;
170     wl_list_for_each(ctx_seat, &ctx->seat_list, seat_node) {
171         if (0 == strcmp(ctx_seat->west_seat->seat_name, nm_seat)) {
172             ret_ctx = ctx_seat;
173             break;
174         }
175     }
176     return ret_ctx;
177 }
178 
179 static void
send_input_acceptance(struct input_context * ctx,uint32_t surface_id,const char * seat,int32_t accepted)180 send_input_acceptance(struct input_context *ctx, uint32_t surface_id, const char *seat, int32_t accepted)
181 {
182     struct wl_resource *resource;
183     wl_resource_for_each(resource, &ctx->resource_list) {
184         ivi_input_send_input_acceptance(resource, surface_id, seat,
185                                         accepted);
186     }
187 }
188 
189 static void
send_input_focus(struct input_context * ctx,struct ivisurface * surf_ctx,ilmInputDevice device,t_ilm_bool enabled)190 send_input_focus(struct input_context *ctx, struct ivisurface *surf_ctx,
191                  ilmInputDevice device, t_ilm_bool enabled)
192 {
193     struct wl_resource *resource;
194     const struct ivi_layout_interface *lyt_if = ctx->ivishell->interface;
195     t_ilm_surface surface_id = lyt_if->get_id_of_surface(surf_ctx->layout_surface);
196 
197     wl_resource_for_each(resource, &ctx->resource_list) {
198         ivi_input_send_input_focus(resource, surface_id, device, enabled);
199     }
200 }
201 
202 static struct ivisurface *
input_ctrl_get_surf_ctx(struct input_context * ctx,struct ivi_layout_surface * lyt_surf)203 input_ctrl_get_surf_ctx(struct input_context *ctx,
204         struct ivi_layout_surface *lyt_surf)
205 {
206     struct ivisurface *surf_ctx = NULL;
207     struct ivisurface *ret_ctx = NULL;
208     wl_list_for_each(surf_ctx, &ctx->ivishell->list_surface, link) {
209         if (lyt_surf == surf_ctx->layout_surface) {
210             ret_ctx = surf_ctx;
211             break;
212         }
213     }
214     return ret_ctx;
215 }
216 
217 
218 static struct ivisurface *
input_ctrl_get_surf_ctx_from_id(struct input_context * ctx,uint32_t ivi_surf_id)219 input_ctrl_get_surf_ctx_from_id(struct input_context *ctx,
220         uint32_t ivi_surf_id)
221 {
222     const struct ivi_layout_interface *interface = ctx->ivishell->interface;
223     struct ivi_layout_surface *lyt_surf;
224     lyt_surf = interface->get_surface_from_id(ivi_surf_id);
225 
226     return input_ctrl_get_surf_ctx(ctx, lyt_surf);
227 }
228 
229 
230 static struct ivisurface *
input_ctrl_get_surf_ctx_from_surf(struct input_context * ctx,struct weston_surface * west_surf)231 input_ctrl_get_surf_ctx_from_surf(struct input_context *ctx,
232         struct weston_surface *west_surf)
233 {
234     struct weston_surface *main_surface;
235     struct ivi_layout_surface *layout_surf;
236     struct ivisurface *surf_ctx = NULL;
237     const struct ivi_layout_interface *lyt_if = ctx->ivishell->interface;
238     main_surface = weston_surface_get_main_surface(west_surf);
239 
240     if (NULL != main_surface) {
241         layout_surf = lyt_if->get_surface(main_surface);
242         surf_ctx = input_ctrl_get_surf_ctx(ctx, layout_surf);
243     }
244     return surf_ctx;
245 }
246 
247 static void
input_ctrl_kbd_snd_event_resource(struct seat_ctx * ctx_seat,struct weston_keyboard * keyboard,struct wl_resource * resource,struct wl_resource * surf_resource,struct wl_keyboard_data * kbd_data)248 input_ctrl_kbd_snd_event_resource(struct seat_ctx *ctx_seat,
249         struct weston_keyboard *keyboard, struct wl_resource *resource,
250         struct wl_resource *surf_resource, struct wl_keyboard_data *kbd_data)
251 {
252     struct weston_seat *seat = ctx_seat->west_seat;
253     switch(kbd_data->kbd_evt)
254     {
255     case KEYBOARD_ENTER:
256         if (wl_resource_get_version(resource) >=
257                 WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
258             wl_keyboard_send_repeat_info(resource,
259                              seat->compositor->kb_repeat_rate,
260                              seat->compositor->kb_repeat_delay);
261         }
262 
263         weston_keyboard_send_keymap(keyboard, resource);
264 
265         wl_keyboard_send_modifiers(resource,
266                        kbd_data->serial,
267                        keyboard->modifiers.mods_depressed,
268                        keyboard->modifiers.mods_latched,
269                        keyboard->modifiers.mods_locked,
270                        keyboard->modifiers.group);
271         wl_keyboard_send_enter(resource, kbd_data->serial, surf_resource,
272                 &keyboard->keys);
273 
274         break;
275     case KEYBOARD_LEAVE:
276         wl_keyboard_send_leave(resource, kbd_data->serial, surf_resource);
277         break;
278     case KEYBOARD_KEY:
279         wl_keyboard_send_key(resource, kbd_data->serial, kbd_data->time,
280                 kbd_data->key, kbd_data->state);
281         break;
282     case KEYBOARD_MODIFIER:
283         wl_keyboard_send_modifiers(resource,
284                        kbd_data->serial,
285                        kbd_data->mods_depressed,
286                        kbd_data->mods_latched,
287                        kbd_data->mods_locked,
288                        kbd_data->group);
289         break;
290     default:
291         weston_log("%s: error:  Uknown keyboard event %d", __FUNCTION__,
292                 kbd_data->kbd_evt);
293         break;
294     }
295 }
296 
297 
298 static void
input_ctrl_kbd_wl_snd_event(struct seat_ctx * ctx_seat,struct weston_surface * send_surf,struct weston_keyboard * keyboard,struct wl_keyboard_data * kbd_data)299 input_ctrl_kbd_wl_snd_event(struct seat_ctx *ctx_seat,
300         struct weston_surface *send_surf, struct weston_keyboard *keyboard,
301         struct wl_keyboard_data *kbd_data)
302 {
303     struct wl_resource *resource;
304     struct wl_client *surface_client;
305     struct wl_client *client;
306     struct wl_list *resource_list;
307 
308     surface_client = wl_resource_get_client(send_surf->resource);
309     resource_list = &keyboard->focus_resource_list;
310     wl_resource_for_each(resource, resource_list) {
311         client = wl_resource_get_client(resource);
312         if (surface_client == client){
313             input_ctrl_kbd_snd_event_resource(ctx_seat, keyboard, resource,
314                     send_surf->resource, kbd_data);
315         }
316     }
317 
318     resource_list = &keyboard->resource_list;
319     wl_resource_for_each(resource, resource_list) {
320         client = wl_resource_get_client(resource);
321         if (surface_client == client){
322             input_ctrl_kbd_snd_event_resource(ctx_seat, keyboard, resource,
323                     send_surf->resource, kbd_data);
324         }
325     }
326 }
327 
328 
329 static void
input_ctrl_kbd_leave_surf(struct seat_ctx * ctx_seat,struct ivisurface * surf_ctx,struct weston_surface * w_surf)330 input_ctrl_kbd_leave_surf(struct seat_ctx *ctx_seat,
331         struct ivisurface *surf_ctx, struct weston_surface *w_surf)
332 {
333     struct wl_keyboard_data kbd_data;
334     struct input_context *ctx = ctx_seat->input_ctx;
335     struct seat_focus *st_focus;
336 
337     st_focus = get_accepted_seat(surf_ctx, ctx_seat);
338 
339     if ((NULL != st_focus)
340         && ((st_focus->focus & ILM_INPUT_DEVICE_KEYBOARD))) {
341 
342         kbd_data.kbd_evt = KEYBOARD_LEAVE;
343         kbd_data.serial = wl_display_next_serial(
344                                 ctx->ivishell->compositor->wl_display);;
345         input_ctrl_kbd_wl_snd_event(ctx_seat, w_surf,
346                 ctx_seat->keyboard_grab.keyboard, &kbd_data);
347 
348         st_focus->focus &= ~ILM_INPUT_DEVICE_KEYBOARD;
349         send_input_focus(ctx, surf_ctx,
350                 ILM_INPUT_DEVICE_KEYBOARD, ILM_FALSE);
351     }
352 }
353 
354 static void
input_ctrl_kbd_enter_surf(struct seat_ctx * ctx_seat,struct ivisurface * surf_ctx,struct weston_surface * w_surf)355 input_ctrl_kbd_enter_surf(struct seat_ctx *ctx_seat,
356         struct ivisurface *surf_ctx, struct weston_surface *w_surf)
357 {
358     struct wl_keyboard_data kbd_data;
359     struct input_context *ctx = ctx_seat->input_ctx;
360     struct seat_focus *st_focus;
361     uint32_t serial;
362 
363     st_focus = get_accepted_seat(surf_ctx, ctx_seat);
364     if ((NULL != st_focus) &&
365         (!(st_focus->focus & ILM_INPUT_DEVICE_KEYBOARD))) {
366         serial = wl_display_next_serial(ctx->ivishell->compositor->wl_display);
367 
368         kbd_data.kbd_evt = KEYBOARD_ENTER;
369         kbd_data.serial = serial;
370         input_ctrl_kbd_wl_snd_event(ctx_seat, w_surf,
371                 ctx_seat->keyboard_grab.keyboard, &kbd_data);
372 
373         st_focus->focus |= ILM_INPUT_DEVICE_KEYBOARD;
374         send_input_focus(ctx, surf_ctx,
375                 ILM_INPUT_DEVICE_KEYBOARD, ILM_TRUE);
376 
377     }
378 }
379 
380 static void
input_ctrl_kbd_set_focus_surf(struct seat_ctx * ctx_seat,struct ivisurface * surf_ctx,int32_t enabled)381 input_ctrl_kbd_set_focus_surf(struct seat_ctx *ctx_seat,
382         struct ivisurface *surf_ctx, int32_t enabled)
383 {
384     struct input_context *ctx = ctx_seat->input_ctx;
385     const struct ivi_layout_interface *interface = ctx->ivishell->interface;
386     struct weston_surface *w_surf;
387 
388     struct weston_keyboard *keyboard = weston_seat_get_keyboard(
389                                             ctx_seat->west_seat);
390 
391 
392     if (NULL != keyboard) {
393         w_surf = interface->surface_get_weston_surface(
394                 surf_ctx->layout_surface);
395 
396         if (ILM_TRUE == enabled) {
397             input_ctrl_kbd_enter_surf(ctx_seat, surf_ctx, w_surf);
398         } else {
399             input_ctrl_kbd_leave_surf(ctx_seat, surf_ctx, w_surf);
400         }
401     }
402 }
403 
404 static void
keyboard_grab_key(struct weston_keyboard_grab * grab,const struct timespec * time,uint32_t key,uint32_t state)405 keyboard_grab_key(struct weston_keyboard_grab *grab, const struct timespec *time,
406                   uint32_t key, uint32_t state)
407 {
408     struct seat_ctx *seat_ctx = wl_container_of(grab, seat_ctx, keyboard_grab);
409     struct ivisurface *surf_ctx;
410     struct seat_focus *st_focus;
411     struct wl_keyboard_data kbd_data;
412     struct weston_surface *surface;
413     const struct ivi_layout_interface *interface =
414         seat_ctx->input_ctx->ivishell->interface;
415 
416     kbd_data.kbd_evt = KEYBOARD_KEY;
417     kbd_data.time = timespec_to_msec(time);
418     kbd_data.key = key;
419     kbd_data.state = state;
420     kbd_data.serial = wl_display_next_serial(grab->keyboard->seat->
421                                             compositor->wl_display);
422 
423     wl_list_for_each(surf_ctx, &seat_ctx->input_ctx->ivishell->list_surface, link) {
424 
425         st_focus = get_accepted_seat(surf_ctx, seat_ctx);
426         if (NULL == st_focus)
427             continue;
428 
429         if (!(st_focus->focus & ILM_INPUT_DEVICE_KEYBOARD))
430             continue;
431 
432         surface = interface->surface_get_weston_surface(surf_ctx->layout_surface);
433         input_ctrl_kbd_wl_snd_event(seat_ctx, surface, grab->keyboard, &kbd_data);
434     }
435 }
436 
437 static void
keyboard_grab_modifiers(struct weston_keyboard_grab * grab,uint32_t serial,uint32_t mods_depressed,uint32_t mods_latched,uint32_t mods_locked,uint32_t group)438 keyboard_grab_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
439                         uint32_t mods_depressed, uint32_t mods_latched,
440                         uint32_t mods_locked, uint32_t group)
441 {
442     struct seat_ctx *seat_ctx = wl_container_of(grab, seat_ctx, keyboard_grab);
443     struct ivisurface *surf_ctx;
444     struct seat_focus *st_focus;
445     struct weston_surface *surface;
446     struct wl_keyboard_data kbd_data;
447     const struct ivi_layout_interface *interface =
448         seat_ctx->input_ctx->ivishell->interface;
449 
450     kbd_data.kbd_evt = KEYBOARD_MODIFIER;
451     kbd_data.serial = serial;
452     kbd_data.mods_depressed = mods_depressed;
453     kbd_data.mods_latched = mods_latched;
454     kbd_data.mods_locked = mods_locked;
455     kbd_data.group = group;
456 
457     wl_list_for_each(surf_ctx, &seat_ctx->input_ctx->ivishell->list_surface, link) {
458 
459         st_focus = get_accepted_seat(surf_ctx, seat_ctx);
460         if (NULL == st_focus)
461             continue;
462 
463         /* Keyboard modifiers go to surfaces with pointer focus as well */
464         if (!(st_focus->focus
465               & (ILM_INPUT_DEVICE_KEYBOARD | ILM_INPUT_DEVICE_POINTER)))
466             continue;
467 
468         surface = interface->surface_get_weston_surface(surf_ctx->layout_surface);
469 
470         input_ctrl_kbd_wl_snd_event(seat_ctx, surface, grab->keyboard, &kbd_data);
471     }
472 }
473 
474 static void
keyboard_grab_cancel(struct weston_keyboard_grab * grab)475 keyboard_grab_cancel(struct weston_keyboard_grab *grab)
476 {
477     struct seat_ctx *ctx_seat = wl_container_of(grab, ctx_seat, keyboard_grab);
478     struct ivisurface *surf;
479     struct weston_surface *w_surf;
480     const struct ivi_layout_interface *interface =
481                                 ctx_seat->input_ctx->ivishell->interface;
482 
483     wl_list_for_each(surf, &ctx_seat->input_ctx->ivishell->list_surface,
484                      link) {
485         w_surf = interface->surface_get_weston_surface(surf->layout_surface);
486         input_ctrl_kbd_leave_surf(ctx_seat, surf, w_surf);
487     }
488 }
489 
490 static struct weston_keyboard_grab_interface keyboard_grab_interface = {
491     keyboard_grab_key,
492     keyboard_grab_modifiers,
493     keyboard_grab_cancel
494 };
495 
496 struct seat_focus *
input_ctrl_snd_focus_to_controller(struct ivisurface * surf_ctx,struct seat_ctx * ctx_seat,ilmInputDevice device,int32_t enabled)497 input_ctrl_snd_focus_to_controller(struct ivisurface *surf_ctx,
498         struct seat_ctx *ctx_seat, ilmInputDevice device,
499         int32_t enabled)
500 {
501     struct input_context *ctx = ctx_seat->input_ctx;
502     struct seat_focus *st_focus = NULL;
503 
504     if (NULL != surf_ctx) {
505         st_focus = get_accepted_seat(surf_ctx, ctx_seat);
506         /* Send focus lost event to the surface which has lost the focus*/
507         if (NULL != st_focus) {
508             if (ILM_TRUE == enabled) {
509                 st_focus->focus |= device;
510             } else {
511                 st_focus->focus &= ~device;
512             }
513             send_input_focus(ctx, surf_ctx, device, enabled);
514         }
515     }
516     return st_focus;
517 }
518 
519 static void
input_ctrl_ptr_leave_west_focus(struct seat_ctx * ctx_seat,struct weston_pointer * pointer)520 input_ctrl_ptr_leave_west_focus(struct seat_ctx *ctx_seat,
521         struct weston_pointer *pointer)
522 {
523     struct ivisurface *surf_ctx;
524     struct input_context *ctx = ctx_seat->input_ctx;
525 
526     if (NULL != pointer->focus) {
527         surf_ctx = input_ctrl_get_surf_ctx_from_surf(ctx,
528                 pointer->focus->surface);
529 
530         input_ctrl_snd_focus_to_controller(surf_ctx, ctx_seat,
531                 ILM_INPUT_DEVICE_POINTER, ILM_FALSE);
532 
533         weston_pointer_clear_focus(pointer);
534     }
535 }
536 
537 
538 static void
input_ctrl_ptr_set_west_focus(struct seat_ctx * ctx_seat,struct weston_pointer * pointer,struct weston_view * w_view)539 input_ctrl_ptr_set_west_focus(struct seat_ctx *ctx_seat,
540         struct weston_pointer *pointer, struct weston_view *w_view)
541 {
542     struct weston_view *view = w_view;
543     struct ivisurface *surf_ctx;
544     struct input_context *ctx = ctx_seat->input_ctx;
545     struct seat_focus *st_focus;
546     wl_fixed_t sx, sy;
547 
548     if (NULL == view) {
549         view = weston_compositor_pick_view(pointer->seat->compositor,
550                        pointer->x, pointer->y,
551                        &sx, &sy);
552     } else {
553         weston_view_from_global_fixed(view, pointer->x,
554                         pointer->y, &sx, &sy);
555     }
556 
557     if (pointer->focus != view) {
558 
559         if (NULL != pointer->focus) {
560             surf_ctx = input_ctrl_get_surf_ctx_from_surf(ctx,
561                                             pointer->focus->surface);
562             /*Leave existing pointer focus*/
563             input_ctrl_snd_focus_to_controller(surf_ctx, ctx_seat,
564                     ILM_INPUT_DEVICE_POINTER, ILM_FALSE);
565 
566         }
567 
568         if (NULL != view) {
569             surf_ctx = input_ctrl_get_surf_ctx_from_surf(ctx, view->surface);
570 
571             if (NULL != surf_ctx) {
572                 /*Enter into new pointer focus is seat accepts*/
573                 st_focus = input_ctrl_snd_focus_to_controller(surf_ctx,
574                         ctx_seat, ILM_INPUT_DEVICE_POINTER, ILM_TRUE);
575 
576                 if (st_focus != NULL) {
577                     weston_pointer_set_focus(pointer, view, sx, sy);
578                 } else {
579                     if (NULL != pointer->focus)
580                         weston_pointer_clear_focus(pointer);
581                 }
582             } else {
583                 weston_pointer_set_focus(pointer, view, sx, sy);
584             }
585         } else {
586             if (NULL != pointer->focus)
587                 weston_pointer_clear_focus(pointer);
588         }
589     }
590 }
591 
592 static bool
input_ctrl_ptr_is_focus_emtpy(struct seat_ctx * ctx_seat)593 input_ctrl_ptr_is_focus_emtpy(struct seat_ctx *ctx_seat)
594 {
595     return (NULL == ctx_seat->pointer_grab.pointer->focus);
596 }
597 
598 static void
input_ctrl_ptr_clear_focus(struct seat_ctx * ctx_seat)599 input_ctrl_ptr_clear_focus(struct seat_ctx *ctx_seat)
600 {
601     if (!input_ctrl_ptr_is_focus_emtpy(ctx_seat)) {
602         input_ctrl_ptr_leave_west_focus(ctx_seat,
603                 ctx_seat->pointer_grab.pointer);
604         ctx_seat->forced_ptr_focus_surf = NULL;
605     }
606 }
607 
608 static void
input_ctrl_ptr_set_focus_surf(struct seat_ctx * ctx_seat,struct ivisurface * surf_ctx,int32_t enabled)609 input_ctrl_ptr_set_focus_surf(struct seat_ctx *ctx_seat,
610         struct ivisurface *surf_ctx, int32_t enabled)
611 {
612     struct weston_pointer *pointer;
613     pointer = weston_seat_get_pointer(ctx_seat->west_seat);
614     if (NULL != pointer) {
615         if (ILM_TRUE == enabled) {
616             if (ctx_seat->forced_ptr_focus_surf != surf_ctx) {
617                 ctx_seat->forced_ptr_focus_surf = surf_ctx;
618                 ctx_seat->forced_surf_enabled = ILM_TRUE;
619                 ctx_seat->pointer_grab.interface->focus(
620                                     &ctx_seat->pointer_grab);
621             }
622         } else {
623             if (ctx_seat->forced_ptr_focus_surf == surf_ctx) {
624                 ctx_seat->forced_surf_enabled = ILM_FALSE;
625                 ctx_seat->pointer_grab.interface->focus(
626                                     &ctx_seat->pointer_grab);
627             }
628         }
629     }
630 }
631 
632 static void
pointer_grab_focus(struct weston_pointer_grab * grab)633 pointer_grab_focus(struct weston_pointer_grab *grab)
634 {
635     struct seat_ctx *seat = wl_container_of(grab, seat, pointer_grab);
636     struct weston_pointer *pointer = grab->pointer;
637     struct weston_surface *forced_west_surf = NULL;
638     struct weston_view *w_view;
639     struct ivi_layout_surface *layout_surf;
640     struct input_context *ctx = seat->input_ctx;
641 
642     if (pointer->button_count > 0) {
643         return;
644     }
645 
646     if (seat->forced_ptr_focus_surf != NULL) {
647         /*When we want to force pointer focus to
648          * a certain surface*/
649         layout_surf = seat->forced_ptr_focus_surf->layout_surface;
650         forced_west_surf = ctx->ivishell->interface->
651                             surface_get_weston_surface(layout_surf);
652 
653         if (seat->forced_surf_enabled == ILM_TRUE) {
654             if ((NULL != forced_west_surf) && !wl_list_empty(&forced_west_surf->views)) {
655                 w_view = wl_container_of(forced_west_surf->views.next,
656                         w_view, surface_link);
657                 input_ctrl_ptr_set_west_focus(seat, pointer, w_view);
658             }
659         } else if (NULL != pointer->focus) {
660             if(pointer->focus->surface == forced_west_surf) {
661                 input_ctrl_ptr_leave_west_focus(seat, pointer);
662             }
663             seat->forced_ptr_focus_surf = NULL;
664         }
665 
666     } else {
667         input_ctrl_ptr_set_west_focus(seat, pointer, NULL);
668     }
669 }
670 
671 static void
pointer_grab_motion(struct weston_pointer_grab * grab,const struct timespec * time,struct weston_pointer_motion_event * event)672 pointer_grab_motion(struct weston_pointer_grab *grab, const struct timespec *time,
673                     struct weston_pointer_motion_event *event)
674 {
675     struct seat_ctx *seat = wl_container_of(grab, seat, pointer_grab);
676     /*Motion results in re-evaluation of pointer focus*/
677     seat->forced_ptr_focus_surf = NULL;
678     weston_pointer_send_motion(grab->pointer, time, event);
679 }
680 
681 static void
pointer_grab_button(struct weston_pointer_grab * grab,const struct timespec * time,uint32_t button,uint32_t state)682 pointer_grab_button(struct weston_pointer_grab *grab, const struct timespec *time,
683                     uint32_t button, uint32_t state)
684 {
685     struct weston_pointer *pointer = grab->pointer;
686 
687     weston_pointer_send_button(pointer, time, button, state);
688 
689     if (pointer->button_count == 0 &&
690         state == WL_POINTER_BUTTON_STATE_RELEASED) {
691         grab->interface->focus(grab);
692     }
693 }
694 
695 static void
pointer_grab_axis(struct weston_pointer_grab * grab,const struct timespec * time,struct weston_pointer_axis_event * event)696 pointer_grab_axis(struct weston_pointer_grab *grab,
697                   const struct timespec *time,
698                   struct weston_pointer_axis_event *event)
699 {
700     weston_pointer_send_axis(grab->pointer, time, event);
701 }
702 
703 static void
pointer_grab_axis_source(struct weston_pointer_grab * grab,uint32_t source)704 pointer_grab_axis_source(struct weston_pointer_grab *grab,
705                           uint32_t source)
706 {
707     weston_pointer_send_axis_source(grab->pointer, source);
708 }
709 
710 static void
pointer_grab_frame(struct weston_pointer_grab * grab)711 pointer_grab_frame(struct weston_pointer_grab *grab)
712 {
713     weston_pointer_send_frame(grab->pointer);
714 }
715 
716 static void
pointer_grab_cancel(struct weston_pointer_grab * grab)717 pointer_grab_cancel(struct weston_pointer_grab *grab)
718 {
719     struct seat_ctx *ctx_seat = wl_container_of(grab, ctx_seat, pointer_grab);
720     input_ctrl_ptr_clear_focus(ctx_seat);
721 }
722 
723 static struct weston_pointer_grab_interface pointer_grab_interface = {
724     pointer_grab_focus,
725     pointer_grab_motion,
726     pointer_grab_button,
727     pointer_grab_axis,
728     pointer_grab_axis_source,
729     pointer_grab_frame,
730     pointer_grab_cancel
731 };
732 
733 static void
input_ctrl_touch_set_west_focus(struct seat_ctx * ctx_seat,struct weston_touch * touch,const struct timespec * time,int touch_id,wl_fixed_t x,wl_fixed_t y)734 input_ctrl_touch_set_west_focus(struct seat_ctx *ctx_seat,
735         struct weston_touch *touch, const struct timespec *time,
736         int touch_id, wl_fixed_t x, wl_fixed_t y)
737 {
738     /*Weston would have set the focus here*/
739     struct ivisurface *surf_ctx;
740     struct seat_focus *st_focus;
741 
742     if (touch->focus == NULL)
743         return;
744 
745     surf_ctx = input_ctrl_get_surf_ctx_from_surf(ctx_seat->input_ctx,
746                             touch->focus->surface);
747 
748     if (NULL != surf_ctx) {
749         if (touch->num_tp == 1) {
750             st_focus = input_ctrl_snd_focus_to_controller(surf_ctx, ctx_seat,
751                     ILM_INPUT_DEVICE_TOUCH, ILM_TRUE);
752         } else {
753             st_focus = get_accepted_seat(surf_ctx, ctx_seat);
754         }
755 
756         if (st_focus != NULL) {
757             weston_touch_send_down(touch, time, touch_id, x, y);
758 
759         } else {
760             weston_touch_set_focus(touch, NULL);
761         }
762     } else {
763         /*Support non ivi-surfaces like input panel*/
764         weston_touch_send_down(touch, time, touch_id, x, y);
765     }
766 }
767 
768 static void
input_ctrl_touch_west_send_cancel(struct weston_touch * touch)769 input_ctrl_touch_west_send_cancel(struct weston_touch *touch)
770 {
771     struct wl_resource *resource;
772 
773     if (!weston_touch_has_focus_resource(touch))
774         return;
775 
776     wl_resource_for_each(resource, &touch->focus_resource_list)
777         wl_touch_send_cancel(resource);
778 
779 }
780 
781 static void
input_ctrl_touch_clear_focus(struct seat_ctx * ctx_seat)782 input_ctrl_touch_clear_focus(struct seat_ctx *ctx_seat)
783 {
784     struct input_context *ctx = ctx_seat->input_ctx;
785     struct weston_touch *touch = ctx_seat->touch_grab.touch;
786     struct ivisurface *surf_ctx;
787 
788     if (touch->focus != NULL) {
789 
790         surf_ctx = input_ctrl_get_surf_ctx_from_surf(ctx,
791                                 touch->focus->surface);
792 
793         input_ctrl_snd_focus_to_controller(surf_ctx, ctx_seat,
794                 ILM_INPUT_DEVICE_TOUCH, ILM_FALSE);
795 
796         input_ctrl_touch_west_send_cancel(touch);
797 
798         weston_touch_set_focus(touch, NULL);
799     }
800 }
801 
802 static void
touch_grab_down(struct weston_touch_grab * grab,const struct timespec * time,int touch_id,wl_fixed_t x,wl_fixed_t y)803 touch_grab_down(struct weston_touch_grab *grab, const struct timespec *time,
804                 int touch_id, wl_fixed_t x, wl_fixed_t y)
805 {
806     struct seat_ctx *seat = wl_container_of(grab, seat, touch_grab);
807 
808     /* if touch device has no focused view, there is nothing to do*/
809     if (grab->touch->focus == NULL)
810         return;
811 
812     input_ctrl_touch_set_west_focus(seat, grab->touch, time, touch_id,
813                                     x, y);
814 }
815 
816 static void
touch_grab_up(struct weston_touch_grab * grab,const struct timespec * time,int touch_id)817 touch_grab_up(struct weston_touch_grab *grab, const struct timespec *time,
818               int touch_id)
819 {
820     struct seat_ctx *seat = wl_container_of(grab, seat, touch_grab);
821     struct input_context *ctx = seat->input_ctx;
822     struct weston_touch *touch = grab->touch;
823     struct ivisurface *surf_ctx;
824 
825     if (NULL != touch->focus) {
826         if (touch->num_tp == 0) {
827             surf_ctx = input_ctrl_get_surf_ctx_from_surf(ctx,
828                                     touch->focus->surface);
829 
830             input_ctrl_snd_focus_to_controller(surf_ctx,
831                     seat, ILM_INPUT_DEVICE_TOUCH, ILM_FALSE);
832         }
833         weston_touch_send_up(touch, time, touch_id);
834     }
835 }
836 
837 static void
touch_grab_motion(struct weston_touch_grab * grab,const struct timespec * time,int touch_id,wl_fixed_t x,wl_fixed_t y)838 touch_grab_motion(struct weston_touch_grab *grab, const struct timespec *time, int touch_id,
839                   wl_fixed_t x, wl_fixed_t y)
840 {
841     weston_touch_send_motion(grab->touch, time, touch_id, x, y);
842 }
843 
844 static void
touch_grab_frame(struct weston_touch_grab * grab)845 touch_grab_frame(struct weston_touch_grab *grab)
846 {
847     weston_touch_send_frame(grab->touch);
848 }
849 
850 static void
touch_grab_cancel(struct weston_touch_grab * grab)851 touch_grab_cancel(struct weston_touch_grab *grab)
852 {
853     struct seat_ctx *ctx_seat = wl_container_of(grab, ctx_seat, touch_grab);
854     input_ctrl_touch_clear_focus(ctx_seat);
855 }
856 
857 static struct weston_touch_grab_interface touch_grab_interface = {
858     touch_grab_down,
859     touch_grab_up,
860     touch_grab_motion,
861     touch_grab_frame,
862     touch_grab_cancel
863 };
864 
865 static uint32_t
get_seat_capabilities(struct weston_seat * seat)866 get_seat_capabilities(struct weston_seat *seat)
867 {
868     struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
869     struct weston_pointer *pointer = weston_seat_get_pointer(seat);
870     struct weston_touch *touch = weston_seat_get_touch(seat);
871     uint32_t caps = 0;
872 
873     if (keyboard != NULL)
874         caps |= ILM_INPUT_DEVICE_KEYBOARD;
875     if (pointer != NULL)
876         caps |= ILM_INPUT_DEVICE_POINTER;
877     if (touch != NULL)
878         caps |= ILM_INPUT_DEVICE_TOUCH;
879     return caps;
880 }
881 
882 static void
handle_seat_updated_caps(struct wl_listener * listener,void * data)883 handle_seat_updated_caps(struct wl_listener *listener, void *data)
884 {
885     struct weston_seat *seat = data;
886     struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
887     struct weston_pointer *pointer = weston_seat_get_pointer(seat);
888     struct weston_touch *touch = weston_seat_get_touch(seat);
889     struct seat_ctx *ctx = wl_container_of(listener, ctx,
890                                            updated_caps_listener);
891     struct input_context* input_ctx = ctx->input_ctx;
892     struct wl_resource *resource;
893 
894     if (keyboard && keyboard != ctx->keyboard_grab.keyboard) {
895         weston_keyboard_start_grab(keyboard, &ctx->keyboard_grab);
896     }
897     else if (!keyboard && ctx->keyboard_grab.keyboard) {
898         ctx->keyboard_grab.keyboard = NULL;
899     }
900 
901     if (pointer && pointer != ctx->pointer_grab.pointer) {
902         weston_pointer_start_grab(pointer, &ctx->pointer_grab);
903     }
904     else if (!pointer && ctx->pointer_grab.pointer) {
905         ctx->pointer_grab.pointer = NULL;
906     }
907 
908     if (touch && touch != ctx->touch_grab.touch) {
909         weston_touch_start_grab(touch, &ctx->touch_grab);
910     }
911     else if (!touch && ctx->touch_grab.touch) {
912         ctx->touch_grab.touch = NULL;
913     }
914 
915     wl_resource_for_each(resource, &input_ctx->resource_list) {
916         ivi_input_send_seat_capabilities(resource,
917                                          seat->seat_name,
918                                          get_seat_capabilities(seat));
919     }
920 }
921 
922 static void
destroy_seat(struct seat_ctx * ctx_seat)923 destroy_seat(struct seat_ctx *ctx_seat)
924 {
925     struct ivisurface *surf;
926     struct wl_resource *resource;
927     if (ctx_seat->keyboard_grab.keyboard) {
928     	keyboard_grab_cancel(&ctx_seat->keyboard_grab);
929         weston_keyboard_end_grab(ctx_seat->keyboard_grab.keyboard);
930     }
931     if (ctx_seat->pointer_grab.pointer) {
932     	pointer_grab_cancel(&ctx_seat->pointer_grab);
933         weston_pointer_end_grab(ctx_seat->pointer_grab.pointer);
934     }
935     if (ctx_seat->touch_grab.touch) {
936     	touch_grab_cancel(&ctx_seat->touch_grab);
937         weston_touch_end_grab(ctx_seat->touch_grab.touch);
938     }
939 
940     /* Remove seat acceptance from surfaces which have input acceptance from
941      * this seat */
942     wl_list_for_each(surf, &ctx_seat->input_ctx->ivishell->list_surface,
943                      link) {
944          remove_if_seat_accepted(surf, ctx_seat);
945     }
946 
947     wl_resource_for_each(resource, &ctx_seat->input_ctx->resource_list) {
948         ivi_input_send_seat_destroyed(resource,
949                                       ctx_seat->west_seat->seat_name);
950     }
951     wl_list_remove(&ctx_seat->destroy_listener.link);
952     wl_list_remove(&ctx_seat->updated_caps_listener.link);
953     wl_list_remove(&ctx_seat->seat_node);
954     free(ctx_seat);
955 }
956 
957 static void
handle_seat_destroy(struct wl_listener * listener,void * data)958 handle_seat_destroy(struct wl_listener *listener, void *data)
959 {
960     struct seat_ctx *ctx = wl_container_of(listener, ctx, destroy_listener);
961     destroy_seat(ctx);
962 }
963 
964 static void
handle_seat_create(struct wl_listener * listener,void * data)965 handle_seat_create(struct wl_listener *listener, void *data)
966 {
967     struct weston_seat *seat = data;
968     struct input_context *input_ctx = wl_container_of(listener, input_ctx,
969                                                       seat_create_listener);
970     struct wl_resource *resource;
971     struct ivisurface *surf;
972     const struct ivi_layout_interface *interface =
973         input_ctx->ivishell->interface;
974     struct seat_ctx *ctx = calloc(1, sizeof *ctx);
975     if (ctx == NULL) {
976         weston_log("%s: Failed to allocate memory\n", __FUNCTION__);
977         return;
978     }
979 
980     ctx->input_ctx = input_ctx;
981     ctx->west_seat = seat;
982 
983     ctx->keyboard_grab.interface = &keyboard_grab_interface;
984     ctx->pointer_grab.interface = &pointer_grab_interface;
985     ctx->touch_grab.interface= &touch_grab_interface;
986 
987     wl_list_insert(&input_ctx->seat_list, &ctx->seat_node);
988     ctx->destroy_listener.notify = &handle_seat_destroy;
989     wl_signal_add(&seat->destroy_signal, &ctx->destroy_listener);
990 
991     ctx->updated_caps_listener.notify = &handle_seat_updated_caps;
992     wl_signal_add(&seat->updated_caps_signal, &ctx->updated_caps_listener);
993 
994     wl_resource_for_each(resource, &input_ctx->resource_list) {
995         ivi_input_send_seat_created(resource,
996                                     seat->seat_name,
997                                     get_seat_capabilities(seat));
998     }
999 
1000     /* If default seat is created, we have to add it to the accepted_seat_list
1001      * of all surfaces. Also we have to send an acceptance event to all clients */
1002     if (!strcmp(ctx->west_seat->seat_name, "default")) {
1003         wl_list_for_each(surf, &input_ctx->ivishell->list_surface, link) {
1004             add_accepted_seat(surf, ctx);
1005             send_input_acceptance(input_ctx,
1006                                  interface->get_id_of_surface(surf->layout_surface),
1007                                  "default", ILM_TRUE);
1008         }
1009     }
1010 }
1011 
1012 static void
input_ctrl_free_surf_ctx(struct input_context * ctx,struct ivisurface * surf_ctx)1013 input_ctrl_free_surf_ctx(struct input_context *ctx, struct ivisurface *surf_ctx)
1014 {
1015     struct seat_ctx *seat_ctx;
1016     struct seat_focus *st_focus;
1017     struct seat_focus *tmp_st_focus;
1018 
1019     wl_list_for_each_safe(st_focus, tmp_st_focus,
1020             &surf_ctx->accepted_seat_list, link) {
1021         seat_ctx = st_focus->seat_ctx;
1022 
1023         if (seat_ctx->forced_ptr_focus_surf == surf_ctx)
1024             seat_ctx->forced_ptr_focus_surf = NULL;
1025 
1026         wl_list_remove(&st_focus->link);
1027         free(st_focus);
1028     }
1029 }
1030 
1031 static void
handle_surface_destroy(struct wl_listener * listener,void * data)1032 handle_surface_destroy(struct wl_listener *listener, void *data)
1033 {
1034     struct input_context *ctx =
1035             wl_container_of(listener, ctx, surface_destroyed);
1036     struct ivisurface *surf = (struct ivisurface *) data;
1037 
1038     if (NULL != surf)
1039         input_ctrl_free_surf_ctx(ctx, surf);
1040 }
1041 
1042 static void
handle_surface_create(struct wl_listener * listener,void * data)1043 handle_surface_create(struct wl_listener *listener, void *data)
1044 {
1045     struct input_context *input_ctx =
1046             wl_container_of(listener, input_ctx, surface_created);
1047     struct ivisurface *ivisurface = (struct ivisurface *) data;
1048     const struct ivi_layout_interface *interface =
1049         input_ctx->ivishell->interface;
1050     struct seat_ctx *seat_ctx;
1051 
1052     wl_list_init(&ivisurface->accepted_seat_list);
1053 
1054     seat_ctx = input_ctrl_get_seat_ctx(input_ctx, "default");
1055     if (seat_ctx) {
1056         add_accepted_seat(ivisurface, seat_ctx);
1057         send_input_acceptance(input_ctx,
1058                               interface->get_id_of_surface(ivisurface->layout_surface),
1059                               "default", ILM_TRUE);
1060     }
1061 }
1062 
1063 static void
unbind_resource_controller(struct wl_resource * resource)1064 unbind_resource_controller(struct wl_resource *resource)
1065 {
1066     wl_list_remove(wl_resource_get_link(resource));
1067 }
1068 
1069 static void
setup_input_focus(struct input_context * ctx,uint32_t surface,uint32_t device,int32_t enabled)1070 setup_input_focus(struct input_context *ctx, uint32_t surface,
1071         uint32_t device, int32_t enabled)
1072 {
1073     struct ivisurface *surf = NULL;
1074     struct seat_focus *st_focus;
1075     struct seat_ctx *ctx_seat;
1076 
1077     surf = input_ctrl_get_surf_ctx_from_id(ctx, surface);
1078     if (NULL != surf) {
1079         wl_list_for_each(st_focus, &surf->accepted_seat_list, link) {
1080             ctx_seat = st_focus->seat_ctx;
1081             if (device & ILM_INPUT_DEVICE_POINTER) {
1082                 input_ctrl_ptr_set_focus_surf(ctx_seat, surf, enabled);
1083             }
1084             if (device & ILM_INPUT_DEVICE_KEYBOARD) {
1085                 input_ctrl_kbd_set_focus_surf(ctx_seat, surf, enabled);
1086             }
1087             if (device & ILM_INPUT_DEVICE_TOUCH) {
1088                 /*Touch focus cannot be forced to a particular surface.
1089                  * Preserve the old behaviour by sending it to controller.
1090                  * TODO: Should we just remove focus setting for touch?*/
1091                 send_input_focus(ctx, surf, device, enabled);
1092             }
1093         }
1094     }
1095 }
1096 
1097 static void
set_focus(uint32_t surface,uint32_t device,int32_t enabled)1098 set_focus(uint32_t surface, uint32_t device, int32_t enabled)
1099 {
1100     weston_log("%{public}s surface: %{public}d device: %{public}d enabled: %{public}d",
1101         __FUNCTION__, surface, device, enabled);
1102     setup_input_focus(get_instance(), surface, device, enabled);
1103     weston_log("%{public}s end.", __FUNCTION__);
1104 }
1105 
1106 static void
input_set_input_focus(struct wl_client * client,struct wl_resource * resource,uint32_t surface,uint32_t device,int32_t enabled)1107 input_set_input_focus(struct wl_client *client,
1108                                  struct wl_resource *resource,
1109                                  uint32_t surface, uint32_t device,
1110                                  int32_t enabled)
1111 {
1112     struct input_context *ctx = wl_resource_get_user_data(resource);
1113     setup_input_focus(ctx, surface, device, enabled);
1114 }
1115 
1116 static void
setup_input_acceptance(struct input_context * ctx,uint32_t surface,const char * seat,int32_t accepted)1117 setup_input_acceptance(struct input_context *ctx,
1118                        uint32_t surface, const char *seat,
1119                        int32_t accepted)
1120 {
1121     struct ivisurface *ivisurface;
1122     struct seat_ctx *ctx_seat;
1123     struct weston_surface *w_surf;
1124     int found_seat = 0;
1125     const struct ivi_layout_interface *interface =
1126         ctx->ivishell->interface;
1127     struct weston_pointer *pointer;
1128     struct weston_touch *touch;
1129     struct weston_keyboard *keyboard;
1130     struct seat_focus *st_focus;
1131 
1132     ctx_seat = input_ctrl_get_seat_ctx(ctx, seat);
1133 
1134     if (NULL == ctx_seat) {
1135         weston_log("%s: seat: %s was not found\n", __FUNCTION__, seat);
1136         return;
1137     }
1138 
1139     ivisurface = input_ctrl_get_surf_ctx_from_id(ctx, surface);
1140 
1141     if (NULL != ivisurface) {
1142         if (accepted == ILM_TRUE) {
1143             found_seat = add_accepted_seat(ivisurface, ctx_seat);
1144 
1145             pointer = weston_seat_get_pointer(ctx_seat->west_seat);
1146             if (NULL != pointer) {
1147                 /*if seat is having NULL pointer focus, now it may be
1148                  * possible that this surface can hold the focus as it
1149                  * accepts events from that seat*/
1150                 if (input_ctrl_ptr_is_focus_emtpy(ctx_seat)) {
1151                     pointer->grab->interface->focus(pointer->grab);
1152                 }
1153             }
1154         } else {
1155             st_focus = get_accepted_seat(ivisurface, ctx_seat);
1156 
1157             if (NULL != st_focus) {
1158                 w_surf = interface->surface_get_weston_surface(ivisurface->
1159                                                                layout_surface);
1160 
1161                 pointer = weston_seat_get_pointer(ctx_seat->west_seat);
1162                 if (NULL != pointer) {
1163                     if ((st_focus->focus & ILM_INPUT_DEVICE_POINTER)
1164                             == ILM_INPUT_DEVICE_POINTER) {
1165                         input_ctrl_ptr_clear_focus(ctx_seat);
1166                     }
1167                 }
1168                 touch = weston_seat_get_touch(ctx_seat->west_seat);
1169                 if (NULL != touch) {
1170                     if ((st_focus->focus & ILM_INPUT_DEVICE_TOUCH)
1171                             == ILM_INPUT_DEVICE_TOUCH) {
1172                         input_ctrl_touch_clear_focus(ctx_seat);
1173                     }
1174                 }
1175                 keyboard = weston_seat_get_keyboard(ctx_seat->west_seat);
1176 
1177                 if (NULL != keyboard) {
1178                     if ((st_focus->focus & ILM_INPUT_DEVICE_KEYBOARD)
1179                             == ILM_INPUT_DEVICE_KEYBOARD) {
1180                         input_ctrl_kbd_leave_surf(ctx_seat,
1181                                 ivisurface, w_surf);
1182                     }
1183                 }
1184 
1185                 found_seat = remove_if_seat_accepted(ivisurface, ctx_seat);
1186             }
1187         }
1188     }
1189 
1190     if (found_seat)
1191         send_input_acceptance(ctx, surface, seat, accepted);
1192 }
1193 
1194 static void
input_set_input_acceptance(struct wl_client * client,struct wl_resource * resource,uint32_t surface,const char * seat,int32_t accepted)1195 input_set_input_acceptance(struct wl_client *client,
1196                                       struct wl_resource *resource,
1197                                       uint32_t surface, const char *seat,
1198                                       int32_t accepted)
1199 {
1200     struct input_context *ctx = wl_resource_get_user_data(resource);
1201     setup_input_acceptance(ctx, surface, seat, accepted);
1202 }
1203 
1204 static const struct ivi_input_interface input_implementation = {
1205     input_set_input_focus,
1206     input_set_input_acceptance
1207 };
1208 
1209 static void
bind_ivi_input(struct wl_client * client,void * data,uint32_t version,uint32_t id)1210 bind_ivi_input(struct wl_client *client, void *data,
1211                uint32_t version, uint32_t id)
1212 {
1213     struct input_context *ctx = data;
1214     struct weston_seat *seat;
1215     struct wl_resource *resource;
1216     struct ivisurface *ivisurface;
1217     const struct ivi_layout_interface *interface =
1218         ctx->ivishell->interface;
1219     struct seat_focus *st_focus;
1220     uint32_t ivi_surf_id;
1221 
1222     resource = wl_resource_create(client, &ivi_input_interface, 1, id);
1223     wl_resource_set_implementation(resource, &input_implementation,
1224                                    ctx, unbind_resource_controller);
1225 
1226     wl_list_insert(&ctx->resource_list, wl_resource_get_link(resource));
1227 
1228     /* Send seat events for all known seats to the client */
1229     wl_list_for_each(seat, &ctx->ivishell->compositor->seat_list, link) {
1230         ivi_input_send_seat_created(resource, seat->seat_name,
1231                                     get_seat_capabilities(seat));
1232     }
1233     /* Send focus and acceptance events for all known surfaces to the client */
1234     wl_list_for_each(ivisurface, &ctx->ivishell->list_surface, link) {
1235         ivi_surf_id = interface->get_id_of_surface(ivisurface->layout_surface);
1236         wl_list_for_each(st_focus, &ivisurface->accepted_seat_list, link) {
1237             ivi_input_send_input_focus(resource, ivi_surf_id,
1238                                        st_focus->focus, ILM_TRUE);
1239             ivi_input_send_input_acceptance(resource, ivi_surf_id,
1240                                             st_focus->seat_ctx->west_seat->seat_name,
1241                                             ILM_TRUE);
1242         }
1243     }
1244 }
1245 
1246 static void
destroy_input_context(struct input_context * ctx)1247 destroy_input_context(struct input_context *ctx)
1248 {
1249     struct seat_ctx *seat;
1250     struct seat_ctx *tmp;
1251     struct ivisurface *surf_ctx;
1252     struct ivisurface *tmp_surf_ctx;
1253     struct wl_resource *resource, *tmp_resource;
1254 
1255     wl_list_for_each_safe(seat, tmp, &ctx->seat_list, seat_node) {
1256         destroy_seat(seat);
1257     }
1258 
1259     wl_list_for_each_safe(surf_ctx, tmp_surf_ctx,
1260             &ctx->ivishell->list_surface, link) {
1261         input_ctrl_free_surf_ctx(ctx, surf_ctx);
1262     }
1263 
1264     wl_list_remove(&ctx->seat_create_listener.link);
1265     wl_list_remove(&ctx->surface_created.link);
1266     wl_list_remove(&ctx->surface_destroyed.link);
1267     wl_list_remove(&ctx->compositor_destroy_listener.link);
1268 
1269     wl_resource_for_each_safe(resource, tmp_resource, &ctx->resource_list) {
1270         /*We have set destroy function for this resource.
1271          * The below api will call unbind_resource_controller and
1272          * free up the controller structure*/
1273         wl_resource_destroy(resource);
1274     }
1275     free(ctx);
1276 }
1277 
1278 static void
input_controller_deinit(struct input_context * ctx)1279 input_controller_deinit(struct input_context *ctx)
1280 {
1281     int deinit_stage;
1282 
1283     if (NULL == ctx) {
1284         return;
1285     }
1286 
1287     for (deinit_stage = ctx->successful_init_stage; deinit_stage >= 0;
1288             deinit_stage--) {
1289         switch (deinit_stage) {
1290         case 1:
1291             /*Nothing to free for this stage*/
1292             break;
1293 
1294         case 0:
1295             destroy_input_context(ctx);
1296             break;
1297 
1298         default:
1299             break;
1300         }
1301     }
1302 }
1303 
1304 static void
input_controller_destroy(struct wl_listener * listener,void * data)1305 input_controller_destroy(struct wl_listener *listener, void *data)
1306 {
1307     (void)data;
1308     if (NULL != listener) {
1309         struct input_context *ctx = wl_container_of(listener,
1310                 ctx, compositor_destroy_listener);
1311 
1312         input_controller_deinit(ctx);
1313     }
1314 }
1315 
1316 
1317 static struct input_context *
create_input_context(struct ivishell * shell)1318 create_input_context(struct ivishell *shell)
1319 {
1320     struct input_context *ctx = get_instance();
1321     struct weston_seat *seat;
1322 
1323     ctx->ivishell = shell;
1324     wl_list_init(&ctx->resource_list);
1325     wl_list_init(&ctx->seat_list);
1326 
1327     /* Add signal handlers for ivi surfaces. */
1328     ctx->surface_created.notify = handle_surface_create;
1329     ctx->surface_destroyed.notify = handle_surface_destroy;
1330     ctx->compositor_destroy_listener.notify = input_controller_destroy;
1331 
1332     wl_signal_add(&ctx->ivishell->ivisurface_created_signal, &ctx->surface_created);
1333     wl_signal_add(&ctx->ivishell->ivisurface_removed_signal, &ctx->surface_destroyed);
1334     wl_signal_add(&ctx->ivishell->compositor->destroy_signal, &ctx->compositor_destroy_listener);
1335 
1336     ctx->seat_create_listener.notify = &handle_seat_create;
1337     wl_signal_add(&ctx->ivishell->compositor->seat_created_signal, &ctx->seat_create_listener);
1338 
1339     wl_list_for_each(seat, &ctx->ivishell->compositor->seat_list, link) {
1340         handle_seat_create(&ctx->seat_create_listener, seat);
1341         wl_signal_emit(&seat->updated_caps_signal, seat);
1342     }
1343 
1344     return ctx;
1345 }
1346 
1347 static int
input_controller_init(struct ivishell * shell)1348 input_controller_init(struct ivishell *shell)
1349 {
1350     int successful_init_stage = 0;
1351     int init_stage;
1352     int ret = -1;
1353     struct input_context *ctx = NULL;
1354     bool init_success = false;
1355 
1356     for (init_stage = 0; init_stage == successful_init_stage;
1357             init_stage++) {
1358         switch(init_stage)
1359         {
1360         case 0:
1361             ctx = create_input_context(shell);
1362             if (NULL != ctx)
1363                 successful_init_stage++;
1364             break;
1365         case 1:
1366             if (wl_global_create(shell->compositor->wl_display, &ivi_input_interface, 1,
1367                                  ctx, bind_ivi_input) != NULL) {
1368                 successful_init_stage++;
1369             }
1370             break;
1371         default:
1372             init_success = true;
1373             break;
1374         }
1375 
1376     }
1377     if (NULL != ctx) {
1378          ctx->successful_init_stage = (successful_init_stage - 1);
1379          ret = 0;
1380          if (!init_success) {
1381              weston_log("Initialization failed at stage: %d\n",\
1382                      successful_init_stage);
1383              input_controller_deinit(ctx);
1384              ret = -1;
1385          }
1386     }
1387     return ret;
1388 }
1389 
1390 static struct ivi_input_interface_for_wms ivi_input_interface_for_wms = {
1391     .set_focus = set_focus,
1392 };
1393 
1394 WL_EXPORT int
input_controller_module_init(struct ivishell * shell)1395 input_controller_module_init(struct ivishell *shell)
1396 {
1397     int ret = -1;
1398 
1399     if (NULL != shell->interface) {
1400         ret = input_controller_init(shell);
1401 
1402         if (ret >= 0)
1403             weston_log("ivi-input-controller module loaded successfully!\n");
1404     }
1405 
1406     weston_plugin_api_register(shell->compositor,
1407         IVI_INPUT_API_NAME_FOR_WMS,
1408         &ivi_input_interface_for_wms,
1409         sizeof(struct ivi_input_interface_for_wms));
1410     return ret;
1411 }
1412 
1413