|  |  |  | @ -21,15 +21,22 @@ | 
			
		
	
		
			
				
					|  |  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #include <stdlib.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <stdio.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <string.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <unistd.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <linux/input.h> | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #include "wayland-server.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "compositor.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "desktop-shell-server-protocol.h" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | struct wl_shell { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlsc_compositor *compositor; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlsc_shell shell; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlsc_surface *panel; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_listener panel_listener; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlsc_surface *background; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_listener background_listener; | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | struct wlsc_move_grab { | 
			
		
	
	
		
			
				
					|  |  |  | @ -733,7 +740,7 @@ shell_create_selection(struct wl_client *client, | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_client_add_resource(client, &selection->resource); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | const static struct wl_shell_interface shell_interface = { | 
			
		
	
		
			
				
					|  |  |  |  | static const struct wl_shell_interface shell_interface = { | 
			
		
	
		
			
				
					|  |  |  |  | 	shell_move, | 
			
		
	
		
			
				
					|  |  |  |  | 	shell_resize, | 
			
		
	
		
			
				
					|  |  |  |  | 	shell_create_drag, | 
			
		
	
	
		
			
				
					|  |  |  | @ -743,15 +750,93 @@ const static struct wl_shell_interface shell_interface = { | 
			
		
	
		
			
				
					|  |  |  |  | 	shell_set_fullscreen | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | handle_background_surface_destroy(struct wl_listener *listener, | 
			
		
	
		
			
				
					|  |  |  |  | 				  struct wl_resource *resource, uint32_t time) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_shell *shell = | 
			
		
	
		
			
				
					|  |  |  |  | 		container_of(listener, struct wl_shell, background_listener); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	fprintf(stderr, "background surface gone\n"); | 
			
		
	
		
			
				
					|  |  |  |  | 	shell->background = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | desktop_shell_set_background(struct wl_client *client, | 
			
		
	
		
			
				
					|  |  |  |  | 			     struct wl_resource *resource, | 
			
		
	
		
			
				
					|  |  |  |  | 			     struct wl_resource *surface_resource) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_shell *shell = resource->data; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlsc_surface *surface = surface_resource->data; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlsc_output *output = | 
			
		
	
		
			
				
					|  |  |  |  | 		container_of(shell->compositor->output_list.next, | 
			
		
	
		
			
				
					|  |  |  |  | 			     struct wlsc_output, link); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	shell->background = surface_resource->data; | 
			
		
	
		
			
				
					|  |  |  |  | 	shell->background_listener.func = handle_background_surface_destroy; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_insert(&surface_resource->destroy_listener_list, | 
			
		
	
		
			
				
					|  |  |  |  | 		       &shell->background_listener.link); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_resource_post_event(resource, | 
			
		
	
		
			
				
					|  |  |  |  | 			       DESKTOP_SHELL_CONFIGURE, | 
			
		
	
		
			
				
					|  |  |  |  | 			       wlsc_compositor_get_time(), 0, surface, | 
			
		
	
		
			
				
					|  |  |  |  | 			       output->current->width, | 
			
		
	
		
			
				
					|  |  |  |  | 			       output->current->height); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | handle_panel_surface_destroy(struct wl_listener *listener, | 
			
		
	
		
			
				
					|  |  |  |  | 			     struct wl_resource *resource, uint32_t time) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_shell *shell = | 
			
		
	
		
			
				
					|  |  |  |  | 		container_of(listener, struct wl_shell, panel_listener); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	fprintf(stderr, "panel surface gone\n"); | 
			
		
	
		
			
				
					|  |  |  |  | 	shell->panel = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | desktop_shell_set_panel(struct wl_client *client, | 
			
		
	
		
			
				
					|  |  |  |  | 			struct wl_resource *resource, | 
			
		
	
		
			
				
					|  |  |  |  | 			struct wl_resource *surface_resource) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_shell *shell = resource->data; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlsc_output *output = | 
			
		
	
		
			
				
					|  |  |  |  | 		container_of(shell->compositor->output_list.next, | 
			
		
	
		
			
				
					|  |  |  |  | 			     struct wlsc_output, link); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	shell->panel = surface_resource->data; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	shell->panel_listener.func = handle_panel_surface_destroy; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_insert(&surface_resource->destroy_listener_list, | 
			
		
	
		
			
				
					|  |  |  |  | 		       &shell->panel_listener.link); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_resource_post_event(resource, | 
			
		
	
		
			
				
					|  |  |  |  | 			       DESKTOP_SHELL_CONFIGURE, | 
			
		
	
		
			
				
					|  |  |  |  | 			       wlsc_compositor_get_time(), 0, surface_resource, | 
			
		
	
		
			
				
					|  |  |  |  | 			       output->current->width, | 
			
		
	
		
			
				
					|  |  |  |  | 			       output->current->height); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static const struct desktop_shell_interface desktop_shell_implementation = { | 
			
		
	
		
			
				
					|  |  |  |  | 	desktop_shell_set_background, | 
			
		
	
		
			
				
					|  |  |  |  | 	desktop_shell_set_panel | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | move_binding(struct wl_input_device *device, uint32_t time, | 
			
		
	
		
			
				
					|  |  |  |  | 	     uint32_t key, uint32_t button, uint32_t state, void *data) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_shell *shell = data; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlsc_surface *surface = | 
			
		
	
		
			
				
					|  |  |  |  | 		(struct wlsc_surface *) device->pointer_focus; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (surface == NULL) | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	if (surface == shell->panel) | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	if (surface == shell->background) | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wlsc_surface_move(surface, (struct wlsc_input_device *) device, time); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | @ -760,6 +845,7 @@ static void | 
			
		
	
		
			
				
					|  |  |  |  | resize_binding(struct wl_input_device *device, uint32_t time, | 
			
		
	
		
			
				
					|  |  |  |  | 	       uint32_t key, uint32_t button, uint32_t state, void *data) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_shell *shell = data; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlsc_surface *surface = | 
			
		
	
		
			
				
					|  |  |  |  | 		(struct wlsc_surface *) device->pointer_focus; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_resource *resource; | 
			
		
	
	
		
			
				
					|  |  |  | @ -768,6 +854,10 @@ resize_binding(struct wl_input_device *device, uint32_t time, | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (surface == NULL) | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	if (surface == shell->panel) | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	if (surface == shell->background) | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	x = device->grab_x - surface->x; | 
			
		
	
		
			
				
					|  |  |  |  | 	y = device->grab_y - surface->y; | 
			
		
	
	
		
			
				
					|  |  |  | @ -794,15 +884,39 @@ resize_binding(struct wl_input_device *device, uint32_t time, | 
			
		
	
		
			
				
					|  |  |  |  | 			    time, edges, resource); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | activate(struct wlsc_shell *base, struct wlsc_surface *es, | 
			
		
	
		
			
				
					|  |  |  |  | 	 struct wlsc_input_device *device, uint32_t time) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_shell *shell = container_of(base, struct wl_shell, shell); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlsc_compositor *compositor = shell->compositor; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wlsc_surface_activate(es, device, time); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (es == shell->background) { | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_list_remove(&es->link); | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_list_insert(compositor->surface_list.prev, &es->link); | 
			
		
	
		
			
				
					|  |  |  |  | 	} else if (shell->panel) { | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_list_remove(&shell->panel->link); | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_list_insert(&compositor->surface_list, &shell->panel->link); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | lock(struct wlsc_shell *shell) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | attach(struct wlsc_shell *shell, struct wlsc_surface *es) | 
			
		
	
		
			
				
					|  |  |  |  | attach(struct wlsc_shell *base, struct wlsc_surface *es) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_shell *shell = container_of(base, struct wl_shell, shell); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlsc_compositor *compositor = shell->compositor; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (es == shell->background) { | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_list_remove(&es->link); | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_list_insert(compositor->surface_list.prev, &es->link); | 
			
		
	
		
			
				
					|  |  |  |  | 	} else if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN) { | 
			
		
	
		
			
				
					|  |  |  |  | 		es->x = (es->fullscreen_output->current->width - es->width) / 2; | 
			
		
	
		
			
				
					|  |  |  |  | 		es->y = (es->fullscreen_output->current->height - es->height) / 2; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
	
		
			
				
					|  |  |  | @ -817,6 +931,16 @@ bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id) | 
			
		
	
		
			
				
					|  |  |  |  | 			     &shell_interface, id, shell); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | bind_desktop_shell(struct wl_client *client, | 
			
		
	
		
			
				
					|  |  |  |  | 		   void *data, uint32_t version, uint32_t id) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_shell *shell = data; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_client_add_object(client, &desktop_shell_interface, | 
			
		
	
		
			
				
					|  |  |  |  | 			     &desktop_shell_implementation, id, shell); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | int | 
			
		
	
		
			
				
					|  |  |  |  | shell_init(struct wlsc_compositor *ec); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -829,6 +953,8 @@ shell_init(struct wlsc_compositor *ec) | 
			
		
	
		
			
				
					|  |  |  |  | 	if (shell == NULL) | 
			
		
	
		
			
				
					|  |  |  |  | 		return -1; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	shell->compositor = ec; | 
			
		
	
		
			
				
					|  |  |  |  | 	shell->shell.activate = activate; | 
			
		
	
		
			
				
					|  |  |  |  | 	shell->shell.lock = lock; | 
			
		
	
		
			
				
					|  |  |  |  | 	shell->shell.attach = attach; | 
			
		
	
		
			
				
					|  |  |  |  | 	shell->shell.set_selection_focus = wlsc_selection_set_focus; | 
			
		
	
	
		
			
				
					|  |  |  | @ -837,6 +963,11 @@ shell_init(struct wlsc_compositor *ec) | 
			
		
	
		
			
				
					|  |  |  |  | 				  shell, bind_shell) == NULL) | 
			
		
	
		
			
				
					|  |  |  |  | 		return -1; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (wl_display_add_global(ec->wl_display, | 
			
		
	
		
			
				
					|  |  |  |  | 				  &desktop_shell_interface, | 
			
		
	
		
			
				
					|  |  |  |  | 				  shell, bind_desktop_shell) == NULL) | 
			
		
	
		
			
				
					|  |  |  |  | 		return -1; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wlsc_compositor_add_binding(ec, 0, BTN_LEFT, MODIFIER_SUPER, | 
			
		
	
		
			
				
					|  |  |  |  | 				    move_binding, shell); | 
			
		
	
		
			
				
					|  |  |  |  | 	wlsc_compositor_add_binding(ec, 0, BTN_MIDDLE, MODIFIER_SUPER, | 
			
		
	
	
		
			
				
					|  |  |  | 
 |