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