int display_new(struct uterm_display **out, const struct display_ops *ops) { struct uterm_display *disp; int ret; if (!out || !ops) return -EINVAL; disp = malloc(sizeof(*disp)); if (!disp) return -ENOMEM; memset(disp, 0, sizeof(*disp)); disp->ref = 1; disp->ops = ops; shl_dlist_init(&disp->modes); log_info("new display %p", disp); ret = shl_hook_new(&disp->hook); if (ret) goto err_free; disp->vblank_spec.it_value.tv_nsec = 15 * 1000 * 1000; ret = ev_timer_new(&disp->vblank_timer, NULL, display_vblank_timer_event, disp, NULL, NULL); if (ret) goto err_hook; ret = VIDEO_CALL(disp->ops->init, 0, disp); if (ret) goto err_timer; *out = disp; return 0; err_timer: ev_timer_unref(disp->vblank_timer); err_hook: shl_hook_free(disp->hook); err_free: free(disp); return ret; }
SHL_EXPORT 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; if (!out || !eloop) 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->mod = mod; video->ops = mod->ops; video->eloop = eloop; shl_dlist_init(&video->displays); ret = shl_hook_new(&video->hook); if (ret) goto err_free; ret = VIDEO_CALL(video->ops->init, 0, video, node); if (ret) goto err_hook; ev_eloop_ref(video->eloop); log_info("new device %p", video); *out = video; return 0; err_hook: shl_hook_free(video->hook); err_free: free(video); return ret; }
int uterm_video_new(struct uterm_video **out, struct ev_eloop *eloop, unsigned int type, const char *node) { 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; } video = malloc(sizeof(*video)); if (!video) return -ENOMEM; memset(video, 0, sizeof(*video)); video->ref = 1; video->ops = ops; video->eloop = eloop; ret = shl_hook_new(&video->hook); if (ret) goto err_free; ret = VIDEO_CALL(video->ops->init, 0, video, node); if (ret) goto err_hook; ev_eloop_ref(video->eloop); log_info("new device %p", video); *out = video; return 0; err_hook: shl_hook_free(video->hook); err_free: free(video); return ret; }