void uterm_screen_unref(struct uterm_screen *screen) { if (!screen || !screen->ref || --screen->ref) return; uterm_display_unref(screen->disp); free(screen); }
static void page_flip_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) { struct uterm_display *disp = data; disp->flags &= ~DISPLAY_VSYNC; uterm_display_unref(disp); }
static void video_destroy(struct uterm_video *video) { struct uterm_display *disp; log_info("free device %p", video); disp = video->displays; video->displays = disp->next; close(disp->fbdev.fd); free(disp->fbdev.node); uterm_display_unref(disp); }
static void unbind_display(struct uterm_display *disp) { if (!display_is_conn(disp)) return; VIDEO_CB(disp->video, disp, UTERM_GONE); display_deactivate(disp); disp->video = NULL; disp->flags &= ~DISPLAY_AVAILABLE; uterm_display_unref(disp); }
static void page_flip_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) { struct uterm_display *disp = data; uterm_display_unref(disp); if (disp->flags & DISPLAY_VSYNC) { disp->flags &= ~DISPLAY_VSYNC; DISPLAY_CB(disp, UTERM_PAGE_FLIP); } }
SHL_EXPORT void uterm_display_unbind(struct uterm_display *disp) { if (!disp || !disp->video) return; VIDEO_CB(disp->video, disp, UTERM_GONE); uterm_display_deactivate(disp); disp->video = NULL; shl_dlist_unlink(&disp->list); ev_eloop_rm_timer(disp->vblank_timer); uterm_display_unref(disp); }
/** * kmscon_text_unset(): * @txt: text renderer * * This redos kmscon_text_set() by dropping the internal references to the font * and screen and invalidating the object. You need to call kmscon_text_set() * again to make use of this text renderer. * This is automatically called when the text renderer is destroyed. */ void kmscon_text_unset(struct kmscon_text *txt) { if (!txt || !txt->disp || !txt->font) return; if (txt->ops->unset) txt->ops->unset(txt); kmscon_font_unref(txt->font); kmscon_font_unref(txt->bold_font); uterm_display_unref(txt->disp); txt->font = NULL; txt->bold_font = NULL; txt->disp = NULL; txt->cols = 0; txt->rows = 0; txt->rendering = false; }
void uterm_video_unref(struct uterm_video *video) { struct uterm_display *disp; if (!video || !video->ref || --video->ref) return; log_info("free device %p", video); VIDEO_CALL(video->ops->destroy, 0, video); while ((disp = video->displays)) { video->displays = disp->next; disp->next = NULL; uterm_display_unref(disp); } shl_hook_free(video->hook); ev_eloop_unref(video->eloop); free(video); }
static void bind_display(struct uterm_video *video, drmModeRes *res, drmModeConnector *conn) { struct uterm_display *disp; struct uterm_mode *mode; int ret, i; ret = display_new(&disp, &dumb_display_ops); if (ret) return; for (i = 0; i < conn->count_modes; ++i) { ret = mode_new(&mode, &dumb_mode_ops); if (ret) continue; mode->dumb.info = conn->modes[i]; mode->next = disp->modes; disp->modes = mode; /* TODO: more sophisticated default-mode selection */ if (!disp->default_mode) disp->default_mode = mode; } if (!disp->modes) { log_warn("no valid mode for display found"); uterm_display_unref(disp); return; } disp->video = video; disp->dumb.conn_id = conn->connector_id; disp->flags |= DISPLAY_AVAILABLE; disp->next = video->displays; video->displays = disp; disp->dpms = get_dpms(disp, conn); log_info("display %p DPMS is %s", disp, uterm_dpms_to_name(disp->dpms)); VIDEO_CB(video, disp, UTERM_NEW); }
static int video_init(struct uterm_video *video, const char *node) { int ret; struct uterm_display *disp; ret = display_new(&disp, &fbdev_display_ops); if (ret) return ret; disp->fbdev.node = strdup(node); if (!disp->fbdev.node) { log_err("cannot dup node name"); ret = -ENOMEM; goto err_free; } disp->fbdev.fd = open(node, O_RDWR | O_CLOEXEC); if (disp->fbdev.fd < 0) { log_err("cannot open %s (%d): %m", node, errno); ret = -EFAULT; goto err_node; } disp->video = video; disp->dpms = UTERM_DPMS_UNKNOWN; video->displays = disp; log_info("new device on %s", disp->fbdev.node); return 0; err_node: free(disp->fbdev.node); err_free: uterm_display_unref(disp); return ret; }