]> git.proxmox.com Git - systemd.git/blame - src/libsystemd-terminal/grdev.h
Imported Upstream version 220
[systemd.git] / src / libsystemd-terminal / grdev.h
CommitLineData
5eef597e
MP
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/*
23 * Graphics Devices
24 * The grdev layer provides generic access to graphics devices. The device
25 * types are hidden in the implementation and exported in a generic way. The
26 * grdev_session object forms the base layer. It loads, configures and prepares
27 * any graphics devices associated with that session. Each session is totally
28 * independent of other sessions and can be controlled separately.
29 * The target devices on a session are called display. A display always
30 * corresponds to a real display regardless how many pipes are needed to drive
31 * that display. That is, an exported display might internally be created out
32 * of arbitrary combinations of target pipes. However, this is meant as
33 * implementation detail and API users must never assume details below the
34 * display-level. That is, a display is the most low-level object exported.
35 * Therefore, pipe-configuration and any low-level modesetting is hidden from
36 * the public API. It is provided by the implementation, and it is the
37 * implementation that decides how pipes are driven.
38 *
39 * The API users are free to ignore specific displays or combine them to create
40 * larger screens. This often requires user-configuration so is dictated by
41 * policy. The underlying pipe-configuration might be affected by these
42 * high-level policies, but is never directly controlled by those. That means,
43 * depending on the displays you use, it might affect how underlying resources
44 * are assigned. However, users can never directly apply policies to the pipes,
45 * but only to displays. In case specific hardware needs quirks on the pipe
46 * level, we support that via hwdb, not via public user configuration.
47 *
48 * Right now, displays are limited to rgb32 memory-mapped framebuffers on the
49 * primary plane. However, the grdev implementation can be easily extended to
50 * allow more powerful access (including hardware-acceleration for 2D and 3D
51 * compositing). So far, this wasn't needed so it is not exposed.
52 */
53
54#pragma once
55
5eef597e
MP
56#include <libudev.h>
57#include <stdbool.h>
58#include <stdlib.h>
59#include <systemd/sd-bus.h>
60#include <systemd/sd-event.h>
61#include "util.h"
62
63typedef struct grdev_fb grdev_fb;
64typedef struct grdev_display_target grdev_display_target;
65typedef struct grdev_display grdev_display;
66
67typedef struct grdev_event grdev_event;
68typedef struct grdev_session grdev_session;
69typedef struct grdev_context grdev_context;
70
71enum {
72 /* clockwise rotation; we treat this is abelian group Z4 with ADD */
73 GRDEV_ROTATE_0 = 0,
74 GRDEV_ROTATE_90 = 1,
75 GRDEV_ROTATE_180 = 2,
76 GRDEV_ROTATE_270 = 3,
77};
78
79enum {
80 /* flip states; we treat this as abelian group V4 with XOR */
81 GRDEV_FLIP_NONE = 0x0,
82 GRDEV_FLIP_HORIZONTAL = 0x1,
83 GRDEV_FLIP_VERTICAL = 0x2,
84};
85
86/*
87 * Displays
88 */
89
90struct grdev_fb {
91 uint32_t width;
92 uint32_t height;
93 uint32_t format;
94 int32_t strides[4];
95 void *maps[4];
96
97 union {
98 void *ptr;
99 uint64_t u64;
100 } data;
101
102 void (*free_fn) (void *ptr);
103};
104
105struct grdev_display_target {
106 uint32_t x;
107 uint32_t y;
108 uint32_t width;
109 uint32_t height;
110 unsigned int rotate;
111 unsigned int flip;
112 grdev_fb *front;
113 grdev_fb *back;
114};
115
116void grdev_display_set_userdata(grdev_display *display, void *userdata);
117void *grdev_display_get_userdata(grdev_display *display);
118
119const char *grdev_display_get_name(grdev_display *display);
120uint32_t grdev_display_get_width(grdev_display *display);
121uint32_t grdev_display_get_height(grdev_display *display);
122
123bool grdev_display_is_enabled(grdev_display *display);
124void grdev_display_enable(grdev_display *display);
125void grdev_display_disable(grdev_display *display);
126
127const grdev_display_target *grdev_display_next_target(grdev_display *display, const grdev_display_target *prev);
128void grdev_display_flip_target(grdev_display *display, const grdev_display_target *target);
129
130#define GRDEV_DISPLAY_FOREACH_TARGET(_display, _t) \
131 for ((_t) = grdev_display_next_target((_display), NULL); \
132 (_t); \
133 (_t) = grdev_display_next_target((_display), (_t)))
134
135/*
136 * Events
137 */
138
139enum {
140 GRDEV_EVENT_DISPLAY_ADD,
141 GRDEV_EVENT_DISPLAY_REMOVE,
142 GRDEV_EVENT_DISPLAY_CHANGE,
143 GRDEV_EVENT_DISPLAY_FRAME,
144};
145
146typedef void (*grdev_event_fn) (grdev_session *session, void *userdata, grdev_event *ev);
147
148struct grdev_event {
149 unsigned int type;
150 union {
151 struct {
152 grdev_display *display;
153 } display_add, display_remove, display_change;
154
155 struct {
156 grdev_display *display;
157 } display_frame;
158 };
159};
160
161/*
162 * Sessions
163 */
164
165enum {
166 GRDEV_SESSION_CUSTOM = (1 << 0),
167 GRDEV_SESSION_MANAGED = (1 << 1),
168};
169
170int grdev_session_new(grdev_session **out,
171 grdev_context *context,
172 unsigned int flags,
173 const char *name,
174 grdev_event_fn event_fn,
175 void *userdata);
176grdev_session *grdev_session_free(grdev_session *session);
177
178DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_session*, grdev_session_free);
179
180bool grdev_session_is_enabled(grdev_session *session);
181void grdev_session_enable(grdev_session *session);
182void grdev_session_disable(grdev_session *session);
183
184void grdev_session_commit(grdev_session *session);
185void grdev_session_restore(grdev_session *session);
186
187void grdev_session_add_drm(grdev_session *session, struct udev_device *ud);
188void grdev_session_remove_drm(grdev_session *session, struct udev_device *ud);
189void grdev_session_hotplug_drm(grdev_session *session, struct udev_device *ud);
190
191/*
192 * Contexts
193 */
194
195int grdev_context_new(grdev_context **out, sd_event *event, sd_bus *sysbus);
196grdev_context *grdev_context_ref(grdev_context *context);
197grdev_context *grdev_context_unref(grdev_context *context);
198
199DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_context*, grdev_context_unref);