/* * Copyright (C) 2020 Purism SPC * SPDX-License-Identifier: GPL-3.0+ * Author: Guido Günther */ #define LIBFEEDBACK_USE_UNSTABLE_API #include "libfeedback.h" #include #include #include #define DEFAULT_EVENT "phone-incoming-call" static GMainLoop *loop; static gboolean on_watch_expired (gpointer unused) { g_warning ("Watch expired waiting for all feedbacks to finish"); g_main_loop_quit (loop); return G_SOURCE_REMOVE; } static void on_feedback_ended (LfbEvent *event, int* data) { g_return_if_fail (LFB_IS_EVENT (event)); g_debug ("Feedback ended for event"); *data = TRUE; g_main_loop_quit (loop); } static gboolean on_user_input (GIOChannel *channel, GIOCondition cond, LfbEvent *event) { g_autoptr(GError) err = NULL; if (cond == G_IO_IN) { g_print ("Ending feedback\n"); if (!lfb_event_end_feedback (event, &err)) g_warning("Failed to end feedback: %s", err->message); } return FALSE; } static gboolean trigger_event(const char *name, gint timeout) { g_autoptr(GError) err = NULL; g_autoptr(LfbEvent) event = NULL; g_autoptr(GIOChannel) input = NULL; int success = FALSE; g_print("Triggering feedback for event '%s'\n", name); event = lfb_event_new (name); lfb_event_set_timeout (event, timeout); g_signal_connect (event, "feedback-ended", (GCallback)on_feedback_ended, &success); if (!lfb_event_trigger_feedback (event, &err)) { g_print("Failed to report event: %s\n", err->message); return FALSE; } input = g_io_channel_unix_new (STDIN_FILENO); g_io_add_watch (input, G_IO_IN, (GIOFunc)on_user_input, event); g_print ("Press to end feedback right away.\n"); loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); g_main_loop_unref (loop); return success; } static void on_profile_changed (LfbGdbusFeedback *proxy, GParamSpec *psepc, gpointer unused) { g_print("Set feedback profile to: '%s'\n", lfb_get_feedback_profile()); g_main_loop_quit (loop); } static gboolean set_profile (const gchar *profile) { LfbGdbusFeedback *proxy; const gchar *current; current = lfb_get_feedback_profile(); g_debug("Current profile is %s", current); if (!g_strcmp0 (current, profile)) { g_print ("Profile is already set to %s\n", profile); return TRUE; } g_debug("Setting profile to %s", profile); proxy = lfb_get_proxy (); /* Set profile and wait until we got notified about the profile change */ loop = g_main_loop_new (NULL, FALSE); lfb_set_feedback_profile(profile); g_signal_connect (proxy, "notify::profile", (GCallback)on_profile_changed, NULL); g_main_loop_run (loop); g_print("Current feedback profile is: '%s'\n", lfb_get_feedback_profile()); return TRUE; } int main(int argc, char *argv[0]) { g_autoptr(GOptionContext) opt_context = NULL; g_autoptr(GError) err = NULL; g_autofree gchar *profile = NULL; const char *name = NULL; gboolean success; int watch = 30; int timeout = -1; const GOptionEntry options [] = { {"event", 'E', 0, G_OPTION_ARG_STRING, &name, "Event name. (default: " DEFAULT_EVENT ").", NULL}, {"timeout", 't', 0, G_OPTION_ARG_INT, &timeout, "Run feedback for timeout seconds", NULL}, {"profile", 'P', 0, G_OPTION_ARG_STRING, &profile, "Profile name to set" , NULL}, {"watch", 'w', 0, G_OPTION_ARG_INT, &watch, "How long to watch for feedback longest", NULL}, { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL } }; setlocale (LC_ALL, ""); opt_context = g_option_context_new ("- A cli for feedbackd"); g_option_context_add_main_entries (opt_context, options, NULL); if (!g_option_context_parse (opt_context, &argc, &argv, &err)) { g_warning ("%s", err->message); return 1; } if (!lfb_init("org.sigxcpu.fbcli", &err)) { g_print("Failed to init libfeedback: %s\n", err->message); return 1; } if (!name) name = g_strdup (DEFAULT_EVENT); g_timeout_add_seconds (watch, (GSourceFunc)on_watch_expired, NULL); if (profile) success = set_profile (profile); else success = trigger_event (name, timeout); lfb_uninit (); return !success; }