From e9019e42cbaa8245a417823cf3eb44777fc680be Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 21 Jul 2012 15:38:04 +0200 Subject: [PATCH] ui: arrange video objects in a list If multiple video objects are added to a UI object, we need to manage them in a list to allow each of them to be added to a running terminal. This only changes the internal structure but does still create the video object when creating the UI object. This is, because the terminal subsystem depends on uterm-video and this needs to be resolved, first. Signed-off-by: David Herrmann --- src/ui.c | 114 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 89 insertions(+), 25 deletions(-) diff --git a/src/ui.c b/src/ui.c index e4cb4ba..3c62008 100644 --- a/src/ui.c +++ b/src/ui.c @@ -34,49 +34,118 @@ #include "conf.h" #include "eloop.h" #include "log.h" +#include "static_misc.h" #include "terminal.h" #include "ui.h" #include "uterm.h" #define LOG_SUBSYSTEM "config" +struct ui_video { + struct kmscon_dlist list; + struct kmscon_ui *ui; + struct uterm_video *video; +}; + struct kmscon_ui { struct ev_eloop *eloop; - struct uterm_video *video; struct uterm_input *input; + struct kmscon_dlist video_list; struct kmscon_terminal *term; }; +static void video_activate(struct ui_video *vid, struct uterm_display *disp) +{ + int ret; + + if (!uterm_video_is_awake(vid->video)) + return; + + if (uterm_display_get_state(disp) == UTERM_DISPLAY_INACTIVE) { + ret = uterm_display_activate(disp, NULL); + if (ret) { + log_warning("cannot activate display"); + return; + } + ret = uterm_display_set_dpms(disp, UTERM_DPMS_ON); + if (ret) { + log_warning("cannot set DPMS state to on for display"); + return; + } + } +} + static void video_event(struct uterm_video *video, struct uterm_video_hotplug *ev, void *data) { - struct kmscon_ui *ui = data; - int ret; + struct ui_video *vid = data; + struct kmscon_ui *ui = vid->ui; struct uterm_display *disp; - struct uterm_video_hotplug fev = *ev; if (ev->action == UTERM_NEW) { - if (uterm_display_get_state(ev->display) == UTERM_DISPLAY_INACTIVE) { - ret = uterm_display_activate(ev->display, NULL); - if (ret) - return; - ret = uterm_display_set_dpms(ev->display, UTERM_DPMS_ON); - if (ret) - return; - } + video_activate(vid, ev->display); kmscon_terminal_add_display(ui->term, ev->display); } else if (ev->action == UTERM_WAKE_UP) { disp = uterm_video_get_displays(video); while (disp) { - fev.display = disp; - fev.action = UTERM_NEW; - video_event(video, &fev, data); + video_activate(vid, disp); + kmscon_terminal_add_display(ui->term, disp); disp = uterm_display_next(disp); } } } +static void video_new(struct kmscon_ui *ui, struct uterm_video *video) +{ + struct kmscon_dlist *iter; + struct ui_video *vid; + int ret; + + kmscon_dlist_for_each(iter, &ui->video_list) { + vid = kmscon_dlist_entry(iter, struct ui_video, list); + if (vid->video == video) + return; + } + + vid = malloc(sizeof(*vid)); + if (!vid) + return; + memset(vid, 0, sizeof(*vid)); + vid->ui = ui; + vid->video = video; + + ret = uterm_video_register_cb(vid->video, video_event, vid); + if (ret) + goto err_free; + + kmscon_dlist_link(&ui->video_list, &vid->list); + uterm_video_ref(vid->video); + return; + +err_free: + free(vid); +} + +static void video_free(struct ui_video *vid) +{ + kmscon_dlist_unlink(&vid->list); + uterm_video_unregister_cb(vid->video, video_event, vid); + uterm_video_unref(vid->video); + free(vid); +} + +static void video_free_all(struct kmscon_ui *ui) +{ + struct ui_video *vid; + struct kmscon_dlist *iter, *tmp; + + kmscon_dlist_for_each_safe(iter, tmp, &ui->video_list) { + vid = kmscon_dlist_entry(iter, struct ui_video, list); + video_free(vid); + } +} + static void input_event(struct uterm_input *input, struct uterm_input_event *ev, void *data) @@ -107,16 +176,14 @@ int kmscon_ui_new(struct kmscon_ui **out, return -ENOMEM; memset(ui, 0, sizeof(*ui)); ui->eloop = eloop; - ui->video = video; ui->input = input; + kmscon_dlist_init(&ui->video_list); - ret = kmscon_terminal_new(&ui->term, eloop, ui->video, ui->input); + ret = kmscon_terminal_new(&ui->term, eloop, video, ui->input); if (ret) goto err_free; - ret = uterm_video_register_cb(ui->video, video_event, ui); - if (ret) - goto err_term; + video_new(ui, video); ret = uterm_input_register_cb(ui->input, input_event, ui); if (ret) @@ -127,7 +194,6 @@ int kmscon_ui_new(struct kmscon_ui **out, goto err_input; ev_eloop_ref(ui->eloop); - uterm_video_ref(ui->video); uterm_input_ref(ui->input); *out = ui; return 0; @@ -135,8 +201,7 @@ int kmscon_ui_new(struct kmscon_ui **out, err_input: uterm_input_unregister_cb(ui->input, input_event, ui); err_video: - uterm_video_unregister_cb(ui->video, video_event, ui); -err_term: + video_free_all(ui); kmscon_terminal_unref(ui->term); err_free: free(ui); @@ -149,10 +214,9 @@ void kmscon_ui_free(struct kmscon_ui *ui) return; uterm_input_unregister_cb(ui->input, input_event, ui); - uterm_video_unregister_cb(ui->video, video_event, ui); + video_free_all(ui); kmscon_terminal_unref(ui->term); uterm_input_unref(ui->input); - uterm_video_unref(ui->video); ev_eloop_unref(ui->eloop); free(ui); }