hook: delete by callback *and* data argument
authorDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 25 Mar 2012 15:08:00 +0000 (17:08 +0200)
committerDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 25 Mar 2012 15:08:00 +0000 (17:08 +0200)
When deleting a hook we should not search for the callback only. Otherwise
we might remove the wrong callback. Therefore, we now search for callback
and data argument. If multiple callbacks are registered with the same data
and cb, then we don't care which one is removed as this wouldn't make any
difference. They behave the same way, anyway.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
src/input.c
src/input.h
src/misc.c
src/misc.h
src/ui.c
src/uterm.h
src/uterm_video.c

index 5d6b3d8..21ce421 100644 (file)
@@ -615,12 +615,13 @@ int kmscon_input_register_cb(struct kmscon_input *input, kmscon_input_cb cb,
        return kmscon_hook_add_cast(input->hook, cb, data);
 }
 
-void kmscon_input_unregister_cb(struct kmscon_input *input, kmscon_input_cb cb)
+void kmscon_input_unregister_cb(struct kmscon_input *input, kmscon_input_cb cb,
+                               void *data)
 {
        if (!input || !cb)
                return;
 
-       kmscon_hook_rm_cast(input->hook, cb);
+       kmscon_hook_rm_cast(input->hook, cb, data);
 }
 
 void kmscon_input_sleep(struct kmscon_input *input)
index b6753a9..31e3ddc 100644 (file)
@@ -87,7 +87,8 @@ int kmscon_input_connect_eloop(struct kmscon_input *input,
 void kmscon_input_disconnect_eloop(struct kmscon_input *input);
 int kmscon_input_register_cb(struct kmscon_input *input, kmscon_input_cb cb,
                                void *data);
-void kmscon_input_unregister_cb(struct kmscon_input *input, kmscon_input_cb cb);
+void kmscon_input_unregister_cb(struct kmscon_input *input, kmscon_input_cb cb,
+                               void *data);
 
 void kmscon_input_sleep(struct kmscon_input *input);
 void kmscon_input_wake_up(struct kmscon_input *input);
index 41867f3..5ee1e92 100644 (file)
@@ -227,7 +227,7 @@ int kmscon_hook_add(struct kmscon_hook *hook, kmscon_hook_cb cb, void *data)
        return 0;
 }
 
-void kmscon_hook_rm(struct kmscon_hook *hook, kmscon_hook_cb cb)
+void kmscon_hook_rm(struct kmscon_hook *hook, kmscon_hook_cb cb, void *data)
 {
        struct hook_entry *entry, *tmp;
 
@@ -235,11 +235,11 @@ void kmscon_hook_rm(struct kmscon_hook *hook, kmscon_hook_cb cb)
                return;
 
        tmp = NULL;
-       if (hook->entries->cb == cb) {
+       if (hook->entries->cb == cb && hook->entries->data == data) {
                tmp = hook->entries;
                hook->entries = tmp->next;
        } else for (entry = hook->entries; entry->next; entry = entry->next) {
-               if (entry->next->cb == cb) {
+               if (entry->next->cb == cb && entry->next->data == data) {
                        tmp = entry->next;
                        entry->next = tmp->next;
                        break;
index 9c088ce..80b17e4 100644 (file)
@@ -51,11 +51,11 @@ typedef void (*kmscon_hook_cb) (void *parent, void *arg, void *data);
 int kmscon_hook_new(struct kmscon_hook **out);
 void kmscon_hook_free(struct kmscon_hook *hook);
 int kmscon_hook_add(struct kmscon_hook *hook, kmscon_hook_cb cb, void *data);
-void kmscon_hook_rm(struct kmscon_hook *hook, kmscon_hook_cb cb);
+void kmscon_hook_rm(struct kmscon_hook *hook, kmscon_hook_cb cb, void *data);
 void kmscon_hook_call(struct kmscon_hook *hook, void *parent, void *arg);
 #define kmscon_hook_add_cast(hook, cb, data) \
        kmscon_hook_add((hook), (kmscon_hook_cb)(cb), (data))
-#define kmscon_hook_rm_cast(hook, cb) \
-       kmscon_hook_rm((hook), (kmscon_hook_cb)(cb))
+#define kmscon_hook_rm_cast(hook, cb, data) \
+       kmscon_hook_rm((hook), (kmscon_hook_cb)(cb), (data))
 
 #endif /* KMSCON_MISC_H */
index e81b75a..a26e2e8 100644 (file)
--- a/src/ui.c
+++ b/src/ui.c
@@ -137,9 +137,9 @@ int kmscon_ui_new(struct kmscon_ui **out,
        return 0;
 
 err_input:
-       kmscon_input_unregister_cb(ui->input, input_event);
+       kmscon_input_unregister_cb(ui->input, input_event, ui);
 err_video:
-       uterm_video_unregister_cb(ui->video, video_event);
+       uterm_video_unregister_cb(ui->video, video_event, ui);
 err_term:
        kmscon_terminal_unref(ui->term);
 err_ff:
@@ -156,8 +156,8 @@ void kmscon_ui_free(struct kmscon_ui *ui)
        if (!ui)
                return;
 
-       kmscon_input_unregister_cb(ui->input, input_event);
-       uterm_video_unregister_cb(ui->video, video_event);
+       kmscon_input_unregister_cb(ui->input, input_event, ui);
+       uterm_video_unregister_cb(ui->video, video_event, ui);
        kmscon_terminal_unref(ui->term);
        kmscon_font_factory_unref(ui->ff);
        kmscon_symbol_table_unref(ui->st);
index 0e435af..fce4dde 100644 (file)
@@ -186,7 +186,8 @@ void uterm_video_segfault(struct uterm_video *video);
 struct uterm_display *uterm_video_get_displays(struct uterm_video *video);
 int uterm_video_register_cb(struct uterm_video *video, uterm_video_cb cb,
                                void *data);
-void uterm_video_unregister_cb(struct uterm_video *video, uterm_video_cb cb);
+void uterm_video_unregister_cb(struct uterm_video *video, uterm_video_cb cb,
+                               void *data);
 
 void uterm_video_sleep(struct uterm_video *video);
 int uterm_video_wake_up(struct uterm_video *video);
index 1d94c2d..444f412 100644 (file)
@@ -535,12 +535,13 @@ int uterm_video_register_cb(struct uterm_video *video, uterm_video_cb cb,
        return kmscon_hook_add_cast(video->hook, cb, data);
 }
 
-void uterm_video_unregister_cb(struct uterm_video *video, uterm_video_cb cb)
+void uterm_video_unregister_cb(struct uterm_video *video, uterm_video_cb cb,
+                               void *data)
 {
        if (!video || !cb)
                return;
 
-       kmscon_hook_rm_cast(video->hook, cb);
+       kmscon_hook_rm_cast(video->hook, cb, data);
 }
 
 void uterm_video_sleep(struct uterm_video *video)