From 663b2b88def5fb28cce8868e2ce2a37c15bb7e0e Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 10 Oct 2012 22:26:01 +0200 Subject: [PATCH] uterm: video: fbdev: send UTERM_NEW/GONE events for fbdev devices We didn't send these events as the fake-display for fbdev video-objects was created during video-creation and thus no listener could have been registered so far. However, this caused every video listener to iterate over all displays on wake-up. This is really ugly and we want to avoid that. Therefore, we now send the UTERM_NEW event in an idle-handler and the GONE event on shutdown. Signed-off-by: David Herrmann --- src/uterm_video.h | 1 + src/uterm_video_fbdev.c | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/uterm_video.h b/src/uterm_video.h index b4b7655..8803592 100644 --- a/src/uterm_video.h +++ b/src/uterm_video.h @@ -243,6 +243,7 @@ struct fbdev_mode { struct fbdev_display { char *node; int fd; + bool pending_intro; struct fb_fix_screeninfo finfo; struct fb_var_screeninfo vinfo; diff --git a/src/uterm_video_fbdev.c b/src/uterm_video_fbdev.c index 877ea28..28228ac 100644 --- a/src/uterm_video_fbdev.c +++ b/src/uterm_video_fbdev.c @@ -845,6 +845,22 @@ static int display_fill(struct uterm_display *disp, return 0; } +static void intro_idle_event(struct ev_eloop *eloop, void *unused, void *data) +{ + struct uterm_display *disp = data; + + if (!disp->fbdev.pending_intro) + return; + + disp->fbdev.pending_intro = false; + ev_eloop_unregister_idle_cb(eloop, intro_idle_event, disp); + + if (!disp->video) + return; + + VIDEO_CB(disp->video, disp, UTERM_NEW); +} + static int video_init(struct uterm_video *video, const char *node) { int ret; @@ -854,11 +870,18 @@ static int video_init(struct uterm_video *video, const char *node) if (ret) return ret; + ret = ev_eloop_register_idle_cb(video->eloop, intro_idle_event, disp); + if (ret) { + log_error("cannot register idle event: %d", ret); + goto err_free; + } + disp->fbdev.pending_intro = true; + disp->fbdev.node = strdup(node); if (!disp->fbdev.node) { log_err("cannot dup node name"); ret = -ENOMEM; - goto err_free; + goto err_idle; } disp->fbdev.fd = open(node, O_RDWR | O_CLOEXEC); @@ -877,6 +900,8 @@ static int video_init(struct uterm_video *video, const char *node) err_node: free(disp->fbdev.node); +err_idle: + ev_eloop_register_idle_cb(video->eloop, intro_idle_event, disp); err_free: uterm_display_unref(disp); return ret; @@ -889,6 +914,13 @@ static void video_destroy(struct uterm_video *video) log_info("free device %p", video); disp = video->displays; video->displays = disp->next; + + if (disp->fbdev.pending_intro) + ev_eloop_unregister_idle_cb(video->eloop, intro_idle_event, + disp); + else + VIDEO_CB(video, disp, UTERM_GONE); + close(disp->fbdev.fd); free(disp->fbdev.node); uterm_display_unref(disp);