blob: 6c734a44a9af742600afd87318f0f528de5e2ca8 [file] [log] [blame]
leng.fangdbaf6fa2024-06-20 19:31:04 +08001/*
2 * If not stated otherwise in this file or this component's Licenses.txt file the
3 * following copyright and licenses apply:
4 *
5 * Copyright 2016 RDK Management
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19#include <stdlib.h>
20#include <stdio.h>
21#include <memory.h>
22#include <sys/time.h>
23
24#include "weston-simpleshell.h"
25#include "aml-weston/aml-simpleshell.h"
26#include <libweston/zalloc.h>
27#include <shared/helpers.h>
28
29#include "wayland-server.h"
30#include "simpleshell-server-protocol.h"
31
32#define WST_UNUSED( n ) ((void)n)
33
34#define MIN(x,y) (((x) < (y)) ? (x) : (y))
35
36#define DEFAULT_NAME "noname"
37#define BROADCAST_DELAY (2000)
38
39static void destroy_shell(struct wl_resource *resource);
40static void wstSimpleShellBroadcastCreation( struct wl_simple_shell *shell, uint32_t surfaceId );
41
42struct shell_info
43{
44 struct wl_client *client;
45 struct wl_resource *resource;
46 struct wl_list link;
47};
48
49struct pending_broadcast_info
50{
51 uint32_t surfaceId;
52 long long creationTime;
53 struct wl_list link;
54};
55
56struct simple_shell_surface_id {
57 uint32_t surfaceId;
58 struct wl_list link;
59};
60
61struct wl_simple_shell
62{
63 struct wl_display *display;
64 struct wl_global *wl_simple_shell_global;
65 struct wayland_simple_shell_callbacks *callbacks;
66 void *userData;
67 struct wl_event_source *delayTimer;
68 struct wl_list shells;
69 struct wl_list surfaces;
70 struct wl_list pendingCreateBroadcast;
71 struct wl_listener create_surface_listener;
72};
73
74struct simple_shell_destroy_info {
75 struct wl_simple_shell *shell;
76 struct wl_listener destroy_surface_listener;
77};
78
79static long long getCurrentTimeMillis()
80{
81 struct timeval tv;
82 long long utcCurrentTimeMillis;
83
84 gettimeofday(&tv,0);
85 utcCurrentTimeMillis= tv.tv_sec*1000LL+(tv.tv_usec/1000LL);
86
87 return utcCurrentTimeMillis;
88}
89
90static void wstISimpleShellSetName(struct wl_client *client, struct wl_resource *resource,
91 uint32_t surfaceId, const char *name);
92static void wstISimpleShellSetVisible(struct wl_client *client, struct wl_resource *resource,
93 uint32_t surfaceId, uint32_t visible);
94static void wstISimpleShellSetGeometry(struct wl_client *client, struct wl_resource *resource,
95 uint32_t surfaceId, int32_t x, int32_t y, int32_t width, int32_t height);
96static void wstISimpleShellSetOpacity(struct wl_client *client, struct wl_resource *resource,
97 uint32_t surfaceId, wl_fixed_t opacity);
98static void wstISimpleShellSetZOrder(struct wl_client *client, struct wl_resource *resource,
99 uint32_t surfaceId, wl_fixed_t zorder);
100static void wstISimpleShellGetStatus(struct wl_client *client, struct wl_resource *resource, uint32_t surface);
101static void wstISimpleShellGetSurfaces(struct wl_client *client, struct wl_resource *resource);
102static void wstISimpleShellSetFocus(struct wl_client *client, struct wl_resource *resource,
103 uint32_t surfaceId);
104static void wstISimpleShellSetScale(struct wl_client *client, struct wl_resource *resource,
105 uint32_t surfaceId, wl_fixed_t scaleX, wl_fixed_t scaleY);
106static void wstISimpleShellSetKeyIntercept(struct wl_client * client, struct wl_resource * resource,
107 uint32_t surfaceId, uint32_t keyCode, uint32_t modifiers);
108static void wstISimpleShellSetMultiKeyIntercept(struct wl_client * client, struct wl_resource * resource,
109 uint32_t surfaceId, struct wl_array * keyCode, struct wl_array * modifiers);
110static void wstISimpleShellRemoveMultiKeyIntercept(struct wl_client * client, struct wl_resource * resource,
111 uint32_t surfaceId, struct wl_array * keyCode, struct wl_array * modifiers);
112static void wstISimpleShellApplyAppsZorder(struct wl_client * client, struct wl_resource * resource,
113 struct wl_array * appList);
114static void wstISimpleShellSendMultiKey(struct wl_client * client, struct wl_resource * resource,
115 uint32_t surfaceId, struct wl_array * keyCode, struct wl_array * modifiers);
116
117
118const static struct wl_simple_shell_interface simple_shell_interface = {
119 wstISimpleShellSetName,
120 wstISimpleShellSetVisible,
121 wstISimpleShellSetGeometry,
122 wstISimpleShellSetOpacity,
123 wstISimpleShellSetZOrder,
124 wstISimpleShellGetStatus,
125 wstISimpleShellGetSurfaces,
126 wstISimpleShellSetFocus,
127 wstISimpleShellSetScale,
128 wstISimpleShellSetKeyIntercept,
129 wstISimpleShellSetMultiKeyIntercept,
130 wstISimpleShellRemoveMultiKeyIntercept,
131 wstISimpleShellApplyAppsZorder,
132 wstISimpleShellSendMultiKey
133};
134
135static void wstSimpleShellBroadcastSurfaceUpdate(struct wl_client *client,
136 struct wl_simple_shell *shell, uint32_t surfaceId )
137{
138 const char *name= 0;
139
140 bool visible;
141 int x, y, width, height;
142 float opacity, zorder;
143 wl_fixed_t fixedOpacity, fixedZOrder;
144 struct shell_info *info, *tmp;
145
146 if (!client || !shell || !shell->callbacks)
147 return;
148
149 if (shell->callbacks->get_name)
150 shell->callbacks->get_name( shell->userData, surfaceId, &name );
151 if ( !name )
152 name= (const char *)DEFAULT_NAME;
153
154 if (shell->callbacks->get_status) {
155 shell->callbacks->get_status( shell->userData, surfaceId,
156 &visible,
157 &x, &y, &width, &height,
158 &opacity, &zorder );
159
160 fixedOpacity= wl_fixed_from_double( (double)opacity );
161 fixedZOrder= wl_fixed_from_double( (double)zorder );
162
163 // Broadcast the surface update announcement to all other clients.
164 wl_list_for_each_safe(info, tmp, &shell->shells, link) {
165 if (info->client != client) {
166 wl_simple_shell_send_surface_status(info->resource, surfaceId,
167 name, (visible ? 1 : 0),
168 x, y, width, height, fixedOpacity, fixedZOrder);
169 }
170 }
171 }
172}
173
174static void wstISimpleShellSetName(struct wl_client *client,
175 struct wl_resource *resource,
176 uint32_t surfaceId, const char *name)
177{
178 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
179 struct pending_broadcast_info *info, *tmp;
180
181 if ( shell ) {
182 if (shell->callbacks && shell->callbacks->set_name)
183 shell->callbacks->set_name( shell->userData, surfaceId, name );
184
185 wl_list_for_each_safe(info, tmp, &shell->pendingCreateBroadcast, link) {
186 if (info->surfaceId == surfaceId) {
187 wl_list_remove(&info->link);
188 free(info);
189 wstSimpleShellBroadcastCreation( shell, surfaceId );
190 break;
191 }
192 }
193
194 wstSimpleShellBroadcastSurfaceUpdate(client, shell, surfaceId );
195 }
196}
197
198static void wstISimpleShellSetVisible(struct wl_client *client,
199 struct wl_resource *resource,
200 uint32_t surfaceId, uint32_t visible)
201{
202 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
203
204 if ( shell ) {
205 if (shell->callbacks && shell->callbacks->set_visible)
206 shell->callbacks->set_visible( shell->userData, surfaceId, (visible != 0) );
207
208 wstSimpleShellBroadcastSurfaceUpdate(client, shell, surfaceId );
209 }
210}
211
212static void wstISimpleShellSetGeometry(struct wl_client *client,
213 struct wl_resource *resource,
214 uint32_t surfaceId,
215 int32_t x, int32_t y, int32_t width, int32_t height)
216{
217 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
218
219 if ( shell ) {
220 if (shell->callbacks && shell->callbacks->set_geometry)
221 shell->callbacks->set_geometry( shell->userData, surfaceId,
222 x, y, width, height );
223
224 wstSimpleShellBroadcastSurfaceUpdate(client, shell, surfaceId );
225 }
226}
227
228static void wstISimpleShellSetOpacity(struct wl_client *client,
229 struct wl_resource *resource,
230 uint32_t surfaceId,
231 wl_fixed_t opacity)
232{
233 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
234 if ( shell ) {
235 float opacityLevel= wl_fixed_to_double( opacity );
236
237 if ( opacityLevel < 0.0 ) opacityLevel= 0.0;
238 if ( opacityLevel > 1.0 ) opacityLevel= 1.0;
239
240 if (shell->callbacks && shell->callbacks->set_opacity)
241 shell->callbacks->set_opacity( shell->userData, surfaceId, opacityLevel );
242
243 wstSimpleShellBroadcastSurfaceUpdate(client, shell, surfaceId );
244 }
245}
246
247static void wstISimpleShellSetZOrder(struct wl_client *client,
248 struct wl_resource *resource,
249 uint32_t surfaceId,
250 wl_fixed_t zorder)
251{
252 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
253 if ( shell ) {
254 float zOrderLevel= wl_fixed_to_double( zorder );
255
256 if ( zOrderLevel < 0.0 ) zOrderLevel= 0.0;
257 if ( zOrderLevel > 1.0 ) zOrderLevel= 1.0;
258
259 if (shell->callbacks && shell->callbacks->set_zorder)
260 shell->callbacks->set_zorder( shell->userData, surfaceId, zOrderLevel );
261
262 wstSimpleShellBroadcastSurfaceUpdate(client, shell, surfaceId );
263 }
264}
265
266static void wstISimpleShellGetStatus(struct wl_client *client, struct wl_resource *resource, uint32_t surfaceId )
267{
268 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
269 if ( shell ) {
270 const char *name= 0;
271 bool visible;
272 int x, y, width = 0, height = 0;
273 float opacity, zorder;
274 wl_fixed_t fixedOpacity, fixedZOrder;
275
276 if (shell->callbacks && shell->callbacks->get_name)
277 shell->callbacks->get_name( shell->userData, surfaceId, &name );
278 if ( !name )
279 name= (const char *)DEFAULT_NAME;
280
281 if (shell->callbacks && shell->callbacks->get_status) {
282 shell->callbacks->get_status( shell->userData, surfaceId,
283 &visible,
284 &x, &y, &width, &height,
285 &opacity, &zorder );
286
287 if (width == 0 && height == 0)
288 return;
289
290 fixedOpacity= wl_fixed_from_double( (double)opacity );
291 fixedZOrder= wl_fixed_from_double( (double)zorder );
292
293 wl_simple_shell_send_surface_status( resource, surfaceId,
294 name, (visible ? 1 : 0),
295 x, y, width, height, fixedOpacity, fixedZOrder );
296 }
297 }
298}
299
300static void wstISimpleShellGetSurfaces(struct wl_client *client, struct wl_resource *resource)
301{
302 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
303 struct simple_shell_surface_id *surface_id, *tmp;
304
305 if ( shell ) {
306 wl_list_for_each_safe(surface_id, tmp, &shell->surfaces, link)
307 wstISimpleShellGetStatus(client, resource, surface_id->surfaceId );
308
309 wl_simple_shell_send_get_surfaces_done( resource );
310 }
311}
312
313static void wstISimpleShellSetFocus(struct wl_client *client, struct wl_resource *resource,
314 uint32_t surfaceId)
315{
316 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
317 if (shell && shell->callbacks && shell->callbacks->set_focus)
318 shell->callbacks->set_focus(shell->userData, surfaceId);
319}
320
321static void wstISimpleShellSetScale(struct wl_client *client, struct wl_resource *resource,
322 uint32_t surfaceId, wl_fixed_t scaleX, wl_fixed_t scaleY)
323{
324 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
325 float fScaleX= wl_fixed_to_double(scaleX);
326 float fScaleY= wl_fixed_to_double(scaleY);
327
328 weston_log("weston-simpleshell: wstSimpleShellSetScale: surfaceId %u scaleX %f scaleY %f\n",
329 surfaceId, fScaleX, fScaleY);
330 if (shell && shell->callbacks && shell->callbacks->set_scale)
331 shell->callbacks->set_scale(shell->userData, surfaceId, fScaleX, fScaleY);
332}
333
334static void wstISimpleShellSetKeyIntercept(struct wl_client * client, struct wl_resource * resource,
335 uint32_t surfaceId, uint32_t keyCode, uint32_t modifiers) {
336 weston_log("intercept key keycode:%d, surfaceId %d, modifiers %d\n", keyCode, surfaceId, modifiers);
337 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
338 if (shell && shell->callbacks)
339 shell->callbacks->set_key_intercept(shell->userData, surfaceId, keyCode, modifiers);
340}
341
342static void
343wstISimpleShellSetMultiKeyIntercept(struct wl_client * client,
344 struct wl_resource * resource,
345 uint32_t surfaceId,
346 struct wl_array * keyCode,
347 struct wl_array * modifiers)
348{
349 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
350 size_t size;
351 uint32_t *key_code, *modifier;
352
353 if (!keyCode || !modifiers || keyCode->size != modifiers->size)
354 return;
355
356 size = keyCode->size / sizeof(uint32_t);
357 key_code = (uint32_t *)keyCode->data;
358 modifier = (uint32_t *)modifiers->data;
359 if (shell && shell->callbacks && shell->callbacks->set_key_intercept) {
360 while (size--) {
361 shell->callbacks->set_key_intercept(shell->userData, surfaceId, *key_code, *modifier);
362 key_code++;
363 modifier++;
364 }
365 }
366}
367
368static void
369wstISimpleShellRemoveMultiKeyIntercept(struct wl_client * client,
370 struct wl_resource * resource,
371 uint32_t surfaceId,
372 struct wl_array * keyCode,
373 struct wl_array * modifiers)
374{
375 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
376 size_t size;
377 uint32_t *key_code, *modifier;
378
379 if (!keyCode || !modifiers || keyCode->size != modifiers->size)
380 return;
381
382 size = keyCode->size / sizeof(uint32_t);
383 key_code = (uint32_t *)keyCode->data;
384 modifier = (uint32_t *)modifiers->data;
385 if (shell && shell->callbacks && shell->callbacks->remove_key_intercept) {
386 while (size--) {
387 shell->callbacks->remove_key_intercept(shell->userData, surfaceId, *key_code, *modifier);
388 key_code++;
389 modifier++;
390 }
391 }
392}
393
394static void
395wstISimpleShellApplyAppsZorder(struct wl_client * client,
396 struct wl_resource * resource,
397 struct wl_array * appList)
398{
399 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
400 uint32_t *id;
401 size_t size;
402 int zorder = WESTON_ZORDER_DEFAULT;
403
404 if (!appList || !appList->size)
405 return;
406
407 id = (uint32_t *)appList->data;
408 size = appList->size / sizeof(uint32_t);
409 if (shell && shell->callbacks && shell->callbacks->set_zorder) {
410 while (size--) {
411 shell->callbacks->set_zorder(shell->userData, *id, (float)zorder / WESTON_ZORDER_MAX);
412 wstSimpleShellBroadcastSurfaceUpdate(client, shell, *id );
413 zorder += WESTON_ZORDER_INTERVAL;
414 id++;
415 }
416 }
417}
418
419static void
420wstISimpleShellSendMultiKey(struct wl_client * client,
421 struct wl_resource * resource,
422 uint32_t surfaceId,
423 struct wl_array * keyCode,
424 struct wl_array * modifiers)
425{
426 struct wl_simple_shell *shell =
427 (struct wl_simple_shell*)wl_resource_get_user_data(resource);
428 size_t size;
429 uint32_t *key_code, *modifier;
430
431 if (!keyCode || !modifiers || keyCode->size != modifiers->size)
432 return;
433
434 size = keyCode->size / sizeof(uint32_t);
435 key_code = (uint32_t *)keyCode->data;
436 modifier = (uint32_t *)modifiers->data;
437
438 if (shell && shell->callbacks && shell->callbacks->send_key) {
439 while (size--) {
440 shell->callbacks->send_key(shell->userData, surfaceId, *key_code, *modifier);
441 key_code++;
442 modifier++;
443 }
444 }
445}
446
447static void destroy_shell(struct wl_resource *resource)
448{
449 struct wl_simple_shell *shell= (struct wl_simple_shell*)wl_resource_get_user_data(resource);
450 struct shell_info *info, *tmp;
451
452 if ( shell ) {
453 wl_list_for_each_safe(info, tmp, &shell->shells, link) {
454 if (info->resource == resource) {
455 wl_list_remove(&info->link);
456 free(info);
457 break;
458 }
459 }
460 }
461}
462
463static void wstSimpleShellBind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
464{
465 struct wl_simple_shell *shell = (struct wl_simple_shell*)data;
466 struct wl_resource *resource;
467 struct shell_info *info;
468
469 if ( shell ) {
470 info = zalloc(sizeof *info);
471 if (info == NULL)
472 return;
473
474 resource= wl_resource_create(client, &wl_simple_shell_interface, MIN(version, 1), id);
475 if (!resource) {
476 wl_client_post_no_memory(client);
477 free(info);
478 return;
479 }
480
481 wl_resource_set_implementation(resource, &simple_shell_interface, shell, destroy_shell);
482
483 info->client= client;
484 info->resource= resource;
485 wl_list_insert(&shell->shells, &info->link);
486 }
487}
488
489static void wstSimpleShellBroadcastCreation( struct wl_simple_shell *shell, uint32_t surfaceId )
490{
491 const char *name= 0;
492 struct shell_info *info, *tmp;
493
494 if (!shell || !shell->callbacks)
495 return;
496
497 // Get any name the creator may have assigned the surface
498 if (shell->callbacks->get_name)
499 shell->callbacks->get_name( shell->userData, surfaceId, &name );
500 if ( !name )
501 name= (const char *)DEFAULT_NAME;
502
503 weston_log("broadcast for surfaceId %x name %s\n", surfaceId, name);
504
505 // Broadcast the surface creation announcement
506 wl_list_for_each_safe(info, tmp, &shell->shells, link) {
507 wl_simple_shell_send_surface_created( info->resource, surfaceId, name );
508 }
509}
510
511static int wstSimpleShellTimeOut( void *data )
512{
513 bool more = true;
514 long long now;
515 long long delay;
516 struct pending_broadcast_info *pendingInfo;
517 struct wl_simple_shell *shell = (struct wl_simple_shell*)data;
518
519 while ( more ) {
520 if (!wl_list_empty(&shell->pendingCreateBroadcast)) {
521 pendingInfo = wl_container_of( shell->pendingCreateBroadcast.next, pendingInfo, link);
522 wl_list_remove( shell->pendingCreateBroadcast.next );
523
524 wstSimpleShellBroadcastCreation( shell, pendingInfo->surfaceId );
525 free(pendingInfo);
526
527 if (!wl_list_empty(&shell->pendingCreateBroadcast)) {
528 pendingInfo = wl_container_of( shell->pendingCreateBroadcast.next, pendingInfo, link);
529 now = getCurrentTimeMillis();
530 delay = now - pendingInfo->creationTime;
531
532 if ( delay >= BROADCAST_DELAY ) {
533 continue;
534 } else {
535 delay = BROADCAST_DELAY - delay;
536 wl_event_source_timer_update( shell->delayTimer, delay );
537 more = false;
538 }
539 }
540 } else {
541 break;
542 }
543 }
544
545 return 0;
546}
547
548static void
549WstSimpleShellDestroySurface(struct wl_listener *listener, void *data)
550{
551 struct weston_surface *surface = (struct weston_surface *)data;
552 struct simple_shell_destroy_info *info =
553 container_of(listener,
554 struct simple_shell_destroy_info, destroy_surface_listener);
555
556 if (!surface || !info)
557 return;
558
559 WstSimpleShellNotifySurfaceDestroyed(info->shell, NULL, surface->surface_id);
560 wl_list_remove(&info->destroy_surface_listener.link);
561 free(info);
562}
563
564static void
565WstSimpleShellCreateSurface(struct wl_listener *listener, void *data)
566{
567 struct weston_surface *surface = (struct weston_surface *)data;
568 struct simple_shell_destroy_info *info;
569 struct wl_simple_shell *shell =
570 container_of(listener,
571 struct wl_simple_shell, create_surface_listener);
572 struct wl_client *client = wl_resource_get_client(surface->resource);
573
574 if (!shell)
575 return;
576
577 info = zalloc(sizeof *info);
578 if (info == NULL)
579 return;
580
581 info->shell = shell;
582 info->destroy_surface_listener.notify = WstSimpleShellDestroySurface;
583 wl_signal_add(&surface->destroy_signal,
584 &info->destroy_surface_listener);
585
586 surface->zorder = WESTON_ZORDER_DEFAULT;
leng.fanga0f20922024-10-11 17:23:59 +0800587 surface->visible = true;
leng.fangdbaf6fa2024-06-20 19:31:04 +0800588 WstSimpleShellNotifySurfaceCreated(shell,
589 client, surface->resource, surface->surface_id);
590}
591
592WL_EXPORT struct wl_simple_shell* WstSimpleShellInit( struct wl_display *display,
593 struct wayland_simple_shell_callbacks *callbacks,
594 void *userData )
595{
596 struct wl_simple_shell *shell= 0;
597 struct wl_event_loop *loop= 0;
598 struct weston_compositor *compositor = (struct weston_compositor *)userData;
599
600 weston_log("weston-simpleshell: WstSimpleShellInit: enter: display %p\n", display );
601 shell= (struct wl_simple_shell*)calloc( 1, sizeof(struct wl_simple_shell) );
602 if ( !shell )
603 goto exit;
604
605 shell->display= display;
606 shell->callbacks= callbacks;
607 shell->userData= userData;
608
609 wl_list_init(&shell->shells);
610 wl_list_init(&shell->surfaces);
611 wl_list_init(&shell->pendingCreateBroadcast);
612 loop= wl_display_get_event_loop(shell->display);
613 if ( !loop ) {
614 free( shell );
615 shell= 0;
616 goto exit;
617 }
618
619 shell->delayTimer= wl_event_loop_add_timer( loop, wstSimpleShellTimeOut, shell );
620 if ( !shell->delayTimer ) {
621 free( shell );
622 shell= 0;
623 goto exit;
624 }
625
626 shell->wl_simple_shell_global= wl_global_create(display, &wl_simple_shell_interface, 1, shell, wstSimpleShellBind );
627 shell->create_surface_listener.notify = WstSimpleShellCreateSurface;
628 wl_signal_add(&compositor->create_surface_signal,
629 &shell->create_surface_listener);
630
631exit:
632 weston_log("weston-simpleshell: WstSimpleShellInit: exit: display %p shell %p\n", display, shell);
633
634 return shell;
635}
636
637static void clear_pending_create_broadcast(struct wl_simple_shell *shell)
638{
639 struct pending_broadcast_info *info, *tmp;
640
641 wl_list_for_each_safe(info, tmp, &shell->pendingCreateBroadcast, link) {
642 wl_list_remove(&info->link);
643 free(info);
644 }
645}
646
647static void clear_surface_id(struct wl_simple_shell *shell)
648{
649 struct simple_shell_surface_id *info, *tmp;
650
651 wl_list_for_each_safe(info, tmp, &shell->surfaces, link) {
652 wl_list_remove(&info->link);
653 free(info);
654 }
655}
656
657static void clear_shell_info(struct wl_simple_shell *shell)
658{
659 struct shell_info *info, *tmp;
660
661 wl_list_for_each_safe(info, tmp, &shell->shells, link) {
662 wl_list_remove(&info->link);
663 free(info);
664 }
665}
666
667void WstSimpleShellUninit( struct wl_simple_shell *shell )
668{
669 if ( shell ) {
670 if ( shell->delayTimer ) {
671 wl_event_source_remove( shell->delayTimer );
672 shell->delayTimer= 0;
673 }
674 wl_global_destroy( shell->wl_simple_shell_global );
675 clear_pending_create_broadcast(shell);
676 clear_surface_id(shell);
677 clear_shell_info(shell);
678
679 free( shell );
680 }
681}
682
683void WstSimpleShellNotifySurfaceCreated( struct wl_simple_shell *shell,
684 struct wl_client *client,
685 struct wl_resource *surface_resource,
686 uint32_t surfaceId )
687{
688 bool creatorNotified= false;
689 struct simple_shell_surface_id *surface_id;
690 struct shell_info *info, *tmp;
691
692 if (!shell)
693 return;
694
695 surface_id = zalloc(sizeof *surface_id);
696 if (surface_id == NULL)
697 return;
698
699 // Add surface to list
700 surface_id->surfaceId = surfaceId;
701 wl_list_insert(&shell->surfaces, &surface_id->link);
702
703 weston_log("WstSimpleShellNotifySurfaceCreated: %d\n", surfaceId);
704
705 // Provide surface creator with surfaceId
706 wl_list_for_each_safe(info, tmp, &shell->shells, link) {
707 if (info->client == client) {
708 long long now;
709 struct pending_broadcast_info *pendingInfo;
710
711 wl_simple_shell_send_surface_id( info->resource, surface_resource, surfaceId );
712
713 pendingInfo = zalloc(sizeof *pendingInfo);
714 if (pendingInfo == NULL) {
715 wl_list_remove(&surface_id->link);
716 free(surface_id);
717 return;
718 }
719
720 creatorNotified= true;
721
722 // Perform the surface creation broadcast after an asynchronous
723 // delay to give the surface creator time to assign a name
724 now = getCurrentTimeMillis();
725 pendingInfo->creationTime = now;
726 pendingInfo->surfaceId = surfaceId;
727 wl_list_insert(&shell->pendingCreateBroadcast, &pendingInfo->link);
728 if (wl_list_length(&shell->pendingCreateBroadcast) == 1)
729 wl_event_source_timer_update( shell->delayTimer, BROADCAST_DELAY );
730 break;
731 }
732 }
733
734 if ( !creatorNotified )
735 wstSimpleShellBroadcastCreation( shell, surfaceId );
736}
737
738void WstSimpleShellNotifySurfaceDestroyed( struct wl_simple_shell *shell, struct wl_client *client, uint32_t surfaceId )
739{
740 const char *name;
741 struct shell_info *info, *shelltmp;
742 struct simple_shell_surface_id *surface_id, *surfacetmp;
743
744 WST_UNUSED(client);
745
746 if (!shell || !shell->callbacks)
747 return;
748
749 // Get any name the creator may have assigned the surface
750 if (shell->callbacks->get_name)
751 shell->callbacks->get_name( shell->userData, surfaceId, &name );
752 if ( !name )
753 name= (const char *)DEFAULT_NAME;
754
755 // Broadcast the surface destruction announcement
756 wl_list_for_each_safe(info, shelltmp, &shell->shells, link)
757 wl_simple_shell_send_surface_destroyed(info->resource, surfaceId, name);
758
759 // Remove surface from list
760 wl_list_for_each_safe(surface_id, surfacetmp, &shell->surfaces, link) {
761 if (surface_id->surfaceId == surfaceId) {
762 wl_list_remove(&surface_id->link);
763 free(surface_id);
764 break;
765 }
766 }
767
768 //Remove surface intercept key
769 if (shell->callbacks->remove_key_intercept)
770 shell->callbacks->remove_key_intercept(shell->userData, surfaceId, 0, 0);
771}