mirror of
https://github.com/cage-kiosk/cage.git
synced 2026-03-21 05:33:55 -04:00
commit
14dde88d88
14 changed files with 248 additions and 21 deletions
2
LICENSE
2
LICENSE
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2018 Jente Hidskes
|
Copyright (c) 2018-2019 Jente Hidskes
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
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
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
|
|
||||||
|
|
@ -57,4 +57,4 @@ Please see
|
||||||
[LICENSE](https://github.com/Hjdskes/cage/blob/master/LICENSE) on
|
[LICENSE](https://github.com/Hjdskes/cage/blob/master/LICENSE) on
|
||||||
[GitHub](https://github.com/Hjdskes/cage).
|
[GitHub](https://github.com/Hjdskes/cage).
|
||||||
|
|
||||||
Copyright © 2018 Jente Hidskes <hjdskes@gmail.com>
|
Copyright © 2018-2019 Jente Hidskes <hjdskes@gmail.com>
|
||||||
|
|
|
||||||
51
cage.c
51
cage.c
|
|
@ -1,13 +1,15 @@
|
||||||
/*
|
/*
|
||||||
* Cage: A Wayland kiosk.
|
* Cage: A Wayland kiosk.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2018 Jente Hidskes
|
* Copyright (C) 2018-2019 Jente Hidskes
|
||||||
*
|
*
|
||||||
* See the LICENSE file accompanying this file.
|
* See the LICENSE file accompanying this file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _POSIX_C_SOURCE 200112L
|
#define _POSIX_C_SOURCE 200112L
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -17,15 +19,24 @@
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
|
#if CAGE_HAS_XWAYLAND
|
||||||
|
#include <wlr/types/wlr_xcursor_manager.h>
|
||||||
|
#endif
|
||||||
#include <wlr/types/wlr_data_device.h>
|
#include <wlr/types/wlr_data_device.h>
|
||||||
#include <wlr/types/wlr_output_layout.h>
|
#include <wlr/types/wlr_output_layout.h>
|
||||||
#include <wlr/types/wlr_xdg_shell.h>
|
#include <wlr/types/wlr_xdg_shell.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
#if CAGE_HAS_XWAYLAND
|
||||||
|
#include <wlr/xwayland.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "seat.h"
|
#include "seat.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "xdg_shell.h"
|
#include "xdg_shell.h"
|
||||||
|
#if CAGE_HAS_XWAYLAND
|
||||||
|
#include "xwayland.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
spawn_primary_client(char *argv[], pid_t *pid_out)
|
spawn_primary_client(char *argv[], pid_t *pid_out)
|
||||||
|
|
@ -69,6 +80,9 @@ main(int argc, char *argv[])
|
||||||
struct wlr_compositor *compositor = NULL;
|
struct wlr_compositor *compositor = NULL;
|
||||||
struct wlr_data_device_manager *data_device_mgr = NULL;
|
struct wlr_data_device_manager *data_device_mgr = NULL;
|
||||||
struct wlr_xdg_shell *xdg_shell = NULL;
|
struct wlr_xdg_shell *xdg_shell = NULL;
|
||||||
|
#if CAGE_HAS_XWAYLAND
|
||||||
|
struct wlr_xwayland *xwayland = NULL;
|
||||||
|
#endif
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
|
|
@ -146,6 +160,31 @@ main(int argc, char *argv[])
|
||||||
server.new_xdg_shell_surface.notify = handle_xdg_shell_surface_new;
|
server.new_xdg_shell_surface.notify = handle_xdg_shell_surface_new;
|
||||||
wl_signal_add(&xdg_shell->events.new_surface, &server.new_xdg_shell_surface);
|
wl_signal_add(&xdg_shell->events.new_surface, &server.new_xdg_shell_surface);
|
||||||
|
|
||||||
|
#if CAGE_HAS_XWAYLAND
|
||||||
|
xwayland = wlr_xwayland_create(server.wl_display, compositor, true);
|
||||||
|
server.new_xwayland_surface.notify = handle_xwayland_surface_new;
|
||||||
|
wl_signal_add(&xwayland->events.new_surface, &server.new_xwayland_surface);
|
||||||
|
|
||||||
|
struct wlr_xcursor_manager *xcursor_manager =
|
||||||
|
wlr_xcursor_manager_create(DEFAULT_XCURSOR, XCURSOR_SIZE);
|
||||||
|
if (!xcursor_manager) {
|
||||||
|
wlr_log(WLR_ERROR, "Cannot create XWayland XCursor manager");
|
||||||
|
ret = 1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (wlr_xcursor_manager_load(xcursor_manager, 1)) {
|
||||||
|
wlr_log(WLR_ERROR, "Cannot load XWayland XCursor theme");
|
||||||
|
}
|
||||||
|
struct wlr_xcursor *xcursor =
|
||||||
|
wlr_xcursor_manager_get_xcursor(xcursor_manager, DEFAULT_XCURSOR, 1);
|
||||||
|
if (xcursor) {
|
||||||
|
struct wlr_xcursor_image *image = xcursor->images[0];
|
||||||
|
wlr_xwayland_set_cursor(xwayland, image->buffer,
|
||||||
|
image->width * 4, image->width, image->height,
|
||||||
|
image->hotspot_x, image->hotspot_y);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *socket = wl_display_add_socket_auto(server.wl_display);
|
const char *socket = wl_display_add_socket_auto(server.wl_display);
|
||||||
if (!socket) {
|
if (!socket) {
|
||||||
wlr_log_errno(WLR_ERROR, "Unable to open Wayland socket");
|
wlr_log_errno(WLR_ERROR, "Unable to open Wayland socket");
|
||||||
|
|
@ -165,6 +204,12 @@ main(int argc, char *argv[])
|
||||||
"Clients may not be able to connect");
|
"Clients may not be able to connect");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CAGE_HAS_XWAYLAND
|
||||||
|
if (xwayland) {
|
||||||
|
wlr_xwayland_set_seat(xwayland, server.seat->seat);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
if (!spawn_primary_client(argv + 1, &pid)) {
|
if (!spawn_primary_client(argv + 1, &pid)) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
@ -178,6 +223,10 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
end:
|
end:
|
||||||
cg_seat_destroy(server.seat);
|
cg_seat_destroy(server.seat);
|
||||||
|
#if CAGE_HAS_XWAYLAND
|
||||||
|
wlr_xwayland_destroy(xwayland);
|
||||||
|
wlr_xcursor_manager_destroy(xcursor_manager);
|
||||||
|
#endif
|
||||||
wlr_xdg_shell_destroy(xdg_shell);
|
wlr_xdg_shell_destroy(xdg_shell);
|
||||||
wlr_data_device_manager_destroy(data_device_mgr);
|
wlr_data_device_manager_destroy(data_device_mgr);
|
||||||
wlr_compositor_destroy(compositor);
|
wlr_compositor_destroy(compositor);
|
||||||
|
|
|
||||||
20
meson.build
20
meson.build
|
|
@ -51,6 +51,9 @@ server_protos = declare_dependency(
|
||||||
sources: server_protos_headers,
|
sources: server_protos_headers,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
conf_data = configuration_data()
|
||||||
|
conf_data.set10('CAGE_HAS_XWAYLAND', get_option('xwayland'))
|
||||||
|
|
||||||
cage_sources = [
|
cage_sources = [
|
||||||
'cage.c',
|
'cage.c',
|
||||||
'output.c',
|
'output.c',
|
||||||
|
|
@ -60,6 +63,9 @@ cage_sources = [
|
||||||
]
|
]
|
||||||
|
|
||||||
cage_headers = [
|
cage_headers = [
|
||||||
|
configure_file(input: 'config.h.in',
|
||||||
|
output: 'config.h',
|
||||||
|
configuration: conf_data),
|
||||||
'output.h',
|
'output.h',
|
||||||
'seat.h',
|
'seat.h',
|
||||||
'server.h',
|
'server.h',
|
||||||
|
|
@ -67,6 +73,11 @@ cage_headers = [
|
||||||
'xdg_shell.h',
|
'xdg_shell.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if conf_data.get('CAGE_HAS_XWAYLAND', 0) == 1
|
||||||
|
cage_sources += 'xwayland.c'
|
||||||
|
cage_headers += 'xwayland.h'
|
||||||
|
endif
|
||||||
|
|
||||||
executable(
|
executable(
|
||||||
meson.project_name(),
|
meson.project_name(),
|
||||||
cage_sources + cage_headers,
|
cage_sources + cage_headers,
|
||||||
|
|
@ -78,3 +89,12 @@ executable(
|
||||||
],
|
],
|
||||||
install: true,
|
install: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
summary = [
|
||||||
|
'',
|
||||||
|
'Cage @0@'.format(meson.project_version()),
|
||||||
|
'',
|
||||||
|
' xwayland: @0@'.format(conf_data.get('CAGE_HAS_XWAYLAND', false)),
|
||||||
|
''
|
||||||
|
]
|
||||||
|
message('\n'.join(summary))
|
||||||
|
|
|
||||||
1
meson_options.txt
Normal file
1
meson_options.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
option('xwayland', type: 'boolean', value: 'false', description: 'Enable support for X11 applications')
|
||||||
12
output.c
12
output.c
|
|
@ -1,13 +1,15 @@
|
||||||
/*
|
/*
|
||||||
* Cage: A Wayland kiosk.
|
* Cage: A Wayland kiosk.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2018 Jente Hidskes
|
* Copyright (C) 2018-2019 Jente Hidskes
|
||||||
*
|
*
|
||||||
* See the LICENSE file accompanying this file.
|
* See the LICENSE file accompanying this file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _POSIX_C_SOURCE 200112L
|
#define _POSIX_C_SOURCE 200112L
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
|
|
@ -19,6 +21,9 @@
|
||||||
#include <wlr/types/wlr_surface.h>
|
#include <wlr/types/wlr_surface.h>
|
||||||
#include <wlr/types/wlr_xdg_shell.h>
|
#include <wlr/types/wlr_xdg_shell.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
#if CAGE_HAS_XWAYLAND
|
||||||
|
#include <wlr/xwayland.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
@ -76,6 +81,11 @@ view_for_each_surface(struct cg_view *view, struct render_data *rdata,
|
||||||
case CAGE_XDG_SHELL_VIEW:
|
case CAGE_XDG_SHELL_VIEW:
|
||||||
wlr_xdg_surface_for_each_surface(view->xdg_surface, iterator, rdata);
|
wlr_xdg_surface_for_each_surface(view->xdg_surface, iterator, rdata);
|
||||||
break;
|
break;
|
||||||
|
#ifdef CAGE_HAS_XWAYLAND
|
||||||
|
case CAGE_XWAYLAND_VIEW:
|
||||||
|
wlr_surface_for_each_surface(view->wlr_surface, iterator, rdata);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
wlr_log(WLR_ERROR, "Unrecognized view type: %d", view->type);
|
wlr_log(WLR_ERROR, "Unrecognized view type: %d", view->type);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
24
seat.c
24
seat.c
|
|
@ -1,11 +1,13 @@
|
||||||
/*
|
/*
|
||||||
* Cage: A Wayland kiosk.
|
* Cage: A Wayland kiosk.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2018 Jente Hidskes
|
* Copyright (C) 2018-2019 Jente Hidskes
|
||||||
*
|
*
|
||||||
* See the LICENSE file accompanying this file.
|
* See the LICENSE file accompanying this file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
|
|
@ -14,15 +16,15 @@
|
||||||
#include <wlr/types/wlr_surface.h>
|
#include <wlr/types/wlr_surface.h>
|
||||||
#include <wlr/types/wlr_xcursor_manager.h>
|
#include <wlr/types/wlr_xcursor_manager.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
#if CAGE_HAS_XWAYLAND
|
||||||
|
#include <wlr/xwayland.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "seat.h"
|
#include "seat.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
|
||||||
#define DEFAULT_XCURSOR "left_ptr"
|
|
||||||
#define XCURSOR_SIZE 24
|
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
have_dialogs_open(struct cg_server *server)
|
have_dialogs_open(struct cg_server *server)
|
||||||
{
|
{
|
||||||
|
|
@ -52,6 +54,13 @@ view_at(struct cg_view *view, double lx, double ly,
|
||||||
view_sx, view_sy,
|
view_sx, view_sy,
|
||||||
&_sx, &_sy);
|
&_sx, &_sy);
|
||||||
break;
|
break;
|
||||||
|
#ifdef CAGE_HAS_XWAYLAND
|
||||||
|
case CAGE_XWAYLAND_VIEW:
|
||||||
|
_surface = wlr_surface_surface_at(view->wlr_surface,
|
||||||
|
view_sx, view_sy,
|
||||||
|
&_sx, &_sy);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
wlr_log(WLR_ERROR, "Unrecognized view type: %d", view->type);
|
wlr_log(WLR_ERROR, "Unrecognized view type: %d", view->type);
|
||||||
}
|
}
|
||||||
|
|
@ -501,6 +510,13 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CAGE_HAS_XWAYLAND
|
||||||
|
if (view->type == CAGE_XWAYLAND_VIEW &&
|
||||||
|
!wlr_xwayland_or_surface_wants_focus(view->xwayland_surface)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (prev_view) {
|
if (prev_view) {
|
||||||
view_activate(prev_view, false);
|
view_activate(prev_view, false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
seat.h
3
seat.h
|
|
@ -10,6 +10,9 @@
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
|
||||||
|
#define DEFAULT_XCURSOR "left_ptr"
|
||||||
|
#define XCURSOR_SIZE 24
|
||||||
|
|
||||||
struct cg_seat {
|
struct cg_seat {
|
||||||
struct wlr_seat *seat;
|
struct wlr_seat *seat;
|
||||||
struct cg_server *server;
|
struct cg_server *server;
|
||||||
|
|
|
||||||
9
server.h
9
server.h
|
|
@ -1,9 +1,14 @@
|
||||||
#ifndef CG_SERVER_H
|
#ifndef CG_SERVER_H
|
||||||
#define CG_SERVER_H
|
#define CG_SERVER_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
#include <wlr/types/wlr_output_layout.h>
|
#include <wlr/types/wlr_output_layout.h>
|
||||||
|
#ifdef CAGE_HAS_XWAYLAND
|
||||||
|
#include <wlr/xwayland.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "seat.h"
|
#include "seat.h"
|
||||||
|
|
@ -20,6 +25,10 @@ struct cg_server {
|
||||||
struct wlr_output_layout *output_layout;
|
struct wlr_output_layout *output_layout;
|
||||||
struct cg_output *output;
|
struct cg_output *output;
|
||||||
struct wl_listener new_output;
|
struct wl_listener new_output;
|
||||||
|
|
||||||
|
#if CAGE_HAS_XWAYLAND
|
||||||
|
struct wl_listener new_xwayland_surface;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
18
view.c
18
view.c
|
|
@ -43,11 +43,11 @@ view_center(struct cg_view *view)
|
||||||
int output_width, output_height;
|
int output_width, output_height;
|
||||||
wlr_output_effective_resolution(output, &output_width, &output_height);
|
wlr_output_effective_resolution(output, &output_width, &output_height);
|
||||||
|
|
||||||
struct wlr_box geom;
|
int width, height;
|
||||||
view->get_geometry(view, &geom);
|
view->get_geometry(view, &width, &height);
|
||||||
|
|
||||||
view->x = (output_width - geom.width) / 2;
|
view->x = (output_width - width) / 2;
|
||||||
view->y = (output_height - geom.height) / 2;
|
view->y = (output_height - height) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -56,6 +56,13 @@ view_is_primary(struct cg_view *view)
|
||||||
return view->is_primary(view);
|
return view->is_primary(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
view_unmap(struct cg_view *view)
|
||||||
|
{
|
||||||
|
wl_list_remove(&view->link);
|
||||||
|
view->wlr_surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
view_map(struct cg_view *view, struct wlr_surface *surface)
|
view_map(struct cg_view *view, struct wlr_surface *surface)
|
||||||
{
|
{
|
||||||
|
|
@ -67,6 +74,7 @@ view_map(struct cg_view *view, struct wlr_surface *surface)
|
||||||
view_center(view);
|
view_center(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_list_insert(&view->server->views, &view->link);
|
||||||
seat_set_focus(view->server->seat, view);
|
seat_set_focus(view->server->seat, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,7 +84,6 @@ view_destroy(struct cg_view *view)
|
||||||
struct cg_server *server = view->server;
|
struct cg_server *server = view->server;
|
||||||
bool terminate = view_is_primary(view);
|
bool terminate = view_is_primary(view);
|
||||||
|
|
||||||
wl_list_remove(&view->link);
|
|
||||||
free(view);
|
free(view);
|
||||||
|
|
||||||
/* If this was our primary view, exit. */
|
/* If this was our primary view, exit. */
|
||||||
|
|
@ -91,7 +98,6 @@ cg_view_create(struct cg_server *server)
|
||||||
struct cg_view *view = calloc(1, sizeof(struct cg_view));
|
struct cg_view *view = calloc(1, sizeof(struct cg_view));
|
||||||
|
|
||||||
view->server = server;
|
view->server = server;
|
||||||
wl_list_insert(&server->views, &view->link);
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
12
view.h
12
view.h
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef CG_VIEW_H
|
#ifndef CG_VIEW_H
|
||||||
#define CG_VIEW_H
|
#define CG_VIEW_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
#include <wlr/types/wlr_box.h>
|
#include <wlr/types/wlr_box.h>
|
||||||
|
|
@ -11,6 +13,9 @@
|
||||||
|
|
||||||
enum cg_view_type {
|
enum cg_view_type {
|
||||||
CAGE_XDG_SHELL_VIEW,
|
CAGE_XDG_SHELL_VIEW,
|
||||||
|
#ifdef CAGE_HAS_XWAYLAND
|
||||||
|
CAGE_XWAYLAND_VIEW,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cg_view {
|
struct cg_view {
|
||||||
|
|
@ -22,16 +27,20 @@ struct cg_view {
|
||||||
enum cg_view_type type;
|
enum cg_view_type type;
|
||||||
union {
|
union {
|
||||||
struct wlr_xdg_surface *xdg_surface;
|
struct wlr_xdg_surface *xdg_surface;
|
||||||
|
#ifdef CAGE_HAS_XWAYLAND
|
||||||
|
struct wlr_xwayland_surface *xwayland_surface;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
|
struct wl_listener unmap;
|
||||||
struct wl_listener map;
|
struct wl_listener map;
|
||||||
// TODO: allow applications to go to fullscreen from maximized?
|
// TODO: allow applications to go to fullscreen from maximized?
|
||||||
// struct wl_listener request_fullscreen;
|
// struct wl_listener request_fullscreen;
|
||||||
|
|
||||||
void (*activate)(struct cg_view *view, bool activate);
|
void (*activate)(struct cg_view *view, bool activate);
|
||||||
void (*maximize)(struct cg_view *view, int output_width, int output_height);
|
void (*maximize)(struct cg_view *view, int output_width, int output_height);
|
||||||
void (*get_geometry)(struct cg_view *view, struct wlr_box *geom);
|
void (*get_geometry)(struct cg_view *view, int *width_out, int *height_out);
|
||||||
bool (*is_primary)(struct cg_view *view);
|
bool (*is_primary)(struct cg_view *view);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -39,6 +48,7 @@ void view_activate(struct cg_view *view, bool activate);
|
||||||
void view_maximize(struct cg_view *view);
|
void view_maximize(struct cg_view *view);
|
||||||
void view_center(struct cg_view *view);
|
void view_center(struct cg_view *view);
|
||||||
bool view_is_primary(struct cg_view *view);
|
bool view_is_primary(struct cg_view *view);
|
||||||
|
void view_unmap(struct cg_view *view);
|
||||||
void view_map(struct cg_view *view, struct wlr_surface *surface);
|
void view_map(struct cg_view *view, struct wlr_surface *surface);
|
||||||
void view_destroy(struct cg_view *view);
|
void view_destroy(struct cg_view *view);
|
||||||
struct cg_view *cg_view_create(struct cg_server *server);
|
struct cg_view *cg_view_create(struct cg_server *server);
|
||||||
|
|
|
||||||
21
xdg_shell.c
21
xdg_shell.c
|
|
@ -28,9 +28,13 @@ maximize(struct cg_view *view, int output_width, int output_height)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_geometry(struct cg_view *view, struct wlr_box *geom)
|
get_geometry(struct cg_view *view, int *width_out, int *height_out)
|
||||||
{
|
{
|
||||||
wlr_xdg_surface_get_geometry(view->xdg_surface, geom);
|
struct wlr_box geom;
|
||||||
|
|
||||||
|
wlr_xdg_surface_get_geometry(view->xdg_surface, &geom);
|
||||||
|
*width_out = geom.width;
|
||||||
|
*height_out = geom.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -41,6 +45,13 @@ is_primary(struct cg_view *view)
|
||||||
return parent == NULL; /*&& role == WLR_XDG_SURFACE_ROLE_TOPLEVEL */
|
return parent == NULL; /*&& role == WLR_XDG_SURFACE_ROLE_TOPLEVEL */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_xdg_shell_surface_unmap(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct cg_view *view = wl_container_of(listener, view, unmap);
|
||||||
|
view_unmap(view);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_xdg_shell_surface_map(struct wl_listener *listener, void *data)
|
handle_xdg_shell_surface_map(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
|
@ -61,16 +72,14 @@ handle_xdg_shell_surface_new(struct wl_listener *listener, void *data)
|
||||||
struct cg_server *server = wl_container_of(listener, server, new_xdg_shell_surface);
|
struct cg_server *server = wl_container_of(listener, server, new_xdg_shell_surface);
|
||||||
struct wlr_xdg_surface *xdg_surface = data;
|
struct wlr_xdg_surface *xdg_surface = data;
|
||||||
|
|
||||||
if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cg_view *view = cg_view_create(server);
|
struct cg_view *view = cg_view_create(server);
|
||||||
view->type = CAGE_XDG_SHELL_VIEW;
|
view->type = CAGE_XDG_SHELL_VIEW;
|
||||||
view->xdg_surface = xdg_surface;
|
view->xdg_surface = xdg_surface;
|
||||||
|
|
||||||
view->map.notify = handle_xdg_shell_surface_map;
|
view->map.notify = handle_xdg_shell_surface_map;
|
||||||
wl_signal_add(&xdg_surface->events.map, &view->map);
|
wl_signal_add(&xdg_surface->events.map, &view->map);
|
||||||
|
view->unmap.notify = handle_xdg_shell_surface_unmap;
|
||||||
|
wl_signal_add(&xdg_surface->events.unmap, &view->unmap);
|
||||||
view->destroy.notify = handle_xdg_shell_surface_destroy;
|
view->destroy.notify = handle_xdg_shell_surface_destroy;
|
||||||
wl_signal_add(&xdg_surface->events.destroy, &view->destroy);
|
wl_signal_add(&xdg_surface->events.destroy, &view->destroy);
|
||||||
|
|
||||||
|
|
|
||||||
86
xwayland.c
Normal file
86
xwayland.c
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Cage: A Wayland kiosk.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018-2019 Jente Hidskes
|
||||||
|
*
|
||||||
|
* See the LICENSE file accompanying this file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <wayland-server.h>
|
||||||
|
#include <wlr/types/wlr_box.h>
|
||||||
|
#include <wlr/xwayland.h>
|
||||||
|
|
||||||
|
#include "server.h"
|
||||||
|
#include "view.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
activate(struct cg_view *view, bool activate)
|
||||||
|
{
|
||||||
|
wlr_xwayland_surface_activate(view->xwayland_surface, activate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
maximize(struct cg_view *view, int output_width, int output_height)
|
||||||
|
{
|
||||||
|
wlr_xwayland_surface_configure(view->xwayland_surface, 0, 0, output_width, output_height);
|
||||||
|
wlr_xwayland_surface_set_maximized(view->xwayland_surface, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_geometry(struct cg_view *view, int *width_out, int *height_out)
|
||||||
|
{
|
||||||
|
*width_out = view->xwayland_surface->surface->current.width;
|
||||||
|
*height_out = view->xwayland_surface->surface->current.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_primary(struct cg_view *view)
|
||||||
|
{
|
||||||
|
struct wlr_xwayland_surface *parent = view->xwayland_surface->parent;
|
||||||
|
return parent == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_xwayland_surface_unmap(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct cg_view *view = wl_container_of(listener, view, unmap);
|
||||||
|
view_unmap(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_xwayland_surface_map(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct cg_view *view = wl_container_of(listener, view, map);
|
||||||
|
view_map(view, view->xwayland_surface->surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_xwayland_surface_destroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct cg_view *view = wl_container_of(listener, view, destroy);
|
||||||
|
view_destroy(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
handle_xwayland_surface_new(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct cg_server *server = wl_container_of(listener, server, new_xwayland_surface);
|
||||||
|
struct wlr_xwayland_surface *xwayland_surface = data;
|
||||||
|
|
||||||
|
struct cg_view *view = cg_view_create(server);
|
||||||
|
view->type = CAGE_XWAYLAND_VIEW;
|
||||||
|
view->xwayland_surface = xwayland_surface;
|
||||||
|
|
||||||
|
view->map.notify = handle_xwayland_surface_map;
|
||||||
|
wl_signal_add(&xwayland_surface->events.map, &view->map);
|
||||||
|
view->unmap.notify = handle_xwayland_surface_unmap;
|
||||||
|
wl_signal_add(&xwayland_surface->events.unmap, &view->unmap);
|
||||||
|
view->destroy.notify = handle_xwayland_surface_destroy;
|
||||||
|
wl_signal_add(&xwayland_surface->events.destroy, &view->destroy);
|
||||||
|
|
||||||
|
view->activate = activate;
|
||||||
|
view->maximize = maximize;
|
||||||
|
view->get_geometry = get_geometry;
|
||||||
|
view->is_primary = is_primary;
|
||||||
|
}
|
||||||
8
xwayland.h
Normal file
8
xwayland.h
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef XWAYLAND_H
|
||||||
|
#define XWAYLAND_H
|
||||||
|
|
||||||
|
#include <wayland-server.h>
|
||||||
|
|
||||||
|
void handle_xwayland_surface_new(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Add a link
Reference in a new issue