chiark / gitweb /
f5915b16e8c8e17fdbd99489e7f5f768a13d62e3
[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         sd_event_source *vsync_src;
146
147         uint32_t width;
148         uint32_t height;
149         uint32_t vrefresh;
150
151         size_t max_fbs;
152         grdev_fb *front;
153         grdev_fb *back;
154         grdev_fb **fbs;
155
156         bool enabled : 1;
157         bool running : 1;
158         bool flip : 1;
159         bool flipping : 1;
160 };
161
162 #define GRDEV_PIPE_INIT(_vtable, _card) ((grdev_pipe){ \
163                 .vtable = (_vtable), \
164                 .card = (_card), \
165         })
166
167 grdev_pipe *grdev_find_pipe(grdev_card *card, const char *name);
168
169 int grdev_pipe_add(grdev_pipe *pipe, const char *name, size_t n_fbs);
170 grdev_pipe *grdev_pipe_free(grdev_pipe *pipe);
171
172 DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_pipe*, grdev_pipe_free);
173
174 void grdev_pipe_ready(grdev_pipe *pipe, bool running);
175 void grdev_pipe_frame(grdev_pipe *pipe);
176 void grdev_pipe_schedule(grdev_pipe *pipe, uint64_t frames);
177
178 /*
179  * Cards
180  */
181
182 struct grdev_card_vtable {
183         void (*free) (grdev_card *card);
184         void (*enable) (grdev_card *card);
185         void (*disable) (grdev_card *card);
186         void (*commit) (grdev_card *card);
187         void (*restore) (grdev_card *card);
188 };
189
190 struct grdev_card {
191         const grdev_card_vtable *vtable;
192         grdev_session *session;
193         char *name;
194
195         Hashmap *pipe_map;
196
197         bool enabled : 1;
198         bool modified : 1;
199 };
200
201 #define GRDEV_CARD_INIT(_vtable, _session) ((grdev_card){ \
202                 .vtable = (_vtable), \
203                 .session = (_session), \
204         })
205
206 grdev_card *grdev_find_card(grdev_session *session, const char *name);
207
208 int grdev_card_add(grdev_card *card, const char *name);
209 grdev_card *grdev_card_free(grdev_card *card);
210
211 DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_card*, grdev_card_free);
212
213 /*
214  * Sessions
215  */
216
217 struct grdev_session {
218         grdev_context *context;
219         char *name;
220         char *path;
221         grdev_event_fn event_fn;
222         void *userdata;
223
224         unsigned long n_pins;
225
226         Hashmap *card_map;
227         Hashmap *display_map;
228
229         bool custom : 1;
230         bool managed : 1;
231         bool enabled : 1;
232         bool modified : 1;
233 };
234
235 grdev_session *grdev_session_pin(grdev_session *session);
236 grdev_session *grdev_session_unpin(grdev_session *session);
237
238 DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_session*, grdev_session_unpin);
239
240 /*
241  * Contexts
242  */
243
244 struct grdev_context {
245         unsigned long ref;
246         sd_event *event;
247         sd_bus *sysbus;
248
249         Hashmap *session_map;
250 };