chiark / gitweb /
ee182695ce1bc9f915cc644949cc5073e5e43c6f
[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         void *userdata;
98
99         size_t n_leafs;
100         grdev_tile *tile;
101
102         size_t n_pipes;
103         size_t max_pipes;
104
105         uint32_t width;
106         uint32_t height;
107
108         struct grdev_display_cache {
109                 grdev_pipe *pipe;
110                 grdev_display_target target;
111
112                 bool incomplete : 1;
113         } *pipes;
114
115         bool enabled : 1;
116         bool public : 1;
117         bool modified : 1;
118         bool framed : 1;
119 };
120
121 grdev_display *grdev_find_display(grdev_session *session, const char *name);
122
123 int grdev_display_new(grdev_display **out, grdev_session *session, const char *name);
124 grdev_display *grdev_display_free(grdev_display *display);
125
126 DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_display*, grdev_display_free);
127
128 /*
129  * Pipes
130  */
131
132 struct grdev_pipe_vtable {
133         void (*free) (grdev_pipe *pipe);
134         void (*enable) (grdev_pipe *pipe);
135         void (*disable) (grdev_pipe *pipe);
136         grdev_fb *(*target) (grdev_pipe *pipe);
137 };
138
139 struct grdev_pipe {
140         const grdev_pipe_vtable *vtable;
141         grdev_card *card;
142         char *name;
143
144         grdev_tile *tile;
145         grdev_display_cache *cache;
146         sd_event_source *vsync_src;
147
148         uint32_t width;
149         uint32_t height;
150         uint32_t vrefresh;
151
152         size_t max_fbs;
153         grdev_fb *front;
154         grdev_fb *back;
155         grdev_fb **fbs;
156
157         bool enabled : 1;
158         bool running : 1;
159         bool flip : 1;
160         bool flipping : 1;
161 };
162
163 #define GRDEV_PIPE_INIT(_vtable, _card) ((grdev_pipe){ \
164                 .vtable = (_vtable), \
165                 .card = (_card), \
166         })
167
168 grdev_pipe *grdev_find_pipe(grdev_card *card, const char *name);
169
170 int grdev_pipe_add(grdev_pipe *pipe, const char *name, size_t n_fbs);
171 grdev_pipe *grdev_pipe_free(grdev_pipe *pipe);
172
173 DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_pipe*, grdev_pipe_free);
174
175 void grdev_pipe_ready(grdev_pipe *pipe, bool running);
176 void grdev_pipe_frame(grdev_pipe *pipe);
177 void grdev_pipe_schedule(grdev_pipe *pipe, uint64_t frames);
178
179 /*
180  * Cards
181  */
182
183 struct grdev_card_vtable {
184         void (*free) (grdev_card *card);
185         void (*enable) (grdev_card *card);
186         void (*disable) (grdev_card *card);
187         void (*commit) (grdev_card *card);
188         void (*restore) (grdev_card *card);
189 };
190
191 struct grdev_card {
192         const grdev_card_vtable *vtable;
193         grdev_session *session;
194         char *name;
195
196         Hashmap *pipe_map;
197
198         bool enabled : 1;
199         bool modified : 1;
200 };
201
202 #define GRDEV_CARD_INIT(_vtable, _session) ((grdev_card){ \
203                 .vtable = (_vtable), \
204                 .session = (_session), \
205         })
206
207 grdev_card *grdev_find_card(grdev_session *session, const char *name);
208
209 int grdev_card_add(grdev_card *card, const char *name);
210 grdev_card *grdev_card_free(grdev_card *card);
211
212 DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_card*, grdev_card_free);
213
214 /*
215  * Sessions
216  */
217
218 struct grdev_session {
219         grdev_context *context;
220         char *name;
221         char *path;
222         grdev_event_fn event_fn;
223         void *userdata;
224
225         unsigned long n_pins;
226
227         Hashmap *card_map;
228         Hashmap *display_map;
229
230         bool custom : 1;
231         bool managed : 1;
232         bool enabled : 1;
233         bool modified : 1;
234 };
235
236 grdev_session *grdev_session_pin(grdev_session *session);
237 grdev_session *grdev_session_unpin(grdev_session *session);
238
239 DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_session*, grdev_session_unpin);
240
241 /*
242  * Contexts
243  */
244
245 struct grdev_context {
246         unsigned long ref;
247         sd_event *event;
248         sd_bus *sysbus;
249
250         Hashmap *session_map;
251 };