aboutsummaryrefslogtreecommitdiff
path: root/include/wlr/backend/session.h
blob: 3179d1f546314ac30c69d0a4c36467b98ea1c5ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#ifndef WLR_BACKEND_SESSION_H
#define WLR_BACKEND_SESSION_H

#include <stdbool.h>
#include <sys/types.h>
#include <wayland-server-core.h>

struct libseat;

/**
 * An opened physical device.
 */
struct wlr_device {
	int fd;
	int device_id;
	dev_t dev;
	struct wl_list link; // wlr_session.devices

	struct {
		struct wl_signal change; // struct wlr_device_change_event
		struct wl_signal remove;
	} events;
};

/**
 * A session manages access to physical devices (such as GPUs and input
 * devices).
 *
 * A session is only required when running on bare metal (e.g. with the KMS or
 * libinput backends).
 *
 * The session listens for device hotplug events, and relays that information
 * via the add_drm_card event and the change/remove events on struct wlr_device.
 * The session provides functions to gain access to physical device (which is a
 * privileged operation), see wlr_session_open_file(). The session also keeps
 * track of the virtual terminal state (allowing users to switch between
 * compositors or TTYs), see wlr_session_change_vt() and the active event.
 */
struct wlr_session {
	/*
	 * Signal for when the session becomes active/inactive.
	 * It's called when we swap virtual terminal.
	 */
	bool active;

	/*
	 * 0 if virtual terminals are not supported
	 * i.e. seat != "seat0"
	 */
	unsigned vtnr;
	char seat[256];

	struct udev *udev;
	struct udev_monitor *mon;
	struct wl_event_source *udev_event;

	struct libseat *seat_handle;
	struct wl_event_source *libseat_event;

	struct wl_list devices; // wlr_device.link

	struct wl_event_loop *event_loop;
	struct wl_listener event_loop_destroy;

	struct {
		struct wl_signal active;
		struct wl_signal add_drm_card; // struct wlr_session_add_event
		struct wl_signal destroy;
	} events;
};

struct wlr_session_add_event {
	const char *path;
};

enum wlr_device_change_type {
	WLR_DEVICE_HOTPLUG = 1,
	WLR_DEVICE_LEASE,
};

struct wlr_device_hotplug_event {
	uint32_t connector_id;
	uint32_t prop_id;
};

struct wlr_device_change_event {
	enum wlr_device_change_type type;
	union {
		struct wlr_device_hotplug_event hotplug;
	};
};

/*
 * Opens a session, taking control of the current virtual terminal.
 * This should not be called if another program is already in control
 * of the terminal (Xorg, another Wayland compositor, etc.).
 *
 * Returns NULL on error.
 */
struct wlr_session *wlr_session_create(struct wl_event_loop *loop);

/*
 * Closes a previously opened session and restores the virtual terminal.
 * You should call wlr_session_close_file() on each files you opened
 * with wlr_session_open_file() before you call this.
 */
void wlr_session_destroy(struct wlr_session *session);

/*
 * Opens the file at path.
 *
 * This can only be used to open DRM or evdev (input) devices. Files opened via
 * this function must be closed by calling wlr_session_close_file().
 *
 * When the session becomes inactive:
 *
 * - DRM files lose their DRM master status
 * - evdev files become invalid and should be closed
 */
struct wlr_device *wlr_session_open_file(struct wlr_session *session,
	const char *path);

/*
 * Closes a file previously opened with wlr_session_open_file().
 */
void wlr_session_close_file(struct wlr_session *session,
	struct wlr_device *device);

/*
 * Changes the virtual terminal.
 */
bool wlr_session_change_vt(struct wlr_session *session, unsigned vt);

/**
 * Enumerate and open KMS devices.
 *
 * ret is filled with up to ret_len devices. The number of devices ret has been
 * filled with is returned on success. If more devices than ret_len are probed,
 * the extraneous ones are ignored. If there is no KMS device, the function
 * will block until such device is detected up to a timeout. The first device
 * returned is the default device (marked as "boot_vga" by the kernel).
 *
 * On error, or if no device was found, -1 is returned.
 */
ssize_t wlr_session_find_gpus(struct wlr_session *session,
	size_t ret_len, struct wlr_device **ret);

#endif