diff --git a/src/fbd-feedback-manager.c b/src/fbd-feedback-manager.c index 7bfac52..44b934c 100644 --- a/src/fbd-feedback-manager.c +++ b/src/fbd-feedback-manager.c @@ -12,8 +12,10 @@ #include "fbd-dev-leds.h" #include "fbd-event.h" #include "fbd-feedback-vibra.h" +#include "fbd-feedback-vibra-pattern.h" #include "fbd-feedback-manager.h" #include "fbd-feedback-theme.h" +#include "fbd-haptic-manager.h" #include "fbd-theme-expander.h" #include @@ -40,6 +42,9 @@ * based on the incoming events. */ +FbdDebugFlags fbd_debug_flags; + + typedef struct _FbdFeedbackManager { LfbGdbusFeedbackSkeleton parent; @@ -54,6 +59,9 @@ typedef struct _FbdFeedbackManager { /* Key: DBus name, value: watch_id */ GHashTable *clients; + /* org.sigxcpu.Feedbackd.Haptic */ + FbdHapticManager *haptic_manager; + /* Hardware interaction */ GUdevClient *client; FbdDevVibra *vibra; @@ -410,15 +418,27 @@ fbd_feedback_manager_handle_trigger_feedback (LfbGdbusFeedback *object, feedbacks = fbd_feedback_theme_lookup_feedback (self->theme, level, event); if (feedbacks) { + gboolean has_vibra = FALSE; + for (l = feedbacks; l; l = l->next) { FbdFeedbackBase *fb = FBD_FEEDBACK_BASE (l->data); if (fbd_feedback_is_available (FBD_FEEDBACK_BASE (fb))) { - /* Handle one haptic feedback at a time */ - /* TODO: should use priorities */ - if (FBD_IS_FEEDBACK_VIBRA (fb) && fbd_dev_vibra_is_busy (self->vibra)) - continue; + /* Handle one haptic feedback at a time. In practice haptics can handle multiple + * patterns but none of the devices supports this atm */ + /* TODO: should respect priorities */ + if (FBD_IS_FEEDBACK_VIBRA (fb)) { + if (fbd_dev_vibra_is_busy (self->vibra)) + continue; + has_vibra = TRUE; + } + fbd_event_add_feedback (event, fb); + + /* Events take priority over the haptic interface */ + if (has_vibra) + fbd_haptic_manager_end_feedback (self->haptic_manager); + found_fb = TRUE; } } @@ -494,6 +514,9 @@ fbd_feedback_manager_constructed (GObject *object) g_signal_connect_swapped (self->settings, "changed::" FEEDBACKD_KEY_ALLOW_IMPORTANT, G_CALLBACK (on_feedbackd_allow_important_changed), self); on_feedbackd_allow_important_changed (self, FEEDBACKD_KEY_ALLOW_IMPORTANT, self->settings); + + if (self->vibra || fbd_debug_flags & FBD_DEBUG_FLAG_FORCE_HAPTIC) + self->haptic_manager = fbd_haptic_manager_new (); } @@ -502,6 +525,8 @@ fbd_feedback_manager_dispose (GObject *object) { FbdFeedbackManager *self = FBD_FEEDBACK_MANAGER (object); + g_clear_object (&self->haptic_manager); + g_clear_object (&self->settings); g_clear_object (&self->theme); g_clear_object (&self->sound); @@ -662,6 +687,15 @@ fbd_feedback_manager_set_profile (FbdFeedbackManager *self, const gchar *profile return TRUE; } + +FbdHapticManager * +fbd_feedback_manager_get_haptic_manager (FbdFeedbackManager *self) +{ + g_assert (FBD_IS_FEEDBACK_MANAGER (self)); + + return self->haptic_manager; +} + /** * fbd_feedback_manager_get_effective_level: * @self: The feedback manager diff --git a/src/fbd-feedback-manager.h b/src/fbd-feedback-manager.h index 7614333..19308ef 100644 --- a/src/fbd-feedback-manager.h +++ b/src/fbd-feedback-manager.h @@ -9,17 +9,25 @@ #include "fbd-dev-leds.h" #include "fbd-dev-sound.h" #include "fbd-feedback-profile.h" +#include "fbd-haptic-manager.h" #include "lfb-gdbus.h" #include G_BEGIN_DECLS +typedef enum { + FBD_DEBUG_FLAG_FORCE_HAPTIC = 1 << 0, +} FbdDebugFlags; + +extern FbdDebugFlags fbd_debug_flags; + #define FBD_TYPE_FEEDBACK_MANAGER (fbd_feedback_manager_get_type()) G_DECLARE_FINAL_TYPE (FbdFeedbackManager, fbd_feedback_manager, FBD, FEEDBACK_MANAGER, LfbGdbusFeedbackSkeleton); FbdFeedbackManager *fbd_feedback_manager_get_default (void); +FbdHapticManager *fbd_feedback_manager_get_haptic_manager (FbdFeedbackManager *self); FbdDevVibra *fbd_feedback_manager_get_dev_vibra (FbdFeedbackManager *self); FbdDevSound *fbd_feedback_manager_get_dev_sound (FbdFeedbackManager *self); FbdDevLeds *fbd_feedback_manager_get_dev_leds (FbdFeedbackManager *self); diff --git a/src/fbd.c b/src/fbd.c index b1bb320..655d05a 100644 --- a/src/fbd.c +++ b/src/fbd.c @@ -8,15 +8,24 @@ #include "fbd.h" #include "fbd-feedback-manager.h" +#include "fbd-haptic-manager.h" #include "lfb-names.h" #include "lfb-gdbus.h" #include #include - static GMainLoop *loop; + +static GDebugKey debug_keys[] = +{ + { .key = "force-haptic", + .value = FBD_DEBUG_FLAG_FORCE_HAPTIC, + }, +}; + + static gboolean quit_cb (gpointer user_data) { @@ -45,17 +54,29 @@ reload_cb (gpointer user_data) static void bus_acquired_cb (GDBusConnection *connection, - const gchar *name, - gpointer user_data) + const gchar *name, + gpointer user_data) { FbdFeedbackManager *manager = fbd_feedback_manager_get_default (); + FbdHapticManager *haptic_manager; - g_debug ("Bus acquired, creating manager..."); + g_assert (FBD_IS_FEEDBACK_MANAGER (manager)); + + g_debug ("Bus acquired, exporting manager..."); g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (manager), connection, FB_DBUS_PATH, NULL); + + haptic_manager = fbd_feedback_manager_get_haptic_manager (manager); + if (haptic_manager) { + g_debug ("Exporting haptic manager..."); + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (haptic_manager), + connection, + FB_DBUS_PATH, + NULL); + } } @@ -88,11 +109,13 @@ name_lost_cb (GDBusConnection *connection, } -int main(int argc, char *argv[]) +int +main (int argc, char *argv[]) { g_autoptr(GError) err = NULL; g_autoptr(GOptionContext) opt_context = NULL; g_autoptr (FbdFeedbackManager) manager = NULL; + const char *debugenv; opt_context = g_option_context_new ("- A daemon to trigger event feedback"); if (!g_option_context_parse (opt_context, &argc, &argv, &err)) { @@ -101,6 +124,11 @@ int main(int argc, char *argv[]) return 1; } + debugenv = g_getenv ("FEEDBACKD_DEBUG"); + fbd_debug_flags = g_parse_debug_string (debugenv, + debug_keys, + G_N_ELEMENTS (debug_keys)); + manager = fbd_feedback_manager_get_default (); fbd_feedback_manager_load_theme (manager);