chiark / gitweb /
terminal: grdev: refresh device state on hotplug events
[elogind.git] / src / libsystemd-terminal / grdev-internal.h
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #pragma once
23
24 #include <inttypes.h>
25 #include <libudev.h>
26 #include <stdbool.h>
27 #include <stdlib.h>
28 #include <systemd/sd-bus.h>
29 #include <systemd/sd-event.h>
30 #include "grdev.h"
31 #include "hashmap.h"
32 #include "list.h"
33 #include "util.h"
34
35 typedef struct grdev_tile               grdev_tile;
36 typedef struct grdev_display_cache      grdev_display_cache;
37
38 typedef struct grdev_pipe_vtable        grdev_pipe_vtable;
39 typedef struct grdev_pipe               grdev_pipe;
40 typedef struct grdev_card_vtable        grdev_card_vtable;
41 typedef struct grdev_card               grdev_card;
42
43 /*
44  * DRM cards
45  */
46
47 bool grdev_is_drm_card(grdev_card *card);
48 grdev_card *grdev_find_drm_card(grdev_session *session, dev_t devnum);
49 int grdev_drm_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud);
50 void grdev_drm_card_hotplug(grdev_card *card, struct udev_device *ud);
51
52 /*
53  * Displays
54  */
55
56 enum {
57         GRDEV_TILE_LEAF,
58         GRDEV_TILE_NODE,
59         GRDEV_TILE_CNT
60 };
61
62 struct grdev_tile {
63         LIST_FIELDS(grdev_tile, childs_by_node);
64         grdev_tile *parent;
65         grdev_display *display;
66
67         uint32_t x;
68         uint32_t y;
69         unsigned int rotate;
70         unsigned int flip;
71         uint32_t cache_w;
72         uint32_t cache_h;
73
74         unsigned int type;
75
76         union {
77                 struct {
78                         grdev_pipe *pipe;
79                 } leaf;
80
81                 struct {
82                         size_t n_childs;
83                         LIST_HEAD(grdev_tile, child_list);
84                 } node;
85         };
86 };
87
88 int grdev_tile_new_leaf(grdev_tile **out, grdev_pipe *pipe);
89 int grdev_tile_new_node(grdev_tile **out);
90 grdev_tile *grdev_tile_free(grdev_tile *tile);
91
92 DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_tile*, grdev_tile_free);
93
94 struct grdev_display {
95         grdev_session *session;
96         char *name;
97
98         size_t n_leafs;
99         grdev_tile *tile;
100
101         size_t n_pipes;
102         size_t max_pipes;
103
104         uint32_t width;
105         uint32_t height;
106
107         struct grdev_display_cache {
108                 grdev_pipe *pipe;
109                 grdev_display_target target;
110
111                 bool incomplete : 1;
112         } *pipes;
113
114         bool enabled : 1;
115         bool public : 1;
116         bool modified : 1;
117         bool framed : 1;
118 };
119
120 grdev_display *grdev_find_display(grdev_session *session, const char *name);
121
122 int grdev_display_new(grdev_display **out, grdev_session *session, const char *name);
123 grdev_display *grdev_display_free(grdev_display *display);
124
125 DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_display*, grdev_display_free);
126
127 /*
128  * Pipes
129  */
130
131 struct grdev_pipe_vtable {
132         void (*free) (grdev_pipe *pipe);
133         void (*enable) (grdev_pipe *pipe);
134         void (*disable) (grdev_pipe *pipe);
135         grdev_fb *(*target) (grdev_pipe *pipe);
136 };
137
138 struct grdev_pipe {
139         const grdev_pipe_vtable *vtable;
140         grdev_card *card;
141         char *name;
142
143         grdev_tile *tile;
144         grdev_display_cache *cache;
145
146         uint32_t width;
147         uint32_t height;
148
149         size_t max_fbs;
150         grdev_fb *front;
151         grdev_fb *back;
152         grdev_fb **fbs;
153
154         bool enabled : 1;
155         bool running : 1;
156         bool flip : 1;
157         bool flipping : 1;
158 };
159
160 #define GRDEV_PIPE_INIT(_vtable, _card) ((grdev_pipe){ \
161                 .vtable = (_vtable), \
162                 .card = (_card), \
163         })
164
165 grdev_pipe *grdev_find_pipe(grdev_card *card, const char *name);
166
167 int grdev_pipe_add(grdev_pipe *pipe, const char *name, size_t n_fbs);
168 grdev_pipe *grdev_pipe_free(grdev_pipe *pipe);
169
170 DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_pipe*, grdev_pipe_free);
171
172 void grdev_pipe_ready(grdev_pipe *pipe, bool running);
173 void grdev_pipe_frame(grdev_pipe *pipe);
174
175 /*
176  * Cards
177  */
178
179 struct grdev_card_vtable {
180         void (*free) (grdev_card *card);
181         void (*enable) (grdev_card *card);
182         void (*disable) (grdev_card *card);
183         void (*commit) (grdev_card *card);
184         void (*restore) (grdev_card *card);
185 };
186
187 struct grdev_card {
188         const grdev_card_vtable *vtable;
189         grdev_session *session;
190         char *name;
191
192         Hashmap *pipe_map;
193
194         bool enabled : 1;
195         bool modified : 1;
196 };
197
198 #define GRDEV_CARD_INIT(_vtable, _session) ((grdev_card){ \
199                 .vtable = (_vtable), \
200                 .session = (_session), \
201         })
202
203 grdev_card *grdev_find_card(grdev_session *session, const char *name);
204
205 int grdev_card_add(grdev_card *card, const char *name);
206 grdev_card *grdev_card_free(grdev_card *card);
207
208 DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_card*, grdev_card_free);
209
210 /*
211  * Sessions
212  */
213
214 struct grdev_session {
215         grdev_context *context;
216         char *name;
217         char *path;
218         grdev_event_fn event_fn;
219         void *userdata;
220
221         unsigned long n_pins;
222
223         Hashmap *card_map;
224         Hashmap *display_map;
225
226         bool custom : 1;
227         bool managed : 1;
228         bool enabled : 1;
229         bool modified : 1;
230 };
231
232 grdev_session *grdev_session_pin(grdev_session *session);
233 grdev_session *grdev_session_unpin(grdev_session *session);
234
235 DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_session*, grdev_session_unpin);
236
237 /*
238  * Contexts
239  */
240
241 struct grdev_context {
242         unsigned long ref;
243         sd_event *event;
244         sd_bus *sysbus;
245
246         Hashmap *session_map;
247 };