summaryrefslogtreecommitdiff
path: root/src/fruits
diff options
context:
space:
mode:
Diffstat (limited to 'src/fruits')
-rw-r--r--src/fruits/cmc/cmc.c39
-rw-r--r--src/fruits/cmc/meson.build2
-rw-r--r--src/fruits/cmc/ui/ui.c29
-rw-r--r--src/fruits/cmc/ui/ui.h18
-rw-r--r--src/fruits/cmsrv/cmsrv.c4
-rw-r--r--src/fruits/cmv/cmv.c6
-rw-r--r--src/fruits/cmv/input_simulator.c53
-rw-r--r--src/fruits/cmv/input_simulator.h6
-rw-r--r--src/fruits/cmv/meson.build2
9 files changed, 153 insertions, 6 deletions
diff --git a/src/fruits/cmc/cmc.c b/src/fruits/cmc/cmc.c
index d39d639..724a489 100644
--- a/src/fruits/cmc/cmc.c
+++ b/src/fruits/cmc/cmc.c
@@ -8,8 +8,11 @@
#include "cmc.h"
+#include "ui/ui.h"
+
enum {
- CLI_ADD = 0
+ CLI_OPEN_UI = 0,
+ CLI_ADD
};
struct cmc {
@@ -19,6 +22,8 @@ struct cmc {
struct camu_client client;
struct camu_post_cache cache;
array(struct cmc_search *) searches;
+ struct cmc_ui ui;
+ struct aki_poll input_poll;
};
static struct cmc_search *get_search_by_id(struct cmc *c, s32 id)
@@ -30,12 +35,37 @@ static struct cmc_search *get_search_by_id(struct cmc *c, s32 id)
return NULL;
}
+static void input_poll_callback(void *userdata, s32 revents)
+{
+ struct cmc *c = (struct cmc *)userdata;
+ (void)revents;
+ struct ncinput input;
+ do {
+ if (!cmc_ui_read_input(&c->ui, &input)) break;
+ if (input.evtype == NCTYPE_PRESS || input.evtype == NCTYPE_UNKNOWN) {
+ switch (input.id) {
+ case 'q':
+ aki_event_loop_break_one(&c->loop);
+ break;
+ }
+ }
+ } while (1);
+}
+
static void client_callback(void *userdata, u8 op, void *opaque)
{
struct cmc *c = (struct cmc *)userdata;
switch (op) {
case CAMU_CLIENT_LOGIN: {
switch (c->command) {
+ case CLI_OPEN_UI:
+ if (!cmc_ui_init(&c->ui)) {
+ aki_event_loop_break_one(&c->loop);
+ }
+ aki_poll_init(&c->input_poll, input_poll_callback, c);
+ aki_poll_set(&c->input_poll, cmc_ui_get_input_fd(&c->ui), AKI_POLL_READ);
+ aki_poll_start(&c->input_poll, &c->loop);
+ break;
case CLI_ADD: {
str *arg;
al_array_foreach_ptr(c->args, i, arg) {
@@ -91,7 +121,10 @@ static bool parse_cmd(s32 argc, char *argv[])
static bool parse_cmd(s32 argc, wchar_t **argv)
#endif
{
- if (argc < 2) return false;
+ if (argc < 2) {
+ c.command = CLI_OPEN_UI;
+ return true;
+ }
if (al_str_eq(al_str_cr(argv[1]), al_str_c("add"))) {
if (argc < 3) return false;
c.command = CLI_ADD;
@@ -133,5 +166,7 @@ s32 wmain(s32 argc, wchar_t **argv)
aki_event_loop_run(&c.loop);
+ cmc_ui_close(&c.ui);
+
return EXIT_SUCCESS;
}
diff --git a/src/fruits/cmc/meson.build b/src/fruits/cmc/meson.build
index 4737c61..627391e 100644
--- a/src/fruits/cmc/meson.build
+++ b/src/fruits/cmc/meson.build
@@ -8,7 +8,7 @@ endif
use_tui = true
if use_tui
- #cmc_src += ['ui.c']
+ cmc_src += ['ui/ui.c']
cmc_deps += [dependency('notcurses')]
endif
diff --git a/src/fruits/cmc/ui/ui.c b/src/fruits/cmc/ui/ui.c
new file mode 100644
index 0000000..a838f96
--- /dev/null
+++ b/src/fruits/cmc/ui/ui.c
@@ -0,0 +1,29 @@
+#include <al/lib.h>
+
+#include "ui.h"
+
+bool cmc_ui_init(struct cmc_ui *ui)
+{
+ al_memset(ui, 0, sizeof(struct cmc_ui));
+ if (!(ui->nc = notcurses_init(NULL, stdin))) {
+ return false;
+ }
+ return true;
+}
+
+s32 cmc_ui_get_input_fd(struct cmc_ui *ui)
+{
+ return notcurses_inputready_fd(ui->nc);
+}
+
+bool cmc_ui_read_input(struct cmc_ui *ui, struct ncinput *input)
+{
+ al_memset(input, 0, sizeof(struct ncinput));
+ u32 ret = notcurses_get_nblock(ui->nc, input);
+ return !(ret == (u32)-1 || ret == 0);
+}
+
+void cmc_ui_close(struct cmc_ui *ui)
+{
+ notcurses_stop(ui->nc);
+}
diff --git a/src/fruits/cmc/ui/ui.h b/src/fruits/cmc/ui/ui.h
new file mode 100644
index 0000000..4af222e
--- /dev/null
+++ b/src/fruits/cmc/ui/ui.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <al/types.h>
+#include <notcurses/notcurses.h>
+
+struct cmc_ui {
+ struct notcurses *nc;
+ u32 term_cols;
+ u32 term_rows;
+ bool pending_layout;
+};
+
+bool cmc_ui_init(struct cmc_ui *ui);
+
+s32 cmc_ui_get_input_fd(struct cmc_ui *ui);
+bool cmc_ui_read_input(struct cmc_ui *ui, struct ncinput *input);
+
+void cmc_ui_close(struct cmc_ui *ui);
diff --git a/src/fruits/cmsrv/cmsrv.c b/src/fruits/cmsrv/cmsrv.c
index 511484d..47f90af 100644
--- a/src/fruits/cmsrv/cmsrv.c
+++ b/src/fruits/cmsrv/cmsrv.c
@@ -133,8 +133,8 @@ s32 wmain(s32 argc, wchar_t **argv)
aki_event_loop_init(&s.loop);
- aki_signal_init(&s.quit_signal, quit_signal_callback, &s);
- aki_signal_start(&s.quit_signal, &s.loop);
+ aki_signal_init(&s.quit_signal, &s.loop, quit_signal_callback, &s);
+ aki_signal_start(&s.quit_signal);
if (!camu_server_init(&s.server, CAMU_LOCAL_TYPE, &s.loop)) return EXIT_FAILURE;
camu_server_listen(&s.server, CAMU_LOCAL_ADDR, CAMU_PORT);
diff --git a/src/fruits/cmv/cmv.c b/src/fruits/cmv/cmv.c
index 0fe33ad..9e3be3f 100644
--- a/src/fruits/cmv/cmv.c
+++ b/src/fruits/cmv/cmv.c
@@ -11,6 +11,8 @@
#include "../../server/common.c"
#endif
+#include "input_simulator.h"
+
struct cmv {
struct aki_event_loop loop;
struct camu_desktop desktop;
@@ -121,8 +123,12 @@ s32 wmain(s32 argc, wchar_t **argv)
struct aki_thread thread0;
aki_thread_create(&thread0, event_loop_thread, &c);
+ //cmv_input_simulator_run(&c.desktop.sink);
+
while (camu_desktop_tick(&c.desktop)) {}
+ //cmv_input_simulator_stop();
+
camu_desktop_stop(&c.desktop);
aki_thread_join(&thread0);
camu_desktop_free(&c.desktop);
diff --git a/src/fruits/cmv/input_simulator.c b/src/fruits/cmv/input_simulator.c
new file mode 100644
index 0000000..7bc3125
--- /dev/null
+++ b/src/fruits/cmv/input_simulator.c
@@ -0,0 +1,53 @@
+#include <aki/thread.h>
+#include <al/random.h>
+
+#include "input_simulator.h"
+
+static struct aki_thread thread;
+static s32 quit = 0;
+
+enum {
+ SKIP = 0,
+ BACKSKIP,
+ SHUFFLE,
+ BASE, // count
+ TOGGLE_PAUSE,
+ SEEK,
+};
+
+static aki_thread_result AKI_THREADCALL input_simulation_thread(void *userdata)
+{
+ struct camu_sink *sink = (struct camu_sink *)userdata;
+ while (!quit) {
+ aki_thread_sleep(AKI_TS_FROM_USEC(30000));
+ switch (al_rand() % BASE) {
+ case SKIP:
+ camu_sink_skip(sink, (al_rand() % 5));
+ break;
+ case BACKSKIP:
+ camu_sink_skip(sink, -(al_rand() % 5));
+ break;
+ case SHUFFLE:
+ camu_sink_shuffle(sink);
+ break;
+ case TOGGLE_PAUSE:
+ camu_sink_toggle_pause(sink);
+ break;
+ case SEEK:
+ camu_sink_seek(sink, 0.0);
+ break;
+ }
+ }
+ return 0;
+}
+
+void cmv_input_simulator_run(struct camu_sink *sink)
+{
+ aki_thread_create(&thread, input_simulation_thread, sink);
+}
+
+void cmv_input_simulator_stop(void)
+{
+ quit = 1;
+ aki_thread_join(&thread);
+}
diff --git a/src/fruits/cmv/input_simulator.h b/src/fruits/cmv/input_simulator.h
new file mode 100644
index 0000000..5380bb2
--- /dev/null
+++ b/src/fruits/cmv/input_simulator.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "../../libsink/sink.h"
+
+void cmv_input_simulator_run(struct camu_sink *sink);
+void cmv_input_simulator_stop(void);
diff --git a/src/fruits/cmv/meson.build b/src/fruits/cmv/meson.build
index 9b83847..b2ab0a2 100644
--- a/src/fruits/cmv/meson.build
+++ b/src/fruits/cmv/meson.build
@@ -1,4 +1,4 @@
-cmv_src = ['cmv.c']
+cmv_src = ['cmv.c', 'input_simulator.c']
cmv_deps = [common_deps, desktop]
cmv_args = []
if get_option('sink-only')