struct uterm_monitor_dev *udev)
{
int ret;
- unsigned int mode;
+ const struct uterm_video_module *mode;
struct app_video *vid;
if (seat->app->exiting)
mode = UTERM_VIDEO_FBDEV;
}
- ret = uterm_video_new(&vid->video, seat->app->eloop, mode, node);
+ ret = uterm_video_new(&vid->video, seat->app->eloop, node, mode);
if (ret) {
if (mode == UTERM_VIDEO_DRM) {
log_info("cannot create drm device %s on seat %s (%d); trying dumb drm mode",
vid->node, seat->name, ret);
ret = uterm_video_new(&vid->video, seat->app->eloop,
- UTERM_VIDEO_DUMB, node);
+ node, UTERM_VIDEO_DUMB);
if (ret)
goto err_node;
} else {
}
}
-bool uterm_video_available(unsigned int type)
+bool uterm_video_available(const struct uterm_video_module *mod)
{
- switch (type) {
- case UTERM_VIDEO_DRM:
-#ifdef BUILD_ENABLE_VIDEO_DRM
- return video_drm_available();
-#endif
+ if (!mod)
return false;
- case UTERM_VIDEO_DUMB:
-#ifdef BUILD_ENABLE_VIDEO_DUMB
+
+ if (mod == UTERM_VIDEO_DUMB || mod == UTERM_VIDEO_DRM)
return video_drm_available();
-#endif
- return false;
- case UTERM_VIDEO_FBDEV:
-#ifdef BUILD_ENABLE_VIDEO_FBDEV
- return true;
-#endif
- return false;
- default:
- return false;
- }
+
+ return true;
}
int mode_new(struct uterm_mode **out, const struct mode_ops *ops)
return VIDEO_CALL(disp->ops->fake_blendv, -EOPNOTSUPP, disp, req, num);
}
-int uterm_video_new(struct uterm_video **out,
- struct ev_eloop *eloop,
- unsigned int type,
- const char *node)
+int uterm_video_new(struct uterm_video **out, struct ev_eloop *eloop,
+ const char *node, const struct uterm_video_module *mod)
{
struct uterm_video *video;
int ret;
- const struct video_ops *ops;
if (!out || !eloop)
return -EINVAL;
-
- switch (type) {
- case UTERM_VIDEO_DRM:
- if (!drm_available) {
- log_err("DRM backend is not available");
- return -EOPNOTSUPP;
- }
- ops = &drm_video_ops;
- break;
- case UTERM_VIDEO_DUMB:
- if (!dumb_available) {
- log_err("Dumb DRM backend is not available");
- return -EOPNOTSUPP;
- }
- ops = &dumb_video_ops;
- break;
- case UTERM_VIDEO_FBDEV:
- if (!fbdev_available) {
- log_err("FBDEV backend is not available");
- return -EOPNOTSUPP;
- }
- ops = &fbdev_video_ops;
- break;
- default:
- log_err("invalid video backend %d", type);
- return -EINVAL;
- }
+ if (!mod || !mod->ops)
+ return -EOPNOTSUPP;
video = malloc(sizeof(*video));
if (!video)
return -ENOMEM;
memset(video, 0, sizeof(*video));
video->ref = 1;
- video->ops = ops;
+ video->mod = mod;
+ video->ops = mod->ops;
video->eloop = eloop;
ret = shl_hook_new(&video->hook);
struct uterm_mode;
struct uterm_display;
struct uterm_video;
+struct uterm_video_module;
enum uterm_display_state {
UTERM_DISPLAY_ACTIVE,
UTERM_DPMS_UNKNOWN,
};
-enum uterm_video_type {
- UTERM_VIDEO_DRM,
- UTERM_VIDEO_DUMB,
- UTERM_VIDEO_FBDEV,
-};
-
enum uterm_video_action {
UTERM_WAKE_UP,
UTERM_SLEEP,
/* misc */
const char *uterm_dpms_to_name(int dpms);
-bool uterm_video_available(unsigned int type);
+bool uterm_video_available(const struct uterm_video_module *mod);
/* display modes interface */
/* video interface */
int uterm_video_new(struct uterm_video **out, struct ev_eloop *eloop,
- unsigned int type, const char *node);
+ const char *node, const struct uterm_video_module *mod);
void uterm_video_ref(struct uterm_video *video);
void uterm_video_unref(struct uterm_video *video);
bool uterm_video_is_awake(struct uterm_video *video);
void uterm_video_poll(struct uterm_video *video);
+/* external modules */
+
+#ifdef BUILD_ENABLE_VIDEO_FBDEV
+extern const struct uterm_video_module *UTERM_VIDEO_FBDEV;
+#else
+#define UTERM_VIDEO_FBDEV NULL
+#endif
+
+#ifdef BUILD_ENABLE_VIDEO_DUMB
+extern const struct uterm_video_module *UTERM_VIDEO_DUMB;
+#else
+#define UTERM_VIDEO_DUMB NULL
+#endif
+
+#ifdef BUILD_ENABLE_VIDEO_DRM
+extern const struct uterm_video_module *UTERM_VIDEO_DRM;
+#else
+#define UTERM_VIDEO_DRM NULL
+#endif
+
#endif /* UTERM_UTERM_VIDEO_H */
return mode->drm.info.vdisplay;
}
+static const struct mode_ops drm_mode_ops = {
+ .init = NULL,
+ .destroy = NULL,
+ .get_name = mode_get_name,
+ .get_width = mode_get_width,
+ .get_height = mode_get_height,
+};
+
static void bo_destroy_event(struct gbm_bo *bo, void *data)
{
struct drm_rb *rb = data;
return 0;
}
+static const struct display_ops drm_display_ops = {
+ .init = NULL,
+ .destroy = NULL,
+ .activate = display_activate,
+ .deactivate = display_deactivate,
+ .set_dpms = display_set_dpms,
+ .use = display_use,
+ .swap = display_swap,
+ .blit = display_blit,
+ .blend = display_blend,
+ .blendv = display_fake_blendv,
+ .fake_blendv = display_fake_blendv,
+ .fill = display_fill,
+};
+
static void show_displays(struct uterm_video *video)
{
int ret;
return 0;
}
-const struct mode_ops drm_mode_ops = {
- .init = NULL,
- .destroy = NULL,
- .get_name = mode_get_name,
- .get_width = mode_get_width,
- .get_height = mode_get_height,
-};
-
-const struct display_ops drm_display_ops = {
- .init = NULL,
- .destroy = NULL,
- .activate = display_activate,
- .deactivate = display_deactivate,
- .set_dpms = display_set_dpms,
- .use = display_use,
- .swap = display_swap,
- .blit = display_blit,
- .blend = display_blend,
- .blendv = display_fake_blendv,
- .fake_blendv = display_fake_blendv,
- .fill = display_fill,
-};
-
-const struct video_ops drm_video_ops = {
+static const struct video_ops drm_video_ops = {
.init = video_init,
.destroy = video_destroy,
.segfault = NULL, /* TODO: reset all saved CRTCs on segfault */
.sleep = video_sleep,
.wake_up = video_wake_up,
};
+
+static const struct uterm_video_module drm_module = {
+ .ops = &drm_video_ops,
+};
+
+const struct uterm_video_module *UTERM_VIDEO_DRM = &drm_module;
return mode->dumb.info.vdisplay;
}
+static const struct mode_ops dumb_mode_ops = {
+ .init = NULL,
+ .destroy = NULL,
+ .get_name = mode_get_name,
+ .get_width = mode_get_width,
+ .get_height = mode_get_height,
+};
+
static int init_rb(struct uterm_display *disp, struct dumb_rb *rb)
{
int ret;
return 0;
}
+static const struct display_ops dumb_display_ops = {
+ .init = NULL,
+ .destroy = NULL,
+ .activate = display_activate,
+ .deactivate = display_deactivate,
+ .set_dpms = display_set_dpms,
+ .use = NULL,
+ .swap = display_swap,
+ .blit = display_blit,
+ .blend = display_blend,
+ .blendv = display_fake_blendv,
+ .fake_blendv = display_fake_blendv,
+ .fill = display_fill,
+};
+
static void show_displays(struct uterm_video *video)
{
int ret;
return 0;
}
-const struct mode_ops dumb_mode_ops = {
- .init = NULL,
- .destroy = NULL,
- .get_name = mode_get_name,
- .get_width = mode_get_width,
- .get_height = mode_get_height,
-};
-
-const struct display_ops dumb_display_ops = {
- .init = NULL,
- .destroy = NULL,
- .activate = display_activate,
- .deactivate = display_deactivate,
- .set_dpms = display_set_dpms,
- .use = NULL,
- .swap = display_swap,
- .blit = display_blit,
- .blend = display_blend,
- .blendv = display_fake_blendv,
- .fake_blendv = display_fake_blendv,
- .fill = display_fill,
-};
-
-const struct video_ops dumb_video_ops = {
+static const struct video_ops dumb_video_ops = {
.init = video_init,
.destroy = video_destroy,
.segfault = NULL, /* TODO: reset all saved CRTCs on segfault */
.sleep = video_sleep,
.wake_up = video_wake_up,
};
+
+static const struct uterm_video_module dumb_module = {
+ .ops = &dumb_video_ops,
+};
+
+const struct uterm_video_module *UTERM_VIDEO_DUMB = &dumb_module;
return mode->fbdev.height;
}
+static const struct mode_ops fbdev_mode_ops = {
+ .init = NULL,
+ .destroy = NULL,
+ .get_name = mode_get_name,
+ .get_width = mode_get_width,
+ .get_height = mode_get_height,
+};
+
static int refresh_info(struct uterm_display *disp)
{
int ret;
return 0;
}
+static const struct display_ops fbdev_display_ops = {
+ .init = NULL,
+ .destroy = NULL,
+ .activate = display_activate,
+ .deactivate = display_deactivate,
+ .set_dpms = display_set_dpms,
+ .use = NULL,
+ .swap = display_swap,
+ .blit = display_blit,
+ .blend = display_blend,
+ .blendv = display_fake_blendv,
+ .fake_blendv = display_fake_blendv,
+ .fill = display_fill,
+};
+
static void intro_idle_event(struct ev_eloop *eloop, void *unused, void *data)
{
struct uterm_display *disp = data;
return 0;
}
-const struct mode_ops fbdev_mode_ops = {
- .init = NULL,
- .destroy = NULL,
- .get_name = mode_get_name,
- .get_width = mode_get_width,
- .get_height = mode_get_height,
-};
-
-const struct display_ops fbdev_display_ops = {
- .init = NULL,
- .destroy = NULL,
- .activate = display_activate,
- .deactivate = display_deactivate,
- .set_dpms = display_set_dpms,
- .use = NULL,
- .swap = display_swap,
- .blit = display_blit,
- .blend = display_blend,
- .blendv = display_fake_blendv,
- .fake_blendv = display_fake_blendv,
- .fill = display_fill,
-};
-
-const struct video_ops fbdev_video_ops = {
+static const struct video_ops fbdev_video_ops = {
.init = video_init,
.destroy = video_destroy,
.segfault = NULL, /* TODO */
.sleep = video_sleep,
.wake_up = video_wake_up,
};
+
+static const struct uterm_video_module fbdev_module = {
+ .ops = &fbdev_video_ops,
+};
+
+const struct uterm_video_module *UTERM_VIDEO_FBDEV = &fbdev_module;
/* Internal definitions */
-#ifndef UTERM_VIDEO_H
-#define UTERM_VIDEO_H
+#ifndef UTERM_VIDEO_INTERNAL_H
+#define UTERM_VIDEO_INTERNAL_H
#include <inttypes.h>
#include <limits.h>
int (*wake_up) (struct uterm_video *video);
};
+struct uterm_video_module {
+ const struct video_ops *ops;
+};
+
#define VIDEO_CALL(func, els, ...) (func ? func(__VA_ARGS__) : els)
/* drm */
GLuint uni_blit_tex;
};
-static const bool drm_available = true;
-extern const struct mode_ops drm_mode_ops;
-extern const struct display_ops drm_display_ops;
-extern const struct video_ops drm_video_ops;
-
#else /* !BUILD_ENABLE_VIDEO_DRM */
struct drm_mode {
int unused;
};
-static const bool drm_available = false;
-static const struct mode_ops drm_mode_ops;
-static const struct display_ops drm_display_ops;
-static const struct video_ops drm_video_ops;
-
#endif /* BUILD_ENABLE_VIDEO_DRM */
/* dumb drm */
struct ev_fd *efd;
};
-static const bool dumb_available = true;
-extern const struct mode_ops dumb_mode_ops;
-extern const struct display_ops dumb_display_ops;
-extern const struct video_ops dumb_video_ops;
-
#else /* !BUILD_ENABLE_VIDEO_DUMB */
struct dumb_mode {
int unused;
};
-static const bool dumb_available = false;
-static const struct mode_ops dumb_mode_ops;
-static const struct display_ops dumb_display_ops;
-static const struct video_ops dumb_video_ops;
-
#endif /* BUILD_ENABLE_VIDEO_DUMB */
/* fbdev */
int unused;
};
-static const bool fbdev_available = true;
-extern const struct mode_ops fbdev_mode_ops;
-extern const struct display_ops fbdev_display_ops;
-extern const struct video_ops fbdev_video_ops;
-
#else /* !BUILD_ENABLE_VIDEO_FBDEV */
struct fbdev_mode {
int unused;
};
-static const bool fbdev_available = false;
-static const struct mode_ops fbdev_mode_ops;
-static const struct display_ops fbdev_display_ops;
-static const struct video_ops fbdev_video_ops;
-
#endif /* BUILD_ENABLE_VIDEO_FBDEV */
/* uterm_mode */
struct uterm_display *displays;
struct shl_hook *hook;
+ const struct uterm_video_module *mod;
const struct video_ops *ops;
union {
struct drm_video drm;
#endif
-#endif /* UTERM_VIDEO_H */
+#endif /* UTERM_VIDEO_INTERNAL_H */