Move libweston-desktop into libweston
It's not really useful to have libweston without libweston-desktop. It's also very little code. Merging both into the same DSO will allow us to cut out a bunch of indirection and pain. Signed-off-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
committed by
Pekka Paalanen
parent
3ed3700ca3
commit
9336263d9b
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright © 2016 Quentin "Sardem FF7" Glidic
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <wayland-server.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <libweston/libweston.h>
|
||||
#include <libweston/zalloc.h>
|
||||
|
||||
#include <libweston-desktop/libweston-desktop.h>
|
||||
#include "internal.h"
|
||||
|
||||
struct weston_desktop_client {
|
||||
struct weston_desktop *desktop;
|
||||
struct wl_client *client;
|
||||
struct wl_resource *resource;
|
||||
struct wl_list surface_list;
|
||||
uint32_t ping_serial;
|
||||
struct wl_event_source *ping_timer;
|
||||
struct wl_signal destroy_signal;
|
||||
};
|
||||
|
||||
void
|
||||
weston_desktop_client_add_destroy_listener(struct weston_desktop_client *client,
|
||||
struct wl_listener *listener)
|
||||
{
|
||||
wl_signal_add(&client->destroy_signal, listener);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_client_destroy(struct weston_desktop_client *client)
|
||||
{
|
||||
struct wl_list *list = &client->surface_list;
|
||||
struct wl_list *link, *tmp;
|
||||
|
||||
assert(client->resource == NULL);
|
||||
|
||||
wl_signal_emit(&client->destroy_signal, client);
|
||||
|
||||
for (link = list->next, tmp = link->next;
|
||||
link != list;
|
||||
link = tmp, tmp = link->next) {
|
||||
wl_list_remove(link);
|
||||
wl_list_init(link);
|
||||
}
|
||||
|
||||
if (client->ping_timer != NULL)
|
||||
wl_event_source_remove(client->ping_timer);
|
||||
|
||||
free(client);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_client_handle_destroy(struct wl_resource *resource)
|
||||
{
|
||||
struct weston_desktop_client *client =
|
||||
wl_resource_get_user_data(resource);
|
||||
|
||||
assert(client->resource == resource);
|
||||
client->resource = NULL;
|
||||
|
||||
weston_desktop_client_destroy(client);
|
||||
}
|
||||
|
||||
static int
|
||||
weston_desktop_client_ping_timeout(void *user_data)
|
||||
{
|
||||
struct weston_desktop_client *client = user_data;
|
||||
|
||||
weston_desktop_api_ping_timeout(client->desktop, client);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct weston_desktop_client *
|
||||
weston_desktop_client_create(struct weston_desktop *desktop,
|
||||
struct wl_client *wl_client,
|
||||
wl_dispatcher_func_t dispatcher,
|
||||
const struct wl_interface *interface,
|
||||
const void *implementation, uint32_t version,
|
||||
uint32_t id)
|
||||
{
|
||||
struct weston_desktop_client *client;
|
||||
struct wl_display *display;
|
||||
struct wl_event_loop *loop;
|
||||
|
||||
client = zalloc(sizeof(struct weston_desktop_client));
|
||||
if (client == NULL) {
|
||||
if (wl_client != NULL)
|
||||
wl_client_post_no_memory(wl_client);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
client->desktop = desktop;
|
||||
client->client = wl_client;
|
||||
|
||||
wl_list_init(&client->surface_list);
|
||||
wl_signal_init(&client->destroy_signal);
|
||||
|
||||
if (wl_client == NULL)
|
||||
return client;
|
||||
|
||||
client->resource = wl_resource_create(wl_client, interface, version, id);
|
||||
if (client->resource == NULL) {
|
||||
wl_client_post_no_memory(wl_client);
|
||||
free(client);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dispatcher != NULL)
|
||||
wl_resource_set_dispatcher(client->resource, dispatcher,
|
||||
weston_desktop_client_handle_destroy, client,
|
||||
weston_desktop_client_handle_destroy);
|
||||
else
|
||||
wl_resource_set_implementation(client->resource, implementation,
|
||||
client,
|
||||
weston_desktop_client_handle_destroy);
|
||||
|
||||
display = wl_client_get_display(client->client);
|
||||
loop = wl_display_get_event_loop(display);
|
||||
client->ping_timer =
|
||||
wl_event_loop_add_timer(loop,
|
||||
weston_desktop_client_ping_timeout,
|
||||
client);
|
||||
if (client->ping_timer == NULL)
|
||||
wl_client_post_no_memory(wl_client);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
struct weston_desktop *
|
||||
weston_desktop_client_get_desktop(struct weston_desktop_client *client)
|
||||
{
|
||||
return client->desktop;
|
||||
}
|
||||
|
||||
struct wl_resource *
|
||||
weston_desktop_client_get_resource(struct weston_desktop_client *client)
|
||||
{
|
||||
return client->resource;
|
||||
}
|
||||
|
||||
struct wl_list *
|
||||
weston_desktop_client_get_surface_list(struct weston_desktop_client *client)
|
||||
{
|
||||
return &client->surface_list;
|
||||
}
|
||||
|
||||
WL_EXPORT struct wl_client *
|
||||
weston_desktop_client_get_client(struct weston_desktop_client *client)
|
||||
{
|
||||
return client->client;
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_client_for_each_surface(struct weston_desktop_client *client,
|
||||
void (*callback)(struct weston_desktop_surface *surface, void *user_data),
|
||||
void *user_data)
|
||||
{
|
||||
struct wl_list *list = &client->surface_list;
|
||||
struct wl_list *link;
|
||||
|
||||
for (link = list->next; link != list; link = link->next)
|
||||
callback(weston_desktop_surface_from_client_link(link),
|
||||
user_data);
|
||||
}
|
||||
|
||||
WL_EXPORT int
|
||||
weston_desktop_client_ping(struct weston_desktop_client *client)
|
||||
{
|
||||
struct weston_desktop_surface *surface =
|
||||
weston_desktop_surface_from_client_link(client->surface_list.next);
|
||||
const struct weston_desktop_surface_implementation *implementation =
|
||||
weston_desktop_surface_get_implementation(surface);
|
||||
void *implementation_data =
|
||||
weston_desktop_surface_get_implementation_data(surface);
|
||||
|
||||
if (implementation->ping == NULL)
|
||||
return -1;
|
||||
|
||||
if (client->ping_serial != 0)
|
||||
return 1;
|
||||
|
||||
client->ping_serial =
|
||||
wl_display_next_serial(wl_client_get_display(client->client));
|
||||
wl_event_source_timer_update(client->ping_timer, 10000);
|
||||
|
||||
implementation->ping(surface, client->ping_serial, implementation_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_client_pong(struct weston_desktop_client *client, uint32_t serial)
|
||||
{
|
||||
if (client->ping_serial != serial)
|
||||
return;
|
||||
|
||||
weston_desktop_api_pong(client->desktop, client);
|
||||
|
||||
wl_event_source_timer_update(client->ping_timer, 0);
|
||||
client->ping_serial = 0;
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright © 2016 Quentin "Sardem FF7" Glidic
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef WESTON_DESKTOP_INTERNAL_H
|
||||
#define WESTON_DESKTOP_INTERNAL_H
|
||||
|
||||
#include <libweston/libweston.h>
|
||||
|
||||
struct weston_desktop_seat;
|
||||
struct weston_desktop_client;
|
||||
|
||||
struct weston_compositor *
|
||||
weston_desktop_get_compositor(struct weston_desktop *desktop);
|
||||
struct wl_display *
|
||||
weston_desktop_get_display(struct weston_desktop *desktop);
|
||||
|
||||
void
|
||||
weston_desktop_api_ping_timeout(struct weston_desktop *desktop,
|
||||
struct weston_desktop_client *client);
|
||||
void
|
||||
weston_desktop_api_pong(struct weston_desktop *desktop,
|
||||
struct weston_desktop_client *client);
|
||||
void
|
||||
weston_desktop_api_surface_added(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface);
|
||||
void
|
||||
weston_desktop_api_surface_removed(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface);
|
||||
void
|
||||
weston_desktop_api_committed(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
int32_t sx, int32_t sy);
|
||||
void
|
||||
weston_desktop_api_show_window_menu(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
struct weston_seat *seat,
|
||||
int32_t x, int32_t y);
|
||||
void
|
||||
weston_desktop_api_set_parent(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
struct weston_desktop_surface *parent);
|
||||
void
|
||||
weston_desktop_api_move(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
struct weston_seat *seat, uint32_t serial);
|
||||
void
|
||||
weston_desktop_api_resize(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
struct weston_seat *seat, uint32_t serial,
|
||||
enum weston_desktop_surface_edge edges);
|
||||
void
|
||||
weston_desktop_api_fullscreen_requested(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
bool fullscreen,
|
||||
struct weston_output *output);
|
||||
void
|
||||
weston_desktop_api_maximized_requested(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
bool maximized);
|
||||
void
|
||||
weston_desktop_api_minimized_requested(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface);
|
||||
|
||||
void
|
||||
weston_desktop_api_set_xwayland_position(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
int32_t x, int32_t y);
|
||||
|
||||
struct weston_desktop_seat *
|
||||
weston_desktop_seat_from_seat(struct weston_seat *wseat);
|
||||
|
||||
struct weston_desktop_surface_implementation {
|
||||
void (*set_activated)(struct weston_desktop_surface *surface,
|
||||
void *user_data, bool activated);
|
||||
void (*set_fullscreen)(struct weston_desktop_surface *surface,
|
||||
void *user_data, bool fullscreen);
|
||||
void (*set_maximized)(struct weston_desktop_surface *surface,
|
||||
void *user_data, bool maximized);
|
||||
void (*set_resizing)(struct weston_desktop_surface *surface,
|
||||
void *user_data, bool resizing);
|
||||
void (*set_size)(struct weston_desktop_surface *surface,
|
||||
void *user_data, int32_t width, int32_t height);
|
||||
void (*committed)(struct weston_desktop_surface *surface, void *user_data,
|
||||
int32_t sx, int32_t sy);
|
||||
void (*update_position)(struct weston_desktop_surface *surface,
|
||||
void *user_data);
|
||||
void (*ping)(struct weston_desktop_surface *surface, uint32_t serial,
|
||||
void *user_data);
|
||||
void (*close)(struct weston_desktop_surface *surface, void *user_data);
|
||||
|
||||
bool (*get_activated)(struct weston_desktop_surface *surface,
|
||||
void *user_data);
|
||||
bool (*get_fullscreen)(struct weston_desktop_surface *surface,
|
||||
void *user_data);
|
||||
bool (*get_maximized)(struct weston_desktop_surface *surface,
|
||||
void *user_data);
|
||||
bool (*get_resizing)(struct weston_desktop_surface *surface,
|
||||
void *user_data);
|
||||
struct weston_size
|
||||
(*get_max_size)(struct weston_desktop_surface *surface,
|
||||
void *user_data);
|
||||
struct weston_size
|
||||
(*get_min_size)(struct weston_desktop_surface *surface,
|
||||
void *user_data);
|
||||
|
||||
void (*destroy)(struct weston_desktop_surface *surface,
|
||||
void *user_data);
|
||||
};
|
||||
|
||||
struct weston_desktop_client *
|
||||
weston_desktop_client_create(struct weston_desktop *desktop,
|
||||
struct wl_client *client,
|
||||
wl_dispatcher_func_t dispatcher,
|
||||
const struct wl_interface *interface,
|
||||
const void *implementation, uint32_t version,
|
||||
uint32_t id);
|
||||
void
|
||||
weston_desktop_client_destroy(struct weston_desktop_client *client);
|
||||
|
||||
void
|
||||
weston_desktop_client_add_destroy_listener(struct weston_desktop_client *client,
|
||||
struct wl_listener *listener);
|
||||
struct weston_desktop *
|
||||
weston_desktop_client_get_desktop(struct weston_desktop_client *client);
|
||||
struct wl_resource *
|
||||
weston_desktop_client_get_resource(struct weston_desktop_client *client);
|
||||
struct wl_list *
|
||||
weston_desktop_client_get_surface_list(struct weston_desktop_client *client);
|
||||
|
||||
void
|
||||
weston_desktop_client_pong(struct weston_desktop_client *client,
|
||||
uint32_t serial);
|
||||
|
||||
struct weston_desktop_surface *
|
||||
weston_desktop_surface_create(struct weston_desktop *desktop,
|
||||
struct weston_desktop_client *client,
|
||||
struct weston_surface *surface,
|
||||
const struct weston_desktop_surface_implementation *implementation,
|
||||
void *implementation_data);
|
||||
void
|
||||
weston_desktop_surface_destroy(struct weston_desktop_surface *surface);
|
||||
void
|
||||
weston_desktop_surface_resource_destroy(struct wl_resource *resource);
|
||||
struct wl_resource *
|
||||
weston_desktop_surface_add_resource(struct weston_desktop_surface *surface,
|
||||
const struct wl_interface *interface,
|
||||
const void *implementation, uint32_t id,
|
||||
wl_resource_destroy_func_t destroy);
|
||||
struct weston_desktop_surface *
|
||||
weston_desktop_surface_from_grab_link(struct wl_list *grab_link);
|
||||
|
||||
struct wl_list *
|
||||
weston_desktop_surface_get_client_link(struct weston_desktop_surface *surface);
|
||||
struct weston_desktop_surface *
|
||||
weston_desktop_surface_from_client_link(struct wl_list *link);
|
||||
bool
|
||||
weston_desktop_surface_has_implementation(struct weston_desktop_surface *surface,
|
||||
const struct weston_desktop_surface_implementation *implementation);
|
||||
const struct weston_desktop_surface_implementation *
|
||||
weston_desktop_surface_get_implementation(struct weston_desktop_surface *surface);
|
||||
void *
|
||||
weston_desktop_surface_get_implementation_data(struct weston_desktop_surface *surface);
|
||||
struct weston_desktop_surface *
|
||||
weston_desktop_surface_get_parent(struct weston_desktop_surface *surface);
|
||||
bool
|
||||
weston_desktop_surface_get_grab(struct weston_desktop_surface *surface);
|
||||
|
||||
void
|
||||
weston_desktop_surface_set_title(struct weston_desktop_surface *surface,
|
||||
const char *title);
|
||||
void
|
||||
weston_desktop_surface_set_app_id(struct weston_desktop_surface *surface,
|
||||
const char *app_id);
|
||||
void
|
||||
weston_desktop_surface_set_pid(struct weston_desktop_surface *surface,
|
||||
pid_t pid);
|
||||
void
|
||||
weston_desktop_surface_set_geometry(struct weston_desktop_surface *surface,
|
||||
struct weston_geometry geometry);
|
||||
void
|
||||
weston_desktop_surface_set_relative_to(struct weston_desktop_surface *surface,
|
||||
struct weston_desktop_surface *parent,
|
||||
int32_t x, int32_t y, bool use_geometry);
|
||||
void
|
||||
weston_desktop_surface_unset_relative_to(struct weston_desktop_surface *surface);
|
||||
void
|
||||
weston_desktop_surface_popup_grab(struct weston_desktop_surface *popup,
|
||||
struct weston_desktop_seat *seat,
|
||||
uint32_t serial);
|
||||
void
|
||||
weston_desktop_surface_popup_ungrab(struct weston_desktop_surface *popup,
|
||||
struct weston_desktop_seat *seat);
|
||||
void
|
||||
weston_desktop_surface_popup_dismiss(struct weston_desktop_surface *surface);
|
||||
|
||||
struct weston_desktop_surface *
|
||||
weston_desktop_seat_popup_grab_get_topmost_surface(struct weston_desktop_seat *seat);
|
||||
bool
|
||||
weston_desktop_seat_popup_grab_start(struct weston_desktop_seat *seat,
|
||||
struct wl_client *client, uint32_t serial);
|
||||
void
|
||||
weston_desktop_seat_popup_grab_add_surface(struct weston_desktop_seat *seat,
|
||||
struct wl_list *link);
|
||||
void
|
||||
weston_desktop_seat_popup_grab_remove_surface(struct weston_desktop_seat *seat,
|
||||
struct wl_list *link);
|
||||
|
||||
void
|
||||
weston_desktop_destroy_request(struct wl_client *client,
|
||||
struct wl_resource *resource);
|
||||
struct wl_global *
|
||||
weston_desktop_xdg_wm_base_create(struct weston_desktop *desktop,
|
||||
struct wl_display *display);
|
||||
struct wl_global *
|
||||
weston_desktop_xdg_shell_v6_create(struct weston_desktop *desktop,
|
||||
struct wl_display *display);
|
||||
void
|
||||
weston_desktop_xwayland_init(struct weston_desktop *desktop);
|
||||
void
|
||||
weston_desktop_xwayland_fini(struct weston_desktop *desktop);
|
||||
|
||||
#endif /* WESTON_DESKTOP_INTERNAL_H */
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright © 2016 Quentin "Sardem FF7" Glidic
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <wayland-server.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <libweston/libweston.h>
|
||||
#include <libweston/zalloc.h>
|
||||
#include "shared/helpers.h"
|
||||
|
||||
#include <libweston-desktop/libweston-desktop.h>
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
struct weston_desktop {
|
||||
struct weston_compositor *compositor;
|
||||
struct weston_desktop_api api;
|
||||
void *user_data;
|
||||
struct wl_global *xdg_wm_base; /* Stable protocol xdg_shell replaces xdg_shell_unstable_v6 */
|
||||
struct wl_global *xdg_shell_v6; /* Unstable xdg_shell_unstable_v6 protocol. */
|
||||
};
|
||||
|
||||
void
|
||||
weston_desktop_destroy_request(struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
||||
WL_EXPORT struct weston_desktop *
|
||||
weston_desktop_create(struct weston_compositor *compositor,
|
||||
const struct weston_desktop_api *api, void *user_data)
|
||||
{
|
||||
struct weston_desktop *desktop;
|
||||
struct wl_display *display = compositor->wl_display;
|
||||
|
||||
assert(api->surface_added);
|
||||
assert(api->surface_removed);
|
||||
|
||||
desktop = zalloc(sizeof(struct weston_desktop));
|
||||
desktop->compositor = compositor;
|
||||
desktop->user_data = user_data;
|
||||
|
||||
desktop->api.struct_size =
|
||||
MIN(sizeof(struct weston_desktop_api), api->struct_size);
|
||||
memcpy(&desktop->api, api, desktop->api.struct_size);
|
||||
|
||||
desktop->xdg_wm_base =
|
||||
weston_desktop_xdg_wm_base_create(desktop, display);
|
||||
if (desktop->xdg_wm_base == NULL) {
|
||||
weston_desktop_destroy(desktop);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
weston_desktop_xwayland_init(desktop);
|
||||
|
||||
return desktop;
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_destroy(struct weston_desktop *desktop)
|
||||
{
|
||||
if (desktop == NULL)
|
||||
return;
|
||||
|
||||
weston_desktop_xwayland_fini(desktop);
|
||||
|
||||
if (desktop->xdg_shell_v6 != NULL)
|
||||
wl_global_destroy(desktop->xdg_shell_v6);
|
||||
if (desktop->xdg_wm_base != NULL)
|
||||
wl_global_destroy(desktop->xdg_wm_base);
|
||||
|
||||
free(desktop);
|
||||
}
|
||||
|
||||
|
||||
struct weston_compositor *
|
||||
weston_desktop_get_compositor(struct weston_desktop *desktop)
|
||||
{
|
||||
return desktop->compositor;
|
||||
}
|
||||
|
||||
struct wl_display *
|
||||
weston_desktop_get_display(struct weston_desktop *desktop)
|
||||
{
|
||||
return desktop->compositor->wl_display;
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_ping_timeout(struct weston_desktop *desktop,
|
||||
struct weston_desktop_client *client)
|
||||
{
|
||||
if (desktop->api.ping_timeout != NULL)
|
||||
desktop->api.ping_timeout(client, desktop->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_pong(struct weston_desktop *desktop,
|
||||
struct weston_desktop_client *client)
|
||||
{
|
||||
if (desktop->api.pong != NULL)
|
||||
desktop->api.pong(client, desktop->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_surface_added(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface)
|
||||
{
|
||||
struct weston_desktop_client *client =
|
||||
weston_desktop_surface_get_client(surface);
|
||||
struct wl_list *list = weston_desktop_client_get_surface_list(client);
|
||||
struct wl_list *link = weston_desktop_surface_get_client_link(surface);
|
||||
|
||||
desktop->api.surface_added(surface, desktop->user_data);
|
||||
wl_list_insert(list, link);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_surface_removed(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface)
|
||||
{
|
||||
struct wl_list *link = weston_desktop_surface_get_client_link(surface);
|
||||
|
||||
wl_list_remove(link);
|
||||
wl_list_init(link);
|
||||
desktop->api.surface_removed(surface, desktop->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_committed(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
int32_t sx, int32_t sy)
|
||||
{
|
||||
if (desktop->api.committed != NULL)
|
||||
desktop->api.committed(surface, sx, sy, desktop->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_show_window_menu(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
struct weston_seat *seat,
|
||||
int32_t x, int32_t y)
|
||||
{
|
||||
if (desktop->api.show_window_menu != NULL)
|
||||
desktop->api.show_window_menu(surface, seat, x, y,
|
||||
desktop->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_set_parent(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
struct weston_desktop_surface *parent)
|
||||
{
|
||||
if (desktop->api.set_parent != NULL)
|
||||
desktop->api.set_parent(surface, parent, desktop->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_move(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
struct weston_seat *seat, uint32_t serial)
|
||||
{
|
||||
if (desktop->api.move != NULL)
|
||||
desktop->api.move(surface, seat, serial, desktop->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_resize(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
struct weston_seat *seat, uint32_t serial,
|
||||
enum weston_desktop_surface_edge edges)
|
||||
{
|
||||
if (desktop->api.resize != NULL)
|
||||
desktop->api.resize(surface, seat, serial, edges,
|
||||
desktop->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_fullscreen_requested(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
bool fullscreen,
|
||||
struct weston_output *output)
|
||||
{
|
||||
if (desktop->api.fullscreen_requested != NULL)
|
||||
desktop->api.fullscreen_requested(surface, fullscreen, output,
|
||||
desktop->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_maximized_requested(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
bool maximized)
|
||||
{
|
||||
if (desktop->api.maximized_requested != NULL)
|
||||
desktop->api.maximized_requested(surface, maximized,
|
||||
desktop->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_minimized_requested(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface)
|
||||
{
|
||||
if (desktop->api.minimized_requested != NULL)
|
||||
desktop->api.minimized_requested(surface, desktop->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_api_set_xwayland_position(struct weston_desktop *desktop,
|
||||
struct weston_desktop_surface *surface,
|
||||
int32_t x, int32_t y)
|
||||
{
|
||||
if (desktop->api.set_xwayland_position != NULL)
|
||||
desktop->api.set_xwayland_position(surface, x, y,
|
||||
desktop->user_data);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
srcs_libweston += files([
|
||||
'libweston-desktop.c',
|
||||
'client.c',
|
||||
'seat.c',
|
||||
'surface.c',
|
||||
'xwayland.c',
|
||||
'xdg-shell.c',
|
||||
'xdg-shell-v6.c',
|
||||
])
|
||||
|
||||
srcs_libweston += [
|
||||
xdg_shell_unstable_v6_server_protocol_h,
|
||||
xdg_shell_unstable_v6_protocol_c,
|
||||
xdg_shell_server_protocol_h,
|
||||
xdg_shell_protocol_c,
|
||||
]
|
||||
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* Copyright © 2010-2012 Intel Corporation
|
||||
* Copyright © 2011-2012 Collabora, Ltd.
|
||||
* Copyright © 2013 Raspberry Pi Foundation
|
||||
* Copyright © 2016 Quentin "Sardem FF7" Glidic
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include <libweston/libweston.h>
|
||||
#include <libweston/zalloc.h>
|
||||
|
||||
#include <libweston-desktop/libweston-desktop.h>
|
||||
#include "internal.h"
|
||||
#include "shared/timespec-util.h"
|
||||
|
||||
struct weston_desktop_seat {
|
||||
struct wl_listener seat_destroy_listener;
|
||||
struct weston_seat *seat;
|
||||
struct {
|
||||
struct weston_keyboard_grab keyboard;
|
||||
struct weston_pointer_grab pointer;
|
||||
struct weston_touch_grab touch;
|
||||
bool initial_up;
|
||||
struct wl_client *client;
|
||||
struct wl_list surfaces;
|
||||
} popup_grab;
|
||||
};
|
||||
|
||||
static void weston_desktop_seat_popup_grab_end(struct weston_desktop_seat *seat);
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_keyboard_key(struct weston_keyboard_grab *grab,
|
||||
const struct timespec *time,
|
||||
uint32_t key,
|
||||
enum wl_keyboard_key_state state)
|
||||
{
|
||||
weston_keyboard_send_key(grab->keyboard, time, key, state);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
|
||||
uint32_t serial,
|
||||
uint32_t mods_depressed,
|
||||
uint32_t mods_latched,
|
||||
uint32_t mods_locked,
|
||||
uint32_t group)
|
||||
{
|
||||
weston_keyboard_send_modifiers(grab->keyboard, serial, mods_depressed,
|
||||
mods_latched, mods_locked, group);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
|
||||
{
|
||||
struct weston_desktop_seat *seat =
|
||||
wl_container_of(grab, seat, popup_grab.keyboard);
|
||||
|
||||
weston_desktop_seat_popup_grab_end(seat);
|
||||
}
|
||||
|
||||
static const struct weston_keyboard_grab_interface weston_desktop_seat_keyboard_popup_grab_interface = {
|
||||
.key = weston_desktop_seat_popup_grab_keyboard_key,
|
||||
.modifiers = weston_desktop_seat_popup_grab_keyboard_modifiers,
|
||||
.cancel = weston_desktop_seat_popup_grab_keyboard_cancel,
|
||||
};
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_pointer_focus(struct weston_pointer_grab *grab)
|
||||
{
|
||||
struct weston_desktop_seat *seat =
|
||||
wl_container_of(grab, seat, popup_grab.pointer);
|
||||
struct weston_pointer *pointer = grab->pointer;
|
||||
struct weston_view *view;
|
||||
wl_fixed_t sx, sy;
|
||||
|
||||
view = weston_compositor_pick_view(pointer->seat->compositor,
|
||||
pointer->x, pointer->y, &sx, &sy);
|
||||
|
||||
if (view != NULL &&
|
||||
view->surface->resource != NULL &&
|
||||
wl_resource_get_client(view->surface->resource) == seat->popup_grab.client)
|
||||
weston_pointer_set_focus(pointer, view, sx, sy);
|
||||
else
|
||||
weston_pointer_clear_focus(pointer);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_pointer_motion(struct weston_pointer_grab *grab,
|
||||
const struct timespec *time,
|
||||
struct weston_pointer_motion_event *event)
|
||||
{
|
||||
weston_pointer_send_motion(grab->pointer, time, event);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_pointer_button(struct weston_pointer_grab *grab,
|
||||
const struct timespec *time,
|
||||
uint32_t button,
|
||||
enum wl_pointer_button_state state)
|
||||
{
|
||||
struct weston_desktop_seat *seat =
|
||||
wl_container_of(grab, seat, popup_grab.pointer);
|
||||
struct weston_pointer *pointer = grab->pointer;
|
||||
bool initial_up = seat->popup_grab.initial_up;
|
||||
|
||||
if (state == WL_POINTER_BUTTON_STATE_RELEASED)
|
||||
seat->popup_grab.initial_up = true;
|
||||
|
||||
if (weston_pointer_has_focus_resource(pointer))
|
||||
weston_pointer_send_button(pointer, time, button, state);
|
||||
else if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
|
||||
(initial_up ||
|
||||
(timespec_sub_to_msec(time, &grab->pointer->grab_time) > 500)))
|
||||
weston_desktop_seat_popup_grab_end(seat);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_pointer_axis(struct weston_pointer_grab *grab,
|
||||
const struct timespec *time,
|
||||
struct weston_pointer_axis_event *event)
|
||||
{
|
||||
weston_pointer_send_axis(grab->pointer, time, event);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_pointer_axis_source(struct weston_pointer_grab *grab,
|
||||
uint32_t source)
|
||||
{
|
||||
weston_pointer_send_axis_source(grab->pointer, source);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_pointer_frame(struct weston_pointer_grab *grab)
|
||||
{
|
||||
weston_pointer_send_frame(grab->pointer);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_pointer_cancel(struct weston_pointer_grab *grab)
|
||||
{
|
||||
struct weston_desktop_seat *seat =
|
||||
wl_container_of(grab, seat, popup_grab.pointer);
|
||||
|
||||
weston_desktop_seat_popup_grab_end(seat);
|
||||
}
|
||||
|
||||
static const struct weston_pointer_grab_interface weston_desktop_seat_pointer_popup_grab_interface = {
|
||||
.focus = weston_desktop_seat_popup_grab_pointer_focus,
|
||||
.motion = weston_desktop_seat_popup_grab_pointer_motion,
|
||||
.button = weston_desktop_seat_popup_grab_pointer_button,
|
||||
.axis = weston_desktop_seat_popup_grab_pointer_axis,
|
||||
.axis_source = weston_desktop_seat_popup_grab_pointer_axis_source,
|
||||
.frame = weston_desktop_seat_popup_grab_pointer_frame,
|
||||
.cancel = weston_desktop_seat_popup_grab_pointer_cancel,
|
||||
};
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_touch_down(struct weston_touch_grab *grab,
|
||||
const struct timespec *time,
|
||||
int touch_id,
|
||||
wl_fixed_t sx, wl_fixed_t sy)
|
||||
{
|
||||
weston_touch_send_down(grab->touch, time, touch_id, sx, sy);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_touch_up(struct weston_touch_grab *grab,
|
||||
const struct timespec *time,
|
||||
int touch_id)
|
||||
{
|
||||
weston_touch_send_up(grab->touch, time, touch_id);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_touch_motion(struct weston_touch_grab *grab,
|
||||
const struct timespec *time,
|
||||
int touch_id,
|
||||
wl_fixed_t sx, wl_fixed_t sy)
|
||||
{
|
||||
weston_touch_send_motion(grab->touch, time, touch_id, sx, sy);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_touch_frame(struct weston_touch_grab *grab)
|
||||
{
|
||||
weston_touch_send_frame(grab->touch);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_touch_cancel(struct weston_touch_grab *grab)
|
||||
{
|
||||
struct weston_desktop_seat *seat =
|
||||
wl_container_of(grab, seat, popup_grab.touch);
|
||||
|
||||
weston_desktop_seat_popup_grab_end(seat);
|
||||
}
|
||||
|
||||
static const struct weston_touch_grab_interface weston_desktop_seat_touch_popup_grab_interface = {
|
||||
.down = weston_desktop_seat_popup_grab_touch_down,
|
||||
.up = weston_desktop_seat_popup_grab_touch_up,
|
||||
.motion = weston_desktop_seat_popup_grab_touch_motion,
|
||||
.frame = weston_desktop_seat_popup_grab_touch_frame,
|
||||
.cancel = weston_desktop_seat_popup_grab_touch_cancel,
|
||||
};
|
||||
|
||||
static void
|
||||
weston_desktop_seat_destroy(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct weston_desktop_seat *seat =
|
||||
wl_container_of(listener, seat, seat_destroy_listener);
|
||||
|
||||
free(seat);
|
||||
}
|
||||
|
||||
struct weston_desktop_seat *
|
||||
weston_desktop_seat_from_seat(struct weston_seat *wseat)
|
||||
{
|
||||
struct wl_listener *listener;
|
||||
struct weston_desktop_seat *seat;
|
||||
|
||||
if (wseat == NULL)
|
||||
return NULL;
|
||||
|
||||
listener = wl_signal_get(&wseat->destroy_signal,
|
||||
weston_desktop_seat_destroy);
|
||||
if (listener != NULL)
|
||||
return wl_container_of(listener, seat, seat_destroy_listener);
|
||||
|
||||
seat = zalloc(sizeof(struct weston_desktop_seat));
|
||||
if (seat == NULL)
|
||||
return NULL;
|
||||
|
||||
seat->seat = wseat;
|
||||
|
||||
seat->seat_destroy_listener.notify = weston_desktop_seat_destroy;
|
||||
wl_signal_add(&wseat->destroy_signal, &seat->seat_destroy_listener);
|
||||
|
||||
seat->popup_grab.keyboard.interface =
|
||||
&weston_desktop_seat_keyboard_popup_grab_interface;
|
||||
seat->popup_grab.pointer.interface =
|
||||
&weston_desktop_seat_pointer_popup_grab_interface;
|
||||
seat->popup_grab.touch.interface =
|
||||
&weston_desktop_seat_touch_popup_grab_interface;
|
||||
wl_list_init(&seat->popup_grab.surfaces);
|
||||
|
||||
return seat;
|
||||
}
|
||||
|
||||
struct weston_desktop_surface *
|
||||
weston_desktop_seat_popup_grab_get_topmost_surface(struct weston_desktop_seat *seat)
|
||||
{
|
||||
if (seat == NULL || wl_list_empty(&seat->popup_grab.surfaces))
|
||||
return NULL;
|
||||
|
||||
struct wl_list *grab_link = seat->popup_grab.surfaces.next;
|
||||
|
||||
return weston_desktop_surface_from_grab_link(grab_link);
|
||||
}
|
||||
|
||||
bool
|
||||
weston_desktop_seat_popup_grab_start(struct weston_desktop_seat *seat,
|
||||
struct wl_client *client, uint32_t serial)
|
||||
{
|
||||
assert(seat == NULL || seat->popup_grab.client == NULL ||
|
||||
seat->popup_grab.client == client);
|
||||
|
||||
struct weston_seat *wseat = seat != NULL ? seat->seat : NULL;
|
||||
/* weston_seat_get_* functions can properly handle a NULL wseat */
|
||||
struct weston_keyboard *keyboard = weston_seat_get_keyboard(wseat);
|
||||
struct weston_pointer *pointer = weston_seat_get_pointer(wseat);
|
||||
struct weston_touch *touch = weston_seat_get_touch(wseat);
|
||||
|
||||
if ((keyboard == NULL || keyboard->grab_serial != serial) &&
|
||||
(pointer == NULL || pointer->grab_serial != serial) &&
|
||||
(touch == NULL || touch->grab_serial != serial)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keyboard != NULL &&
|
||||
keyboard->grab->interface != &weston_desktop_seat_keyboard_popup_grab_interface)
|
||||
weston_keyboard_start_grab(keyboard, &seat->popup_grab.keyboard);
|
||||
|
||||
if (pointer != NULL &&
|
||||
pointer->grab->interface != &weston_desktop_seat_pointer_popup_grab_interface)
|
||||
weston_pointer_start_grab(pointer, &seat->popup_grab.pointer);
|
||||
|
||||
if (touch != NULL &&
|
||||
touch->grab->interface != &weston_desktop_seat_touch_popup_grab_interface)
|
||||
weston_touch_start_grab(touch, &seat->popup_grab.touch);
|
||||
|
||||
seat->popup_grab.initial_up =
|
||||
(pointer == NULL || pointer->button_count == 0);
|
||||
seat->popup_grab.client = client;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_seat_popup_grab_end(struct weston_desktop_seat *seat)
|
||||
{
|
||||
struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat->seat);
|
||||
struct weston_pointer *pointer = weston_seat_get_pointer(seat->seat);
|
||||
struct weston_touch *touch = weston_seat_get_touch(seat->seat);
|
||||
|
||||
while (!wl_list_empty(&seat->popup_grab.surfaces)) {
|
||||
struct wl_list *link = seat->popup_grab.surfaces.prev;
|
||||
struct weston_desktop_surface *surface =
|
||||
weston_desktop_surface_from_grab_link(link);
|
||||
|
||||
wl_list_remove(link);
|
||||
wl_list_init(link);
|
||||
weston_desktop_surface_popup_dismiss(surface);
|
||||
}
|
||||
|
||||
if (keyboard != NULL &&
|
||||
keyboard->grab->interface == &weston_desktop_seat_keyboard_popup_grab_interface)
|
||||
weston_keyboard_end_grab(keyboard);
|
||||
|
||||
if (pointer != NULL &&
|
||||
pointer->grab->interface == &weston_desktop_seat_pointer_popup_grab_interface)
|
||||
weston_pointer_end_grab(pointer);
|
||||
|
||||
if (touch != NULL &&
|
||||
touch->grab->interface == &weston_desktop_seat_touch_popup_grab_interface)
|
||||
weston_touch_end_grab(touch);
|
||||
|
||||
seat->popup_grab.client = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_seat_popup_grab_add_surface(struct weston_desktop_seat *seat,
|
||||
struct wl_list *link)
|
||||
{
|
||||
assert(seat->popup_grab.client != NULL);
|
||||
|
||||
wl_list_insert(&seat->popup_grab.surfaces, link);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_seat_popup_grab_remove_surface(struct weston_desktop_seat *seat,
|
||||
struct wl_list *link)
|
||||
{
|
||||
assert(seat->popup_grab.client != NULL);
|
||||
|
||||
wl_list_remove(link);
|
||||
wl_list_init(link);
|
||||
if (wl_list_empty(&seat->popup_grab.surfaces))
|
||||
weston_desktop_seat_popup_grab_end(seat);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_seat_break_desktop_grabs(struct weston_seat *wseat)
|
||||
{
|
||||
struct weston_desktop_seat *seat = weston_desktop_seat_from_seat(wseat);
|
||||
|
||||
weston_desktop_seat_popup_grab_end(seat);
|
||||
}
|
||||
@@ -0,0 +1,830 @@
|
||||
/*
|
||||
* Copyright © 2016 Quentin "Sardem FF7" Glidic
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include <libweston/libweston.h>
|
||||
#include <libweston/zalloc.h>
|
||||
|
||||
#include <libweston-desktop/libweston-desktop.h>
|
||||
#include "internal.h"
|
||||
|
||||
struct weston_desktop_view {
|
||||
struct wl_list link;
|
||||
struct weston_view *view;
|
||||
struct weston_desktop_view *parent;
|
||||
struct wl_list children_list;
|
||||
struct wl_list children_link;
|
||||
};
|
||||
|
||||
struct weston_desktop_surface {
|
||||
struct weston_desktop *desktop;
|
||||
struct weston_desktop_client *client;
|
||||
struct wl_list client_link;
|
||||
const struct weston_desktop_surface_implementation *implementation;
|
||||
void *implementation_data;
|
||||
void *user_data;
|
||||
struct weston_surface *surface;
|
||||
struct wl_list view_list;
|
||||
struct weston_position buffer_move;
|
||||
struct wl_listener surface_commit_listener;
|
||||
struct wl_listener surface_destroy_listener;
|
||||
struct wl_listener client_destroy_listener;
|
||||
struct wl_list children_list;
|
||||
|
||||
struct wl_list resource_list;
|
||||
bool has_geometry;
|
||||
struct weston_geometry geometry;
|
||||
struct {
|
||||
char *title;
|
||||
char *app_id;
|
||||
pid_t pid;
|
||||
struct wl_signal metadata_signal;
|
||||
};
|
||||
struct {
|
||||
struct weston_desktop_surface *parent;
|
||||
struct wl_list children_link;
|
||||
struct weston_position position;
|
||||
bool use_geometry;
|
||||
};
|
||||
struct {
|
||||
struct wl_list grab_link;
|
||||
};
|
||||
};
|
||||
|
||||
static void
|
||||
weston_desktop_surface_update_view_position(struct weston_desktop_surface *surface)
|
||||
{
|
||||
struct weston_desktop_view *view;
|
||||
int32_t x, y;
|
||||
|
||||
x = surface->position.x;
|
||||
y = surface->position.y;
|
||||
|
||||
if (surface->use_geometry) {
|
||||
struct weston_desktop_surface *parent =
|
||||
weston_desktop_surface_get_parent(surface);
|
||||
struct weston_geometry geometry, parent_geometry;
|
||||
|
||||
geometry = weston_desktop_surface_get_geometry(surface);
|
||||
parent_geometry = weston_desktop_surface_get_geometry(parent);
|
||||
|
||||
x += parent_geometry.x - geometry.x;
|
||||
y += parent_geometry.y - geometry.y;
|
||||
}
|
||||
wl_list_for_each(view, &surface->view_list, link)
|
||||
weston_view_set_position(view->view, x, y);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
weston_desktop_view_propagate_layer(struct weston_desktop_view *view);
|
||||
|
||||
static void
|
||||
weston_desktop_view_destroy(struct weston_desktop_view *view)
|
||||
{
|
||||
struct weston_desktop_view *child_view, *tmp;
|
||||
|
||||
wl_list_for_each_safe(child_view, tmp, &view->children_list, children_link)
|
||||
weston_desktop_view_destroy(child_view);
|
||||
|
||||
wl_list_remove(&view->children_link);
|
||||
wl_list_remove(&view->link);
|
||||
|
||||
weston_view_damage_below(view->view);
|
||||
if (view->parent != NULL)
|
||||
weston_view_destroy(view->view);
|
||||
|
||||
free(view);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_surface_destroy(struct weston_desktop_surface *surface)
|
||||
{
|
||||
struct weston_desktop_view *view, *next_view;
|
||||
struct weston_desktop_surface *child, *next_child;
|
||||
|
||||
wl_list_remove(&surface->surface_commit_listener.link);
|
||||
wl_list_remove(&surface->surface_destroy_listener.link);
|
||||
wl_list_remove(&surface->client_destroy_listener.link);
|
||||
|
||||
if (!wl_list_empty(&surface->resource_list)) {
|
||||
struct wl_resource *resource, *tmp;
|
||||
wl_resource_for_each_safe(resource, tmp, &surface->resource_list) {
|
||||
wl_resource_set_user_data(resource, NULL);
|
||||
wl_list_remove(wl_resource_get_link(resource));
|
||||
}
|
||||
}
|
||||
|
||||
surface->implementation->destroy(surface, surface->implementation_data);
|
||||
|
||||
surface->surface->committed = NULL;
|
||||
surface->surface->committed_private = NULL;
|
||||
|
||||
weston_desktop_surface_unset_relative_to(surface);
|
||||
wl_list_remove(&surface->client_link);
|
||||
|
||||
wl_list_for_each_safe(child, next_child,
|
||||
&surface->children_list,
|
||||
children_link)
|
||||
weston_desktop_surface_unset_relative_to(child);
|
||||
|
||||
wl_list_for_each_safe(view, next_view, &surface->view_list, link)
|
||||
weston_desktop_view_destroy(view);
|
||||
|
||||
free(surface->title);
|
||||
free(surface->app_id);
|
||||
|
||||
free(surface);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_surface_surface_committed(struct wl_listener *listener,
|
||||
void *data)
|
||||
{
|
||||
struct weston_desktop_surface *surface =
|
||||
wl_container_of(listener, surface, surface_commit_listener);
|
||||
|
||||
if (surface->implementation->committed != NULL)
|
||||
surface->implementation->committed(surface,
|
||||
surface->implementation_data,
|
||||
surface->buffer_move.x,
|
||||
surface->buffer_move.y);
|
||||
|
||||
if (surface->parent != NULL) {
|
||||
struct weston_desktop_view *view;
|
||||
|
||||
wl_list_for_each(view, &surface->view_list, link) {
|
||||
weston_view_set_transform_parent(view->view,
|
||||
view->parent->view);
|
||||
weston_desktop_view_propagate_layer(view->parent);
|
||||
}
|
||||
weston_desktop_surface_update_view_position(surface);
|
||||
}
|
||||
|
||||
if (!wl_list_empty(&surface->children_list)) {
|
||||
struct weston_desktop_surface *child;
|
||||
|
||||
wl_list_for_each(child, &surface->children_list, children_link)
|
||||
weston_desktop_surface_update_view_position(child);
|
||||
}
|
||||
|
||||
surface->buffer_move.x = 0;
|
||||
surface->buffer_move.y = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_surface_surface_destroyed(struct wl_listener *listener,
|
||||
void *data)
|
||||
{
|
||||
struct weston_desktop_surface *surface =
|
||||
wl_container_of(listener, surface, surface_destroy_listener);
|
||||
|
||||
weston_desktop_surface_destroy(surface);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_surface_resource_destroy(struct wl_resource *resource)
|
||||
{
|
||||
struct weston_desktop_surface *surface =
|
||||
wl_resource_get_user_data(resource);
|
||||
|
||||
if (surface != NULL)
|
||||
weston_desktop_surface_destroy(surface);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_surface_committed(struct weston_surface *wsurface,
|
||||
int32_t sx, int32_t sy)
|
||||
{
|
||||
struct weston_desktop_surface *surface = wsurface->committed_private;
|
||||
|
||||
surface->buffer_move.x = sx;
|
||||
surface->buffer_move.y = sy;
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_surface_client_destroyed(struct wl_listener *listener,
|
||||
void *data)
|
||||
{
|
||||
struct weston_desktop_surface *surface =
|
||||
wl_container_of(listener, surface, client_destroy_listener);
|
||||
|
||||
weston_desktop_surface_destroy(surface);
|
||||
}
|
||||
|
||||
struct weston_desktop_surface *
|
||||
weston_desktop_surface_create(struct weston_desktop *desktop,
|
||||
struct weston_desktop_client *client,
|
||||
struct weston_surface *wsurface,
|
||||
const struct weston_desktop_surface_implementation *implementation,
|
||||
void *implementation_data)
|
||||
{
|
||||
assert(implementation->destroy != NULL);
|
||||
|
||||
struct weston_desktop_surface *surface;
|
||||
|
||||
surface = zalloc(sizeof(struct weston_desktop_surface));
|
||||
if (surface == NULL) {
|
||||
if (client != NULL)
|
||||
wl_client_post_no_memory(weston_desktop_client_get_client(client));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface->desktop = desktop;
|
||||
surface->implementation = implementation;
|
||||
surface->implementation_data = implementation_data;
|
||||
surface->surface = wsurface;
|
||||
|
||||
surface->client = client;
|
||||
surface->client_destroy_listener.notify =
|
||||
weston_desktop_surface_client_destroyed;
|
||||
weston_desktop_client_add_destroy_listener(
|
||||
client, &surface->client_destroy_listener);
|
||||
|
||||
wsurface->committed = weston_desktop_surface_committed;
|
||||
wsurface->committed_private = surface;
|
||||
|
||||
surface->pid = -1;
|
||||
|
||||
surface->surface_commit_listener.notify =
|
||||
weston_desktop_surface_surface_committed;
|
||||
wl_signal_add(&surface->surface->commit_signal,
|
||||
&surface->surface_commit_listener);
|
||||
surface->surface_destroy_listener.notify =
|
||||
weston_desktop_surface_surface_destroyed;
|
||||
wl_signal_add(&surface->surface->destroy_signal,
|
||||
&surface->surface_destroy_listener);
|
||||
|
||||
wl_list_init(&surface->client_link);
|
||||
wl_list_init(&surface->resource_list);
|
||||
wl_list_init(&surface->children_list);
|
||||
wl_list_init(&surface->children_link);
|
||||
wl_list_init(&surface->view_list);
|
||||
wl_list_init(&surface->grab_link);
|
||||
|
||||
wl_signal_init(&surface->metadata_signal);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
struct wl_resource *
|
||||
weston_desktop_surface_add_resource(struct weston_desktop_surface *surface,
|
||||
const struct wl_interface *interface,
|
||||
const void *implementation, uint32_t id,
|
||||
wl_resource_destroy_func_t destroy)
|
||||
{
|
||||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(surface->client);
|
||||
struct wl_client *wl_client =
|
||||
weston_desktop_client_get_client(surface->client);
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create(wl_client,
|
||||
interface,
|
||||
wl_resource_get_version(client_resource),
|
||||
id);
|
||||
if (resource == NULL) {
|
||||
wl_client_post_no_memory(wl_client);
|
||||
weston_desktop_surface_destroy(surface);
|
||||
return NULL;
|
||||
}
|
||||
if (destroy == NULL)
|
||||
destroy = weston_desktop_surface_resource_destroy;
|
||||
wl_resource_set_implementation(resource, implementation, surface, destroy);
|
||||
wl_list_insert(&surface->resource_list, wl_resource_get_link(resource));
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
struct weston_desktop_surface *
|
||||
weston_desktop_surface_from_grab_link(struct wl_list *grab_link)
|
||||
{
|
||||
struct weston_desktop_surface *surface =
|
||||
wl_container_of(grab_link, surface, grab_link);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
WL_EXPORT bool
|
||||
weston_surface_is_desktop_surface(struct weston_surface *wsurface)
|
||||
{
|
||||
return wsurface->committed == weston_desktop_surface_committed;
|
||||
}
|
||||
|
||||
WL_EXPORT struct weston_desktop_surface *
|
||||
weston_surface_get_desktop_surface(struct weston_surface *wsurface)
|
||||
{
|
||||
if (!weston_surface_is_desktop_surface(wsurface))
|
||||
return NULL;
|
||||
return wsurface->committed_private;
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_surface_set_user_data(struct weston_desktop_surface *surface,
|
||||
void *user_data)
|
||||
{
|
||||
surface->user_data = user_data;
|
||||
}
|
||||
|
||||
static struct weston_desktop_view *
|
||||
weston_desktop_surface_create_desktop_view(struct weston_desktop_surface *surface)
|
||||
{
|
||||
struct wl_client *wl_client=
|
||||
weston_desktop_client_get_client(surface->client);
|
||||
struct weston_desktop_view *view, *child_view;
|
||||
struct weston_view *wview;
|
||||
struct weston_desktop_surface *child;
|
||||
|
||||
wview = weston_view_create(surface->surface);
|
||||
if (wview == NULL) {
|
||||
if (wl_client != NULL)
|
||||
wl_client_post_no_memory(wl_client);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
view = zalloc(sizeof(struct weston_desktop_view));
|
||||
if (view == NULL) {
|
||||
if (wl_client != NULL)
|
||||
wl_client_post_no_memory(wl_client);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
view->view = wview;
|
||||
wl_list_init(&view->children_list);
|
||||
wl_list_init(&view->children_link);
|
||||
wl_list_insert(surface->view_list.prev, &view->link);
|
||||
|
||||
wl_list_for_each(child, &surface->children_list, children_link) {
|
||||
child_view =
|
||||
weston_desktop_surface_create_desktop_view(child);
|
||||
if (child_view == NULL) {
|
||||
weston_desktop_view_destroy(view);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
child_view->parent = view;
|
||||
wl_list_insert(view->children_list.prev,
|
||||
&child_view->children_link);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
WL_EXPORT struct weston_view *
|
||||
weston_desktop_surface_create_view(struct weston_desktop_surface *surface)
|
||||
{
|
||||
struct weston_desktop_view *view;
|
||||
|
||||
view = weston_desktop_surface_create_desktop_view(surface);
|
||||
if (view == NULL)
|
||||
return NULL;
|
||||
|
||||
return view->view;
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_surface_unlink_view(struct weston_view *wview)
|
||||
{
|
||||
struct weston_desktop_surface *surface;
|
||||
struct weston_desktop_view *view;
|
||||
|
||||
if (!weston_surface_is_desktop_surface(wview->surface))
|
||||
return;
|
||||
|
||||
surface = weston_surface_get_desktop_surface(wview->surface);
|
||||
wl_list_for_each(view, &surface->view_list, link) {
|
||||
if (view->view == wview) {
|
||||
weston_desktop_view_destroy(view);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_view_propagate_layer(struct weston_desktop_view *view)
|
||||
{
|
||||
struct weston_desktop_view *child;
|
||||
struct wl_list *link = &view->view->layer_link.link;
|
||||
|
||||
wl_list_for_each_reverse(child, &view->children_list, children_link) {
|
||||
struct weston_layer_entry *prev =
|
||||
wl_container_of(link->prev, prev, link);
|
||||
|
||||
if (prev == &child->view->layer_link)
|
||||
continue;
|
||||
|
||||
child->view->is_mapped = true;
|
||||
weston_view_damage_below(child->view);
|
||||
weston_view_geometry_dirty(child->view);
|
||||
weston_layer_entry_remove(&child->view->layer_link);
|
||||
weston_layer_entry_insert(prev, &child->view->layer_link);
|
||||
weston_view_geometry_dirty(child->view);
|
||||
weston_surface_damage(child->view->surface);
|
||||
weston_view_update_transform(child->view);
|
||||
|
||||
weston_desktop_view_propagate_layer(child);
|
||||
}
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_surface_propagate_layer(struct weston_desktop_surface *surface)
|
||||
{
|
||||
struct weston_desktop_view *view;
|
||||
|
||||
wl_list_for_each(view, &surface->view_list, link)
|
||||
weston_desktop_view_propagate_layer(view);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_surface_set_activated(struct weston_desktop_surface *surface, bool activated)
|
||||
{
|
||||
if (surface->implementation->set_activated != NULL)
|
||||
surface->implementation->set_activated(surface,
|
||||
surface->implementation_data,
|
||||
activated);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_surface_set_fullscreen(struct weston_desktop_surface *surface, bool fullscreen)
|
||||
{
|
||||
if (surface->implementation->set_fullscreen != NULL)
|
||||
surface->implementation->set_fullscreen(surface,
|
||||
surface->implementation_data,
|
||||
fullscreen);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_surface_set_maximized(struct weston_desktop_surface *surface, bool maximized)
|
||||
{
|
||||
if (surface->implementation->set_maximized != NULL)
|
||||
surface->implementation->set_maximized(surface,
|
||||
surface->implementation_data,
|
||||
maximized);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_surface_set_resizing(struct weston_desktop_surface *surface, bool resizing)
|
||||
{
|
||||
if (surface->implementation->set_resizing != NULL)
|
||||
surface->implementation->set_resizing(surface,
|
||||
surface->implementation_data,
|
||||
resizing);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_surface_set_size(struct weston_desktop_surface *surface, int32_t width, int32_t height)
|
||||
{
|
||||
if (surface->implementation->set_size != NULL)
|
||||
surface->implementation->set_size(surface,
|
||||
surface->implementation_data,
|
||||
width, height);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_surface_close(struct weston_desktop_surface *surface)
|
||||
{
|
||||
if (surface->implementation->close != NULL)
|
||||
surface->implementation->close(surface,
|
||||
surface->implementation_data);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_desktop_surface_add_metadata_listener(struct weston_desktop_surface *surface,
|
||||
struct wl_listener *listener)
|
||||
{
|
||||
wl_signal_add(&surface->metadata_signal, listener);
|
||||
}
|
||||
|
||||
struct weston_desktop_surface *
|
||||
weston_desktop_surface_from_client_link(struct wl_list *link)
|
||||
{
|
||||
struct weston_desktop_surface *surface;
|
||||
|
||||
surface = wl_container_of(link, surface, client_link);
|
||||
return surface;
|
||||
}
|
||||
|
||||
struct wl_list *
|
||||
weston_desktop_surface_get_client_link(struct weston_desktop_surface *surface)
|
||||
{
|
||||
return &surface->client_link;
|
||||
}
|
||||
|
||||
bool
|
||||
weston_desktop_surface_has_implementation(struct weston_desktop_surface *surface,
|
||||
const struct weston_desktop_surface_implementation *implementation)
|
||||
{
|
||||
return surface->implementation == implementation;
|
||||
}
|
||||
|
||||
const struct weston_desktop_surface_implementation *
|
||||
weston_desktop_surface_get_implementation(struct weston_desktop_surface *surface)
|
||||
{
|
||||
return surface->implementation;
|
||||
}
|
||||
|
||||
void *
|
||||
weston_desktop_surface_get_implementation_data(struct weston_desktop_surface *surface)
|
||||
{
|
||||
return surface->implementation_data;
|
||||
}
|
||||
|
||||
struct weston_desktop_surface *
|
||||
weston_desktop_surface_get_parent(struct weston_desktop_surface *surface)
|
||||
{
|
||||
return surface->parent;
|
||||
}
|
||||
|
||||
bool
|
||||
weston_desktop_surface_get_grab(struct weston_desktop_surface *surface)
|
||||
{
|
||||
return !wl_list_empty(&surface->grab_link);
|
||||
}
|
||||
|
||||
WL_EXPORT struct weston_desktop_client *
|
||||
weston_desktop_surface_get_client(struct weston_desktop_surface *surface)
|
||||
{
|
||||
return surface->client;
|
||||
}
|
||||
|
||||
WL_EXPORT void *
|
||||
weston_desktop_surface_get_user_data(struct weston_desktop_surface *surface)
|
||||
{
|
||||
return surface->user_data;
|
||||
}
|
||||
|
||||
WL_EXPORT struct weston_surface *
|
||||
weston_desktop_surface_get_surface(struct weston_desktop_surface *surface)
|
||||
{
|
||||
return surface->surface;
|
||||
}
|
||||
|
||||
WL_EXPORT const char *
|
||||
weston_desktop_surface_get_title(struct weston_desktop_surface *surface)
|
||||
{
|
||||
return surface->title;
|
||||
}
|
||||
|
||||
WL_EXPORT const char *
|
||||
weston_desktop_surface_get_app_id(struct weston_desktop_surface *surface)
|
||||
{
|
||||
return surface->app_id;
|
||||
}
|
||||
|
||||
WL_EXPORT pid_t
|
||||
weston_desktop_surface_get_pid(struct weston_desktop_surface *surface)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
if (surface->pid != -1) {
|
||||
pid = surface->pid;
|
||||
} else {
|
||||
struct weston_desktop_client *client =
|
||||
weston_desktop_surface_get_client(surface);
|
||||
struct wl_client *wl_client =
|
||||
weston_desktop_client_get_client(client);
|
||||
|
||||
/* wl_client should always be valid, because only in the
|
||||
* xwayland case it wouldn't be, but in that case we won't
|
||||
* reach here, as the pid is initialized to 0. */
|
||||
assert(wl_client);
|
||||
wl_client_get_credentials(wl_client, &pid, NULL, NULL);
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
WL_EXPORT bool
|
||||
weston_desktop_surface_get_activated(struct weston_desktop_surface *surface)
|
||||
{
|
||||
if (surface->implementation->get_activated == NULL)
|
||||
return false;
|
||||
return surface->implementation->get_activated(surface,
|
||||
surface->implementation_data);
|
||||
}
|
||||
|
||||
WL_EXPORT bool
|
||||
weston_desktop_surface_get_resizing(struct weston_desktop_surface *surface)
|
||||
{
|
||||
if (surface->implementation->get_resizing == NULL)
|
||||
return false;
|
||||
return surface->implementation->get_resizing(surface,
|
||||
surface->implementation_data);
|
||||
}
|
||||
|
||||
WL_EXPORT bool
|
||||
weston_desktop_surface_get_maximized(struct weston_desktop_surface *surface)
|
||||
{
|
||||
if (surface->implementation->get_maximized == NULL)
|
||||
return false;
|
||||
return surface->implementation->get_maximized(surface,
|
||||
surface->implementation_data);
|
||||
}
|
||||
|
||||
WL_EXPORT bool
|
||||
weston_desktop_surface_get_fullscreen(struct weston_desktop_surface *surface)
|
||||
{
|
||||
if (surface->implementation->get_fullscreen == NULL)
|
||||
return false;
|
||||
return surface->implementation->get_fullscreen(surface,
|
||||
surface->implementation_data);
|
||||
}
|
||||
|
||||
WL_EXPORT struct weston_geometry
|
||||
weston_desktop_surface_get_geometry(struct weston_desktop_surface *surface)
|
||||
{
|
||||
if (surface->has_geometry)
|
||||
return surface->geometry;
|
||||
return weston_surface_get_bounding_box(surface->surface);
|
||||
}
|
||||
|
||||
WL_EXPORT struct weston_size
|
||||
weston_desktop_surface_get_max_size(struct weston_desktop_surface *surface)
|
||||
{
|
||||
struct weston_size size = { 0, 0 };
|
||||
|
||||
if (surface->implementation->get_max_size == NULL)
|
||||
return size;
|
||||
return surface->implementation->get_max_size(surface,
|
||||
surface->implementation_data);
|
||||
}
|
||||
|
||||
WL_EXPORT struct weston_size
|
||||
weston_desktop_surface_get_min_size(struct weston_desktop_surface *surface)
|
||||
{
|
||||
struct weston_size size = { 0, 0 };
|
||||
|
||||
if (surface->implementation->get_min_size == NULL)
|
||||
return size;
|
||||
return surface->implementation->get_min_size(surface,
|
||||
surface->implementation_data);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_surface_set_title(struct weston_desktop_surface *surface,
|
||||
const char *title)
|
||||
{
|
||||
char *tmp, *old;
|
||||
|
||||
tmp = strdup(title);
|
||||
if (tmp == NULL)
|
||||
return;
|
||||
|
||||
old = surface->title;
|
||||
surface->title = tmp;
|
||||
wl_signal_emit(&surface->metadata_signal, surface);
|
||||
free(old);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_surface_set_app_id(struct weston_desktop_surface *surface,
|
||||
const char *app_id)
|
||||
{
|
||||
char *tmp, *old;
|
||||
|
||||
tmp = strdup(app_id);
|
||||
if (tmp == NULL)
|
||||
return;
|
||||
|
||||
old = surface->app_id;
|
||||
surface->app_id = tmp;
|
||||
wl_signal_emit(&surface->metadata_signal, surface);
|
||||
free(old);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_surface_set_pid(struct weston_desktop_surface *surface,
|
||||
pid_t pid)
|
||||
{
|
||||
surface->pid = pid;
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_surface_set_geometry(struct weston_desktop_surface *surface,
|
||||
struct weston_geometry geometry)
|
||||
{
|
||||
surface->has_geometry = true;
|
||||
surface->geometry = geometry;
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_surface_set_relative_to(struct weston_desktop_surface *surface,
|
||||
struct weston_desktop_surface *parent,
|
||||
int32_t x, int32_t y, bool use_geometry)
|
||||
{
|
||||
struct weston_desktop_view *view, *parent_view;
|
||||
struct wl_list *link, *tmp;
|
||||
|
||||
assert(parent);
|
||||
|
||||
surface->position.x = x;
|
||||
surface->position.y = y;
|
||||
surface->use_geometry = use_geometry;
|
||||
|
||||
if (surface->parent == parent)
|
||||
return;
|
||||
|
||||
surface->parent = parent;
|
||||
wl_list_remove(&surface->children_link);
|
||||
wl_list_insert(surface->parent->children_list.prev,
|
||||
&surface->children_link);
|
||||
|
||||
link = surface->view_list.next;
|
||||
tmp = link->next;
|
||||
wl_list_for_each(parent_view, &parent->view_list, link) {
|
||||
if (link == &surface->view_list) {
|
||||
view = weston_desktop_surface_create_desktop_view(surface);
|
||||
if (view == NULL)
|
||||
return;
|
||||
tmp = &surface->view_list;
|
||||
} else {
|
||||
view = wl_container_of(link, view, link);
|
||||
wl_list_remove(&view->children_link);
|
||||
}
|
||||
|
||||
view->parent = parent_view;
|
||||
wl_list_insert(parent_view->children_list.prev,
|
||||
&view->children_link);
|
||||
weston_desktop_view_propagate_layer(view);
|
||||
|
||||
link = tmp;
|
||||
tmp = link->next;
|
||||
}
|
||||
for (; link != &surface->view_list; link = tmp, tmp = link->next) {
|
||||
view = wl_container_of(link, view, link);
|
||||
weston_desktop_view_destroy(view);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_surface_unset_relative_to(struct weston_desktop_surface *surface)
|
||||
{
|
||||
struct weston_desktop_view *view, *tmp;
|
||||
|
||||
if (surface->parent == NULL)
|
||||
return;
|
||||
|
||||
surface->parent = NULL;
|
||||
wl_list_remove(&surface->children_link);
|
||||
wl_list_init(&surface->children_link);
|
||||
|
||||
wl_list_for_each_safe(view, tmp, &surface->view_list, link)
|
||||
weston_desktop_view_destroy(view);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_surface_popup_grab(struct weston_desktop_surface *surface,
|
||||
struct weston_desktop_seat *seat,
|
||||
uint32_t serial)
|
||||
{
|
||||
struct wl_client *wl_client =
|
||||
weston_desktop_client_get_client(surface->client);
|
||||
if (weston_desktop_seat_popup_grab_start(seat, wl_client, serial))
|
||||
weston_desktop_seat_popup_grab_add_surface(seat, &surface->grab_link);
|
||||
else
|
||||
weston_desktop_surface_popup_dismiss(surface);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_surface_popup_ungrab(struct weston_desktop_surface *surface,
|
||||
struct weston_desktop_seat *seat)
|
||||
{
|
||||
weston_desktop_seat_popup_grab_remove_surface(seat, &surface->grab_link);
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_surface_popup_dismiss(struct weston_desktop_surface *surface)
|
||||
{
|
||||
struct weston_desktop_view *view, *tmp;
|
||||
|
||||
wl_list_for_each_safe(view, tmp, &surface->view_list, link)
|
||||
weston_desktop_view_destroy(view);
|
||||
wl_list_remove(&surface->grab_link);
|
||||
wl_list_init(&surface->grab_link);
|
||||
weston_desktop_surface_close(surface);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,470 @@
|
||||
/*
|
||||
* Copyright © 2010-2012 Intel Corporation
|
||||
* Copyright © 2011-2012 Collabora, Ltd.
|
||||
* Copyright © 2013 Raspberry Pi Foundation
|
||||
* Copyright © 2016 Quentin "Sardem FF7" Glidic
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include <libweston/libweston.h>
|
||||
#include <libweston/zalloc.h>
|
||||
|
||||
#include <libweston-desktop/libweston-desktop.h>
|
||||
#include "internal.h"
|
||||
#include "xwayland/xwayland-internal-interface.h"
|
||||
|
||||
enum weston_desktop_xwayland_surface_state {
|
||||
NONE,
|
||||
TOPLEVEL,
|
||||
MAXIMIZED,
|
||||
FULLSCREEN,
|
||||
TRANSIENT,
|
||||
XWAYLAND,
|
||||
};
|
||||
|
||||
struct weston_desktop_xwayland {
|
||||
struct weston_desktop *desktop;
|
||||
struct weston_desktop_client *client;
|
||||
struct weston_layer layer;
|
||||
};
|
||||
|
||||
struct weston_desktop_xwayland_surface {
|
||||
struct weston_desktop_xwayland *xwayland;
|
||||
struct weston_desktop *desktop;
|
||||
struct weston_desktop_surface *surface;
|
||||
struct wl_listener resource_destroy_listener;
|
||||
struct weston_view *view;
|
||||
const struct weston_xwayland_client_interface *client_interface;
|
||||
struct weston_geometry next_geometry;
|
||||
bool has_next_geometry;
|
||||
bool committed;
|
||||
bool added;
|
||||
enum weston_desktop_xwayland_surface_state state;
|
||||
enum weston_desktop_xwayland_surface_state prev_state;
|
||||
};
|
||||
|
||||
static void
|
||||
weston_desktop_xwayland_surface_change_state(struct weston_desktop_xwayland_surface *surface,
|
||||
enum weston_desktop_xwayland_surface_state state,
|
||||
struct weston_desktop_surface *parent,
|
||||
int32_t x, int32_t y)
|
||||
{
|
||||
struct weston_surface *wsurface;
|
||||
bool to_add = (parent == NULL && state != XWAYLAND);
|
||||
|
||||
assert(state != NONE);
|
||||
assert(!parent || state == TRANSIENT);
|
||||
|
||||
if (to_add && surface->added) {
|
||||
surface->state = state;
|
||||
return;
|
||||
}
|
||||
|
||||
wsurface = weston_desktop_surface_get_surface(surface->surface);
|
||||
|
||||
if (surface->state != state) {
|
||||
if (surface->state == XWAYLAND) {
|
||||
assert(!surface->added);
|
||||
|
||||
weston_desktop_surface_unlink_view(surface->view);
|
||||
weston_view_destroy(surface->view);
|
||||
surface->view = NULL;
|
||||
weston_surface_unmap(wsurface);
|
||||
}
|
||||
|
||||
if (to_add) {
|
||||
weston_desktop_surface_unset_relative_to(surface->surface);
|
||||
weston_desktop_api_surface_added(surface->desktop,
|
||||
surface->surface);
|
||||
surface->added = true;
|
||||
if (surface->state == NONE && surface->committed)
|
||||
/* We had a race, and wl_surface.commit() was
|
||||
* faster, just fake a commit to map the
|
||||
* surface */
|
||||
weston_desktop_api_committed(surface->desktop,
|
||||
surface->surface,
|
||||
0, 0);
|
||||
|
||||
} else if (surface->added) {
|
||||
weston_desktop_api_surface_removed(surface->desktop,
|
||||
surface->surface);
|
||||
surface->added = false;
|
||||
}
|
||||
|
||||
if (state == XWAYLAND) {
|
||||
assert(!surface->added);
|
||||
|
||||
surface->view =
|
||||
weston_desktop_surface_create_view(surface->surface);
|
||||
weston_layer_entry_insert(&surface->xwayland->layer.view_list,
|
||||
&surface->view->layer_link);
|
||||
surface->view->is_mapped = true;
|
||||
weston_surface_map(wsurface);
|
||||
}
|
||||
|
||||
surface->state = state;
|
||||
}
|
||||
|
||||
if (parent != NULL)
|
||||
weston_desktop_surface_set_relative_to(surface->surface, parent,
|
||||
x, y, false);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_xwayland_surface_committed(struct weston_desktop_surface *dsurface,
|
||||
void *user_data,
|
||||
int32_t sx, int32_t sy)
|
||||
{
|
||||
struct weston_desktop_xwayland_surface *surface = user_data;
|
||||
struct weston_geometry oldgeom;
|
||||
|
||||
assert(dsurface == surface->surface);
|
||||
surface->committed = true;
|
||||
|
||||
#ifdef WM_DEBUG
|
||||
weston_log("%s: xwayland surface %p\n", __func__, surface);
|
||||
#endif
|
||||
|
||||
if (surface->has_next_geometry) {
|
||||
oldgeom = weston_desktop_surface_get_geometry(surface->surface);
|
||||
/* If we're transitioning away from fullscreen or maximized
|
||||
* we've moved to old saved co-ordinates that were saved
|
||||
* with window geometry in place, so avoid adajusting by
|
||||
* the geometry in those cases.
|
||||
*/
|
||||
if (surface->state == surface->prev_state) {
|
||||
sx -= surface->next_geometry.x - oldgeom.x;
|
||||
sy -= surface->next_geometry.y - oldgeom.y;
|
||||
}
|
||||
surface->prev_state = surface->state;
|
||||
|
||||
surface->has_next_geometry = false;
|
||||
weston_desktop_surface_set_geometry(surface->surface,
|
||||
surface->next_geometry);
|
||||
}
|
||||
|
||||
if (surface->added)
|
||||
weston_desktop_api_committed(surface->desktop, surface->surface,
|
||||
sx, sy);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_xwayland_surface_set_size(struct weston_desktop_surface *dsurface,
|
||||
void *user_data,
|
||||
int32_t width, int32_t height)
|
||||
{
|
||||
struct weston_desktop_xwayland_surface *surface = user_data;
|
||||
struct weston_surface *wsurface =
|
||||
weston_desktop_surface_get_surface(surface->surface);
|
||||
|
||||
surface->client_interface->send_configure(wsurface, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_xwayland_surface_destroy(struct weston_desktop_surface *dsurface,
|
||||
void *user_data)
|
||||
{
|
||||
struct weston_desktop_xwayland_surface *surface = user_data;
|
||||
|
||||
wl_list_remove(&surface->resource_destroy_listener.link);
|
||||
|
||||
weston_desktop_surface_unset_relative_to(surface->surface);
|
||||
if (surface->added)
|
||||
weston_desktop_api_surface_removed(surface->desktop,
|
||||
surface->surface);
|
||||
else if (surface->state == XWAYLAND)
|
||||
weston_desktop_surface_unlink_view(surface->view);
|
||||
|
||||
free(surface);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_xwayland_surface_close(struct weston_desktop_surface *dsurface,
|
||||
void *user_data)
|
||||
{
|
||||
struct weston_desktop_xwayland_surface *surface = user_data;
|
||||
struct weston_surface *wsurface =
|
||||
weston_desktop_surface_get_surface(surface->surface);
|
||||
|
||||
surface->client_interface->send_close(wsurface);
|
||||
}
|
||||
|
||||
static bool
|
||||
weston_desktop_xwayland_surface_get_maximized(struct weston_desktop_surface *dsurface,
|
||||
void *user_data)
|
||||
{
|
||||
struct weston_desktop_xwayland_surface *surface = user_data;
|
||||
|
||||
return surface->state == MAXIMIZED;
|
||||
}
|
||||
|
||||
static bool
|
||||
weston_desktop_xwayland_surface_get_fullscreen(struct weston_desktop_surface *dsurface,
|
||||
void *user_data)
|
||||
{
|
||||
struct weston_desktop_xwayland_surface *surface = user_data;
|
||||
|
||||
return surface->state == FULLSCREEN;
|
||||
}
|
||||
|
||||
static const struct weston_desktop_surface_implementation weston_desktop_xwayland_surface_internal_implementation = {
|
||||
.committed = weston_desktop_xwayland_surface_committed,
|
||||
.set_size = weston_desktop_xwayland_surface_set_size,
|
||||
|
||||
.get_maximized = weston_desktop_xwayland_surface_get_maximized,
|
||||
.get_fullscreen = weston_desktop_xwayland_surface_get_fullscreen,
|
||||
|
||||
.destroy = weston_desktop_xwayland_surface_destroy,
|
||||
.close = weston_desktop_xwayland_surface_close,
|
||||
};
|
||||
|
||||
static void
|
||||
weston_destop_xwayland_resource_destroyed(struct wl_listener *listener,
|
||||
void *data)
|
||||
{
|
||||
struct weston_desktop_xwayland_surface *surface =
|
||||
wl_container_of(listener, surface, resource_destroy_listener);
|
||||
|
||||
weston_desktop_surface_destroy(surface->surface);
|
||||
}
|
||||
|
||||
static struct weston_desktop_xwayland_surface *
|
||||
create_surface(struct weston_desktop_xwayland *xwayland,
|
||||
struct weston_surface *wsurface,
|
||||
const struct weston_xwayland_client_interface *client_interface)
|
||||
{
|
||||
struct weston_desktop_xwayland_surface *surface;
|
||||
|
||||
surface = zalloc(sizeof(struct weston_desktop_xwayland_surface));
|
||||
if (surface == NULL)
|
||||
return NULL;
|
||||
|
||||
surface->xwayland = xwayland;
|
||||
surface->desktop = xwayland->desktop;
|
||||
surface->client_interface = client_interface;
|
||||
|
||||
surface->surface =
|
||||
weston_desktop_surface_create(surface->desktop,
|
||||
xwayland->client, wsurface,
|
||||
&weston_desktop_xwayland_surface_internal_implementation,
|
||||
surface);
|
||||
if (surface->surface == NULL) {
|
||||
free(surface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface->resource_destroy_listener.notify =
|
||||
weston_destop_xwayland_resource_destroyed;
|
||||
wl_resource_add_destroy_listener(wsurface->resource,
|
||||
&surface->resource_destroy_listener);
|
||||
|
||||
weston_desktop_surface_set_pid(surface->surface, 0);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
set_toplevel(struct weston_desktop_xwayland_surface *surface)
|
||||
{
|
||||
weston_desktop_xwayland_surface_change_state(surface, TOPLEVEL, NULL,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
set_toplevel_with_position(struct weston_desktop_xwayland_surface *surface,
|
||||
int32_t x, int32_t y)
|
||||
{
|
||||
weston_desktop_xwayland_surface_change_state(surface, TOPLEVEL, NULL,
|
||||
0, 0);
|
||||
weston_desktop_api_set_xwayland_position(surface->desktop,
|
||||
surface->surface, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
set_parent(struct weston_desktop_xwayland_surface *surface,
|
||||
struct weston_surface *wparent)
|
||||
{
|
||||
struct weston_desktop_surface *parent;
|
||||
|
||||
if (!weston_surface_is_desktop_surface(wparent))
|
||||
return;
|
||||
|
||||
parent = weston_surface_get_desktop_surface(wparent);
|
||||
weston_desktop_api_set_parent(surface->desktop, surface->surface, parent);
|
||||
}
|
||||
|
||||
static void
|
||||
set_transient(struct weston_desktop_xwayland_surface *surface,
|
||||
struct weston_surface *wparent, int x, int y)
|
||||
{
|
||||
struct weston_desktop_surface *parent;
|
||||
|
||||
if (!weston_surface_is_desktop_surface(wparent))
|
||||
return;
|
||||
|
||||
parent = weston_surface_get_desktop_surface(wparent);
|
||||
weston_desktop_xwayland_surface_change_state(surface, TRANSIENT, parent,
|
||||
x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
set_fullscreen(struct weston_desktop_xwayland_surface *surface,
|
||||
struct weston_output *output)
|
||||
{
|
||||
weston_desktop_xwayland_surface_change_state(surface, FULLSCREEN, NULL,
|
||||
0, 0);
|
||||
weston_desktop_api_fullscreen_requested(surface->desktop,
|
||||
surface->surface, true, output);
|
||||
}
|
||||
|
||||
static void
|
||||
set_xwayland(struct weston_desktop_xwayland_surface *surface, int x, int y)
|
||||
{
|
||||
weston_desktop_xwayland_surface_change_state(surface, XWAYLAND, NULL,
|
||||
x, y);
|
||||
weston_view_set_position(surface->view, x, y);
|
||||
}
|
||||
|
||||
static int
|
||||
move(struct weston_desktop_xwayland_surface *surface,
|
||||
struct weston_pointer *pointer)
|
||||
{
|
||||
if (surface->state == TOPLEVEL ||
|
||||
surface->state == MAXIMIZED ||
|
||||
surface->state == FULLSCREEN)
|
||||
weston_desktop_api_move(surface->desktop, surface->surface,
|
||||
pointer->seat, pointer->grab_serial);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
resize(struct weston_desktop_xwayland_surface *surface,
|
||||
struct weston_pointer *pointer, uint32_t edges)
|
||||
{
|
||||
if (surface->state == TOPLEVEL ||
|
||||
surface->state == MAXIMIZED ||
|
||||
surface->state == FULLSCREEN)
|
||||
weston_desktop_api_resize(surface->desktop, surface->surface,
|
||||
pointer->seat, pointer->grab_serial,
|
||||
edges);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
set_title(struct weston_desktop_xwayland_surface *surface, const char *title)
|
||||
{
|
||||
weston_desktop_surface_set_title(surface->surface, title);
|
||||
}
|
||||
|
||||
static void
|
||||
set_window_geometry(struct weston_desktop_xwayland_surface *surface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
{
|
||||
surface->has_next_geometry = true;
|
||||
surface->next_geometry.x = x;
|
||||
surface->next_geometry.y = y;
|
||||
surface->next_geometry.width = width;
|
||||
surface->next_geometry.height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
set_maximized(struct weston_desktop_xwayland_surface *surface)
|
||||
{
|
||||
weston_desktop_xwayland_surface_change_state(surface, MAXIMIZED, NULL,
|
||||
0, 0);
|
||||
weston_desktop_api_maximized_requested(surface->desktop,
|
||||
surface->surface, true);
|
||||
}
|
||||
|
||||
static void
|
||||
set_minimized(struct weston_desktop_xwayland_surface *surface)
|
||||
{
|
||||
weston_desktop_api_minimized_requested(surface->desktop,
|
||||
surface->surface);
|
||||
}
|
||||
|
||||
static void
|
||||
set_pid(struct weston_desktop_xwayland_surface *surface, pid_t pid)
|
||||
{
|
||||
weston_desktop_surface_set_pid(surface->surface, pid);
|
||||
}
|
||||
|
||||
static const struct weston_desktop_xwayland_interface weston_desktop_xwayland_interface = {
|
||||
.create_surface = create_surface,
|
||||
.set_toplevel = set_toplevel,
|
||||
.set_toplevel_with_position = set_toplevel_with_position,
|
||||
.set_parent = set_parent,
|
||||
.set_transient = set_transient,
|
||||
.set_fullscreen = set_fullscreen,
|
||||
.set_xwayland = set_xwayland,
|
||||
.move = move,
|
||||
.resize = resize,
|
||||
.set_title = set_title,
|
||||
.set_window_geometry = set_window_geometry,
|
||||
.set_maximized = set_maximized,
|
||||
.set_minimized = set_minimized,
|
||||
.set_pid = set_pid,
|
||||
};
|
||||
|
||||
void
|
||||
weston_desktop_xwayland_init(struct weston_desktop *desktop)
|
||||
{
|
||||
struct weston_compositor *compositor = weston_desktop_get_compositor(desktop);
|
||||
struct weston_desktop_xwayland *xwayland;
|
||||
|
||||
xwayland = zalloc(sizeof(struct weston_desktop_xwayland));
|
||||
if (xwayland == NULL)
|
||||
return;
|
||||
|
||||
xwayland->desktop = desktop;
|
||||
xwayland->client = weston_desktop_client_create(desktop, NULL, NULL, NULL, NULL, 0, 0);
|
||||
|
||||
weston_layer_init(&xwayland->layer, compositor);
|
||||
/* We put this layer on top of regular shell surfaces, but hopefully
|
||||
* below any UI the shell would add */
|
||||
weston_layer_set_position(&xwayland->layer,
|
||||
WESTON_LAYER_POSITION_NORMAL + 1);
|
||||
|
||||
compositor->xwayland = xwayland;
|
||||
compositor->xwayland_interface = &weston_desktop_xwayland_interface;
|
||||
}
|
||||
|
||||
void
|
||||
weston_desktop_xwayland_fini(struct weston_desktop *desktop)
|
||||
{
|
||||
struct weston_compositor *compositor = weston_desktop_get_compositor(desktop);
|
||||
struct weston_desktop_xwayland *xwayland;
|
||||
|
||||
xwayland = compositor->xwayland;
|
||||
|
||||
weston_desktop_client_destroy(xwayland->client);
|
||||
weston_layer_fini(&xwayland->layer);
|
||||
free(xwayland);
|
||||
|
||||
compositor->xwayland = NULL;
|
||||
compositor->xwayland_interface = NULL;
|
||||
}
|
||||
Reference in New Issue
Block a user