/** * kmscon_text_set: * @txt: Valid text-renderer object * @font: font object * @bold_font: bold font object or NULL * @disp: display object * * This makes the text-renderer @txt use the font @font and screen @screen. You * can drop your reference to both after calling this. * This calls kmscon_text_unset() first to remove all previous associations. * None of the arguments can be NULL! * If this function fails then you must assume that no font/screen will be set * and the object is invalid. * If @bold_font is NULL, @font is also used for bold characters. The caller * must make sure that @font and @bold_font have the same metrics. The renderers * will always use the metrics of @font. * * Returns: 0 on success, negative error code on failure. */ int kmscon_text_set(struct kmscon_text *txt, struct kmscon_font *font, struct kmscon_font *bold_font, struct uterm_display *disp) { int ret; if (!txt || !font || !disp) return -EINVAL; if (!bold_font) bold_font = font; kmscon_text_unset(txt); txt->font = font; txt->bold_font = bold_font; txt->disp = disp; if (txt->ops->set) { ret = txt->ops->set(txt); if (ret) { txt->font = NULL; txt->bold_font = NULL; txt->disp = NULL; return ret; } } kmscon_font_ref(txt->font); kmscon_font_ref(txt->bold_font); uterm_display_ref(txt->disp); return 0; }
/* Until we allow multiple displays in one screen, we use this constructor which * is basically just a wrapper around "struct uterm_dispaly". * The idea behind screens is having one single drawing-target which is spread * across several displays which can be placed anywhere in the virtual screen. */ int uterm_screen_new_single(struct uterm_screen **out, struct uterm_display *disp) { struct uterm_screen *screen; if (!out || !disp) return -EINVAL; screen = malloc(sizeof(*screen)); if (!screen) return -ENOMEM; memset(screen, 0, sizeof(*screen)); screen->ref = 1; screen->disp = disp; uterm_display_ref(screen->disp); *out = screen; return 0; }
SHL_EXPORT int uterm_display_bind(struct uterm_display *disp, struct uterm_video *video) { int ret; if (!disp || !video || disp->video) return -EINVAL; ret = ev_eloop_add_timer(video->eloop, disp->vblank_timer); if (ret) return ret; shl_dlist_link_tail(&video->displays, &disp->list); disp->video = video; uterm_display_ref(disp); VIDEO_CB(disp->video, disp, UTERM_NEW); return 0; }
static int display_swap(struct uterm_display *disp) { int ret; if (!display_is_online(disp) || !video_is_awake(disp->video)) return -EINVAL; if (disp->dpms != UTERM_DPMS_ON) return -EINVAL; errno = 0; disp->dumb.current_rb ^= 1; ret = drmModePageFlip(disp->video->dumb.fd, disp->dumb.crtc_id, disp->dumb.rb[disp->dumb.current_rb].fb, DRM_MODE_PAGE_FLIP_EVENT, disp); if (ret) { log_warn("page-flip failed %d %d", ret, errno); return -EFAULT; } uterm_display_ref(disp); disp->flags |= DISPLAY_VSYNC; return 0; }