summaryrefslogtreecommitdiff
path: root/src/ui.c
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2014-02-09 11:50:07 +0100
committerAlfred E. Heggestad <aeh@db.org>2014-02-09 11:50:07 +0100
commit98bf08bdcf2edd9d397f32650a8bfe62186fbecf (patch)
treeebc6ec71f44bff8c42e4eefced61948623df02fc /src/ui.c
parente6ad5cf4401b860ba402d4b7b3c7c254bc87a019 (diff)
baresip 0.4.10
Diffstat (limited to 'src/ui.c')
-rw-r--r--src/ui.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/ui.c b/src/ui.c
new file mode 100644
index 0000000..2d69fd7
--- /dev/null
+++ b/src/ui.c
@@ -0,0 +1,185 @@
+/**
+ * @file ui.c User Interface
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <re.h>
+#include <baresip.h>
+#include "core.h"
+
+
+/** User Interface */
+struct ui {
+ struct le le;
+ const char *name;
+ struct ui_st *st; /* only one instance */
+ ui_output_h *outputh;
+ struct cmd_ctx *ctx;
+};
+
+static struct list uil; /**< List of UIs (struct ui) */
+static struct config_input input_cfg;
+
+
+static void ui_handler(char key, struct re_printf *pf, void *arg)
+{
+ struct ui *ui = arg;
+
+ (void)cmd_process(ui ? &ui->ctx : NULL, key, pf);
+}
+
+
+static void destructor(void *arg)
+{
+ struct ui *ui = arg;
+
+ list_unlink(&ui->le);
+ mem_deref(ui->st);
+ mem_deref(ui->ctx);
+}
+
+
+static int stdout_handler(const char *p, size_t size, void *arg)
+{
+ (void)arg;
+
+ if (1 != fwrite(p, size, 1, stdout))
+ return ENOMEM;
+
+ return 0;
+}
+
+
+/**
+ * Register a new User-Interface (UI) module
+ *
+ * @param uip Pointer to allocated UI module
+ * @param name Name of the UI module
+ * @param alloch UI allocation handler
+ * @param outh UI output handler
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int ui_register(struct ui **uip, const char *name,
+ ui_alloc_h *alloch, ui_output_h *outh)
+{
+ struct ui *ui;
+ int err = 0;
+
+ if (!uip)
+ return EINVAL;
+
+ ui = mem_zalloc(sizeof(*ui), destructor);
+ if (!ui)
+ return ENOMEM;
+
+ list_append(&uil, &ui->le, ui);
+
+ ui->name = name;
+ ui->outputh = outh;
+
+ if (alloch) {
+ struct ui_prm prm;
+
+ prm.device = input_cfg.device;
+ prm.port = input_cfg.port;
+
+ err = alloch(&ui->st, &prm, ui_handler, ui);
+ if (err) {
+ warning("ui: register: module '%s' failed (%m)\n",
+ ui->name, err);
+ }
+ }
+
+ if (err)
+ mem_deref(ui);
+ else
+ *uip = ui;
+
+ return err;
+}
+
+
+/**
+ * Send input to the UI subsystem
+ *
+ * @param key Input character
+ */
+void ui_input(char key)
+{
+ struct re_printf pf;
+
+ pf.vph = stdout_handler;
+ pf.arg = NULL;
+
+ ui_handler(key, &pf, list_ledata(uil.head));
+}
+
+
+/**
+ * Send an input string to the UI subsystem
+ *
+ * @param str Input string
+ */
+void ui_input_str(const char *str)
+{
+ struct re_printf pf;
+ struct pl pl;
+
+ if (!str)
+ return;
+
+ pf.vph = stdout_handler;
+ pf.arg = NULL;
+
+ pl_set_str(&pl, str);
+
+ (void)ui_input_pl(&pf, &pl);
+}
+
+
+int ui_input_pl(struct re_printf *pf, const struct pl *pl)
+{
+ struct cmd_ctx *ctx = NULL;
+ size_t i;
+ int err = 0;
+
+ if (!pf || !pl)
+ return EINVAL;
+
+ for (i=0; i<pl->l; i++) {
+ err |= cmd_process(&ctx, pl->p[i], pf);
+ }
+
+ if (pl->l > 1 && ctx)
+ err |= cmd_process(&ctx, '\n', pf);
+
+ return err;
+}
+
+
+/**
+ * Send output to all modules registered in the UI subsystem
+ *
+ * @param str Output string
+ */
+void ui_output(const char *str)
+{
+ struct le *le;
+
+ for (le = uil.head; le; le = le->next) {
+ const struct ui *ui = le->data;
+
+ if (ui->outputh)
+ ui->outputh(ui->st, str);
+ }
+}
+
+
+void ui_init(const struct config_input *cfg)
+{
+ if (!cfg)
+ return;
+
+ input_cfg = *cfg;
+}