diff options
author | Alfred E. Heggestad <aeh@db.org> | 2014-02-09 11:50:07 +0100 |
---|---|---|
committer | Alfred E. Heggestad <aeh@db.org> | 2014-02-09 11:50:07 +0100 |
commit | 98bf08bdcf2edd9d397f32650a8bfe62186fbecf (patch) | |
tree | ebc6ec71f44bff8c42e4eefced61948623df02fc /modules/wincons | |
parent | e6ad5cf4401b860ba402d4b7b3c7c254bc87a019 (diff) |
baresip 0.4.10
Diffstat (limited to 'modules/wincons')
-rw-r--r-- | modules/wincons/module.mk | 11 | ||||
-rw-r--r-- | modules/wincons/wincons.c | 183 |
2 files changed, 194 insertions, 0 deletions
diff --git a/modules/wincons/module.mk b/modules/wincons/module.mk new file mode 100644 index 0000000..aa1746e --- /dev/null +++ b/modules/wincons/module.mk @@ -0,0 +1,11 @@ +# +# module.mk +# +# Copyright (C) 2010 Creytiv.com +# + +MOD := wincons +$(MOD)_SRCS += wincons.c +$(MOD)_LFLAGS += + +include mk/mod.mk diff --git a/modules/wincons/wincons.c b/modules/wincons/wincons.c new file mode 100644 index 0000000..6724fc7 --- /dev/null +++ b/modules/wincons/wincons.c @@ -0,0 +1,183 @@ +/** + * @file wincons.c Windows console input + * + * Copyright (C) 2010 Creytiv.com + */ + +#include <winsock2.h> +#include <re.h> +#include <baresip.h> + + +/** Local constants */ +enum { + RELEASE_VAL = 250 /**< Key release value in [ms] */ +}; + +struct ui_st { + struct ui *ui; /* base class */ + struct tmr tmr; + struct mqueue *mq; + HANDLE hThread; + bool run; + ui_input_h *h; + void *arg; +}; + + +static struct ui *wincons; + + +static void destructor(void *arg) +{ + struct ui_st *st = arg; + + st->run = false; + CloseHandle(st->hThread); + + tmr_cancel(&st->tmr); + mem_deref(st->mq); + mem_deref(st->ui); +} + + +static int print_handler(const char *p, size_t size, void *arg) +{ + (void)arg; + + return 1 == fwrite(p, size, 1, stderr) ? 0 : ENOMEM; +} + + +static void report_key(struct ui_st *ui, char key) +{ + struct re_printf pf; + + pf.vph = print_handler; + + if (ui->h) + ui->h(key, &pf, ui->arg); +} + + +static void timeout(void *arg) +{ + struct ui_st *st = arg; + + /* Emulate key-release */ + report_key(st, 0x00); +} + + +static DWORD WINAPI input_thread(LPVOID arg) +{ + struct ui_st *st = arg; + + HANDLE hstdin = GetStdHandle( STD_INPUT_HANDLE ); + DWORD mode; + + /* Switch to raw mode */ + GetConsoleMode(hstdin, &mode); + SetConsoleMode(hstdin, 0); + + while (st->run) { + + char buf[4]; + DWORD i, count = 0; + + ReadConsole(hstdin, buf, sizeof(buf), &count, NULL); + + for (i=0; i<count; i++) { + int ch = buf[i]; + + if (ch == '\r') + ch = '\n'; + + /* + * The keys are read from a thread so we have + * to send them to the RE main event loop via + * a message queue + */ + mqueue_push(st->mq, ch, 0); + } + } + + /* Restore the console to its previous state */ + SetConsoleMode(hstdin, mode); + + return 0; +} + + +static void mqueue_handler(int id, void *data, void *arg) +{ + struct ui_st *st = arg; + (void)data; + + tmr_start(&st->tmr, RELEASE_VAL, timeout, st); + report_key(st, id); +} + + +static int ui_alloc(struct ui_st **stp, struct ui_prm *prm, + ui_input_h *ih, void *arg) +{ + struct ui_st *st; + DWORD threadID; + int err = 0; + (void)prm; + + if (!stp) + return EINVAL; + + st = mem_zalloc(sizeof(*st), destructor); + if (!st) + return ENOMEM; + + st->ui = mem_ref(wincons); + st->h = ih; + st->arg = arg; + + tmr_init(&st->tmr); + + err = mqueue_alloc(&st->mq, mqueue_handler, st); + if (err) + goto out; + + st->run = true; + st->hThread = CreateThread(NULL, 0, input_thread, st, 0, &threadID); + if (!st->hThread) { + st->run = false; + err = ENOMEM; + goto out; + } + + out: + if (err) + mem_deref(st); + else + *stp = st; + + return err; +} + + +static int module_init(void) +{ + return ui_register(&wincons, "wincons", ui_alloc, NULL); +} + + +static int module_close(void) +{ + wincons = mem_deref(wincons); + return 0; +} + + +const struct mod_export DECL_EXPORTS(wincons) = { + "wincons", + "ui", + module_init, + module_close +}; |