1 /**************************************************************************
2 *
3 * Copyright 2015 Codethink Ltd
4 * Copyright (C) 2015 Advanced Driver Information Technology Joint Venture GmbH
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ****************************************************************************/
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "ivi-input-client-protocol.h"
25 #include "ilm_input.h"
26 #include "ilm_control_platform.h"
27
28 extern struct ilm_control_context ilm_context;
29
30 ILM_EXPORT ilmErrorTypes
ilm_setInputAcceptanceOn(t_ilm_surface surfaceID,t_ilm_uint num_seats,t_ilm_string * seats)31 ilm_setInputAcceptanceOn(t_ilm_surface surfaceID, t_ilm_uint num_seats,
32 t_ilm_string *seats)
33 {
34 struct ilm_control_context *ctx;
35 t_ilm_uint i;
36 struct surface_context *surface_ctx = NULL;
37 struct accepted_seat *accepted_seat;
38 struct seat_context *seat;
39 int surface_found = 0;
40 int seat_found = 0;
41
42 if ((seats == NULL) && (num_seats != 0)) {
43 fprintf(stderr, "Invalid Argument\n");
44 return ILM_FAILED;
45 }
46
47 ctx = sync_and_acquire_instance();
48
49 wl_list_for_each(surface_ctx, &ctx->wl.list_surface, link) {
50 if (surface_ctx->id_surface == surfaceID) {
51 surface_found = 1;
52 break;
53 }
54 }
55
56 if (!surface_found) {
57 fprintf(stderr, "surface ID %d not found\n", surfaceID);
58 release_instance();
59 return ILM_FAILED;
60 }
61
62 for(i = 0; i < num_seats; i++) {
63 wl_list_for_each(seat, &ctx->wl.list_seat, link) {
64 if (strcmp(seat->seat_name, seats[i]) == 0)
65 seat_found = 1;
66 }
67
68 if (!seat_found) {
69 fprintf(stderr, "seat: %s not found\n", seats[i]);
70 release_instance();
71 return ILM_FAILED;
72 }
73
74 seat_found = 0;
75 }
76 /* Send events to add input acceptance for every seat in 'seats', but
77 * not on the surface's list */
78 for(i = 0; i < num_seats; i++) {
79 int has_seat = 0;
80
81 wl_list_for_each(accepted_seat, &surface_ctx->list_accepted_seats,
82 link) {
83 if (strcmp(accepted_seat->seat_name, seats[i]) == 0)
84 has_seat = 1;
85 }
86
87 if (!has_seat) {
88 ivi_input_set_input_acceptance(ctx->wl.input_controller,
89 surfaceID, seats[i],
90 ILM_TRUE);
91 }
92 }
93
94 /* Send events to remove input acceptance for every seat on the surface's
95 * list but not in 'seats' */
96 wl_list_for_each(accepted_seat, &surface_ctx->list_accepted_seats, link) {
97 int has_seat = 0;
98 for (i = 0; i < num_seats; i++) {
99 if (strcmp(accepted_seat->seat_name, seats[i]) == 0)
100 has_seat = 1;
101 }
102 if (!has_seat)
103 ivi_input_set_input_acceptance(ctx->wl.input_controller,
104 surfaceID,
105 accepted_seat->seat_name,
106 ILM_FALSE);
107 }
108
109 release_instance();
110 return ILM_SUCCESS;
111 }
112
113 ILM_EXPORT ilmErrorTypes
ilm_getInputAcceptanceOn(t_ilm_surface surfaceID,t_ilm_uint * num_seats,t_ilm_string ** seats)114 ilm_getInputAcceptanceOn(t_ilm_surface surfaceID, t_ilm_uint *num_seats,
115 t_ilm_string **seats)
116 {
117 struct ilm_control_context *ctx;
118 struct surface_context *surface_ctx;
119 struct accepted_seat *accepted_seat;
120 int surface_found = 0;
121 int i;
122
123 if ((seats == NULL) || (num_seats == NULL)) {
124 fprintf(stderr, "Invalid Argument\n");
125 return ILM_FAILED;
126 }
127
128 ctx = sync_and_acquire_instance();
129
130 wl_list_for_each(surface_ctx, &ctx->wl.list_surface, link) {
131 if (surface_ctx->id_surface == surfaceID) {
132 surface_found = 1;
133 break;
134 }
135 }
136
137 if (!surface_found) {
138 fprintf(stderr, "Surface ID %d not found\n", surfaceID);
139 release_instance();
140 return ILM_FAILED;
141 }
142
143 *num_seats = wl_list_length(&surface_ctx->list_accepted_seats);
144 *seats = calloc(*num_seats, sizeof **seats);
145 if (*seats == NULL) {
146 fprintf(stderr, "Failed to allocate memory for seat array\n");
147 release_instance();
148 return ILM_FAILED;
149 }
150
151 i = 0;
152 wl_list_for_each(accepted_seat, &surface_ctx->list_accepted_seats, link) {
153 (*seats)[i] = strdup(accepted_seat->seat_name);
154 if ((*seats)[i] == NULL) {
155 int j;
156 fprintf(stderr, "Failed to copy seat name %s\n",
157 accepted_seat->seat_name);
158 release_instance();
159 for (j = 0; j < i; j++)
160 free((*seats)[j]);
161 free(*seats);
162 *seats = NULL;
163 *num_seats = 0;
164 return ILM_FAILED;
165 }
166 i++;
167 }
168
169 release_instance();
170 return ILM_SUCCESS;
171 }
172
173 ILM_EXPORT ilmErrorTypes
ilm_getInputDevices(ilmInputDevice bitmask,t_ilm_uint * num_seats,t_ilm_string ** seats)174 ilm_getInputDevices(ilmInputDevice bitmask, t_ilm_uint *num_seats,
175 t_ilm_string **seats)
176 {
177 ilmErrorTypes returnValue = ILM_FAILED;
178 struct ilm_control_context *ctx;
179 struct seat_context *seat;
180 int max_seats;
181 int seats_added = 0;
182
183 if ((seats == NULL) || (num_seats == NULL)) {
184 fprintf(stderr, "Invalid Argument\n");
185 return ILM_FAILED;
186 }
187
188 ctx = sync_and_acquire_instance();
189 max_seats = wl_list_length(&ctx->wl.list_seat);
190 *seats = calloc(max_seats, sizeof **seats);
191
192 if (*seats == NULL) {
193 fprintf(stderr, "Failed to allocate memory for input device list\n");
194 release_instance();
195 return ILM_FAILED;
196 }
197
198 wl_list_for_each(seat, &ctx->wl.list_seat, link) {
199 returnValue = ILM_SUCCESS;
200
201 if ((seat->capabilities & bitmask) == 0)
202 continue;
203
204 (*seats)[seats_added] = strdup(seat->seat_name);
205 if ((*seats)[seats_added] == NULL) {
206 int j;
207 fprintf(stderr, "Failed to duplicate seat name %s\n",
208 seat->seat_name);
209 for (j = 0; j < seats_added; j++)
210 free((*seats)[j]);
211 free(*seats);
212 *seats = NULL;
213 returnValue = ILM_FAILED;
214 break;
215 }
216
217 seats_added++;
218 }
219 *num_seats = seats_added;
220 release_instance();
221 return returnValue;
222 }
223
224 ILM_EXPORT ilmErrorTypes
ilm_getInputDeviceCapabilities(t_ilm_string seat_name,ilmInputDevice * bitmask)225 ilm_getInputDeviceCapabilities(t_ilm_string seat_name, ilmInputDevice *bitmask)
226 {
227 ilmErrorTypes returnValue = ILM_FAILED;
228 struct ilm_control_context *ctx;
229 struct seat_context *seat;
230
231 if ((seat_name == NULL) || (bitmask == NULL)) {
232 fprintf(stderr, "Invalid Argument\n");
233 return ILM_FAILED;
234 }
235
236 ctx = sync_and_acquire_instance();
237 wl_list_for_each(seat, &ctx->wl.list_seat, link) {
238 if (strcmp(seat_name, seat->seat_name) == 0) {
239 *bitmask = seat->capabilities;
240 returnValue = ILM_SUCCESS;
241 }
242 }
243
244 release_instance();
245 return returnValue;
246 }
247
248 ILM_EXPORT ilmErrorTypes
ilm_setInputFocus(t_ilm_surface * surfaceIDs,t_ilm_uint num_surfaces,ilmInputDevice bitmask,t_ilm_bool is_set)249 ilm_setInputFocus(t_ilm_surface *surfaceIDs, t_ilm_uint num_surfaces,
250 ilmInputDevice bitmask, t_ilm_bool is_set)
251 {
252 ilmErrorTypes returnValue = ILM_FAILED;
253 struct ilm_control_context *ctx;
254 t_ilm_uint i;
255
256 if (surfaceIDs == NULL) {
257 fprintf(stderr, "Invalid Argument\n");
258 return ILM_FAILED;
259 }
260
261 if (bitmask & (ILM_INPUT_DEVICE_POINTER | ILM_INPUT_DEVICE_TOUCH)
262 && num_surfaces > 1 && is_set == ILM_TRUE) {
263 fprintf(stderr,
264 "Cannot set pointer or touch focus for multiple surfaces\n");
265 release_instance();
266 return ILM_FAILED;
267 }
268
269 ctx = sync_and_acquire_instance();
270 for (i = 0; i < num_surfaces; i++) {
271 struct surface_context *ctx_surf;
272 int found_surface = 0;
273 wl_list_for_each(ctx_surf, &ctx->wl.list_surface, link) {
274 if (ctx_surf->id_surface == surfaceIDs[i]) {
275 found_surface = 1;
276 break;
277 }
278 }
279
280 if (!found_surface) {
281 fprintf(stderr, "Surface %d was not found\n", surfaceIDs[i]);
282 break;
283 }
284
285 ivi_input_set_input_focus(ctx->wl.input_controller,
286 ctx_surf->id_surface,
287 bitmask, is_set);
288 returnValue = ILM_SUCCESS;
289 }
290 release_instance();
291 return returnValue;
292 }
293
294 ILM_EXPORT ilmErrorTypes
ilm_getInputFocus(t_ilm_surface ** surfaceIDs,ilmInputDevice ** bitmasks,t_ilm_uint * num_ids)295 ilm_getInputFocus(t_ilm_surface **surfaceIDs, ilmInputDevice **bitmasks,
296 t_ilm_uint *num_ids)
297 {
298 struct ilm_control_context *ctx;
299 int i = 0;
300 struct surface_context *ctx_surf;
301
302 if ((surfaceIDs == NULL) || (bitmasks == NULL)
303 ||(num_ids == NULL)) {
304 fprintf(stderr, "Invalid Argument\n");
305 return ILM_FAILED;
306 }
307
308 ctx = sync_and_acquire_instance();
309 *num_ids = wl_list_length(&ctx->wl.list_surface);
310 *surfaceIDs = calloc(*num_ids, sizeof **surfaceIDs);
311
312 if (*surfaceIDs == NULL) {
313 fprintf(stderr, "Failed to allocate memory for surface ID list\n");
314 release_instance();
315 return ILM_FAILED;
316 }
317
318 *bitmasks = calloc(*num_ids, sizeof **bitmasks);
319 if (*bitmasks == NULL) {
320 fprintf(stderr, "Failed to allocate memory for bitmask list\n");
321 free(*surfaceIDs);
322 release_instance();
323 return ILM_FAILED;
324 }
325
326 wl_list_for_each(ctx_surf, &ctx->wl.list_surface, link) {
327 (*surfaceIDs)[i] = ctx_surf->id_surface;
328 (*bitmasks)[i] = ctx_surf->prop.focus;
329 i++;
330 }
331
332 release_instance();
333 return ILM_SUCCESS;
334
335 }
336