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 <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2012-10-10 22:26:01 +02:00
parent 26949d961a
commit 663b2b88de
2 changed files with 34 additions and 1 deletions

View File

@ -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;

View File

@ -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);