summaryrefslogtreecommitdiff
path: root/src/fruits
diff options
context:
space:
mode:
Diffstat (limited to 'src/fruits')
-rw-r--r--src/fruits/cmc/cmc.c10
-rw-r--r--src/fruits/cmsrv/cmsrv.c88
-rw-r--r--src/fruits/cmsrv/ui.c27
-rw-r--r--src/fruits/cmv/cmv.c34
-rw-r--r--src/fruits/common.h8
5 files changed, 118 insertions, 49 deletions
diff --git a/src/fruits/cmc/cmc.c b/src/fruits/cmc/cmc.c
index d95a2f6..3d91ba6 100644
--- a/src/fruits/cmc/cmc.c
+++ b/src/fruits/cmc/cmc.c
@@ -147,13 +147,13 @@ static void client_callback(void *userdata, u8 op, void *opaque)
}
case CAMU_CLIENT_GOT_META: {
struct nn_packet *packet = (struct nn_packet *)opaque;
- u8 op = nn_packet_read_u8(packet);
+ u8 meta_op = nn_packet_read_u8(packet);
str name;
nn_packet_read_str(packet, &name);
struct cmc_list *list = get_list_by_name(c, &name);
list->meta_changed = true;
if (!list) break;
- switch (op) {
+ switch (meta_op) {
case LIANA_META_ADDED_ENTRY: {
u32 id = nn_packet_read_u32(packet);
struct cmc_list_entry *entry = al_alloc_object(struct cmc_list_entry);
@@ -174,7 +174,7 @@ static void client_callback(void *userdata, u8 op, void *opaque)
cmc_ui_queue_render(&c->ui);
break;
}
- case LIANA_META_ORDER_CHANGED: {
+ case LIANA_META_ORDER_PROBABLY_CHANGED: {
struct cmc_list_entry *entry;
u32 count = nn_packet_read_u32(packet);
for (u32 i = 0; i < count; i++) {
@@ -266,7 +266,9 @@ static bool parse_command_line(s32 argc, char *argv[])
s32 main(s32 argc, char *argv[])
{
- if (!nn_common_init("cmc_main")) return EXIT_FAILURE;
+ if (!nn_common_init("cmc_main")) {
+ return EXIT_FAILURE;
+ }
al_array_init(c.cli.args);
if (!parse_command_line(argc, argv)) {
diff --git a/src/fruits/cmsrv/cmsrv.c b/src/fruits/cmsrv/cmsrv.c
index 8e24701..ef66be8 100644
--- a/src/fruits/cmsrv/cmsrv.c
+++ b/src/fruits/cmsrv/cmsrv.c
@@ -36,6 +36,19 @@ struct cmsrv {
#endif
};
+static void close_cmsrv(struct cmsrv *s)
+{
+#ifdef CMSRV_LOCAL_SOCKET
+ nn_line_processor_stop(&s->local.cli);
+#endif
+#ifdef CMSRV_USE_UI
+ nn_poll_stop(&s->input_poll);
+ nn_timer_stop(&s->render_timer);
+#endif
+ camu_server_close(&s->server);
+ nn_signal_stop(&s->quit_signal);
+}
+
#ifdef CMSRV_LOCAL_SOCKET
static u8 server_line_callback(void *userdata, str *line)
{
@@ -43,10 +56,34 @@ static u8 server_line_callback(void *userdata, str *line)
struct lia_list *list = al_array_at(s->server.lists, 0);
if (al_str_eq(line, &al_str_c(";PAUSE"))) {
lia_list_toggle_pause(list, LIANA_SEQUENCE_ANY, -1.0);
- } else if (al_str_eq(line, &al_str_c(";NEXT"))) {
- lia_list_skip(list, LIANA_SEQUENCE_ANY, 1);
- } else if (al_str_eq(line, &al_str_c(";PREV"))) {
- lia_list_skip(list, LIANA_SEQUENCE_ANY, -1);
+ } else if (al_str_cmp(line, &al_str_c(";NEXT"), 0, 5) == 0) {
+ s32 n = 1;
+ if (line->length > 6) {
+ str arg = al_str_substr(line, 6, line->length);
+ bool error;
+ s64 i = al_str_to_long(&arg, 10, &error);
+ if (!error) n = CLAMP(i, (s64)INT32_MIN, (s64)INT32_MAX);
+ }
+ lia_list_skip(list, LIANA_SEQUENCE_ANY, n);
+ } else if (al_str_cmp(line, &al_str_c(";PREV"), 0, 5) == 0) {
+ s32 n = -1;
+ if (line->length > 6) {
+ str arg = al_str_substr(line, 6, line->length);
+ bool error;
+ s64 i = -al_str_to_long(&arg, 10, &error);
+ if (!error) n = CLAMP(i, (s64)INT32_MIN, (s64)INT32_MAX);
+ }
+ lia_list_skip(list, LIANA_SEQUENCE_ANY, n);
+ } else if (al_str_cmp(line, &al_str_c(";SEEK"), 0, 5) == 0) {
+ if (line->length > 6) {
+ str arg = al_str_substr(line, 6, line->length);
+ bool error;
+ s64 i = al_str_to_long(&arg, 10, &error);
+ if (!error) {
+ i *= 1000000;
+ lia_list_seek(list, LIANA_SEQUENCE_ANY, 0, CLAMP(i, (s64)0, (s64)INT64_MAX));
+ }
+ }
} else if (al_str_eq(line, &al_str_c(";SHUFFLE"))) {
lia_list_shuffle(list);
} else if (al_str_eq(line, &al_str_c(";SORT"))) {
@@ -54,22 +91,24 @@ static u8 server_line_callback(void *userdata, str *line)
} else if (al_str_eq(line, &al_str_c(";REVERSE"))) {
lia_list_reverse(list);
} else if (al_str_eq(line, &al_str_c(";CLEAR"))) {
- //lia_list_clear(list);
+ lia_list_clear(list);
} else {
struct nn_packet *packet = nn_packet_create();
nn_packet_write_str(packet, line);
camu_server_local_add(&s->server, packet);
+ nn_packet_free(packet);
}
return NNWT_LINE_PROCESSOR_CONTINUE;
}
#endif
#ifdef CMSRV_USE_UI
-static void render_timer_callback(void *userdata, struct nn_timer *timer)
+static s32 log_callback(void *userdata, u8 level, char *message)
{
struct cmsrv *s = (struct cmsrv *)userdata;
- (void)timer;
- cmsrv_ui_render(&s->ui);
+ (void)level;
+ cmsrv_ui_push_message(&s->ui, al_strndup(message, AL_LOG_MESSAGE_SIZE));
+ return al_strnlen(message, AL_LOG_MESSAGE_SIZE);
}
static void input_poll_callback(void *userdata, s32 revents)
@@ -82,7 +121,7 @@ static void input_poll_callback(void *userdata, s32 revents)
if (input.evtype == NCTYPE_PRESS || input.evtype == NCTYPE_UNKNOWN) {
switch (input.id) {
case 'q':
- nn_event_loop_break_one(&s->loop);
+ close_cmsrv(s);
break;
case '1':
cmsrv_ui_set_pane(&s->ui, CMSRV_UI_LISTS);
@@ -98,19 +137,18 @@ static void input_poll_callback(void *userdata, s32 revents)
}
}
-static s32 log_callback(void *userdata, u8 level, char *message)
+static void render_timer_callback(void *userdata, struct nn_timer *timer)
{
struct cmsrv *s = (struct cmsrv *)userdata;
- (void)level;
- cmsrv_ui_push_message(&s->ui, al_strndup(message, AL_LOG_MESSAGE_SIZE));
- return al_strnlen(message, AL_LOG_MESSAGE_SIZE);
+ (void)timer;
+ cmsrv_ui_render(&s->ui);
}
#endif
static void quit_signal_callback(void *userdata)
{
struct cmsrv *s = (struct cmsrv *)userdata;
- nn_event_loop_break_one(&s->loop);
+ close_cmsrv(s);
}
static struct cmsrv s = { 0 };
@@ -127,16 +165,17 @@ s32 wmain(s32 argc, wchar_t **argv)
s32 main(s32 argc, char *argv[])
#endif
{
- (void)argc;
- (void)argv;
- if (!nn_common_init("cmsrv_main")) return EXIT_FAILURE;
+ if (!nn_common_init("cmsrv_main")) {
+ return EXIT_FAILURE;
+ }
+
#ifdef CMSRV_USE_UI
- if (!cmsrv_ui_init(&s.ui, &s.server)) return EXIT_FAILURE;
+ if (!cmsrv_ui_init(&s.ui, &s.server)) {
+ return EXIT_FAILURE;
+ }
al_set_print(log_callback, &s);
#endif
- signal(SIGINT, sigint_handler);
-
#ifdef CAMU_HAVE_FFMPEG
camu_ff_common_init();
#endif
@@ -145,6 +184,7 @@ s32 main(s32 argc, char *argv[])
nn_signal_init(&s.quit_signal, &s.loop, quit_signal_callback, &s);
nn_signal_start(&s.quit_signal);
+ signal(SIGINT, sigint_handler);
camu_server_init(&s.server, &s.loop);
if (!camu_server_listen(&s.server, CAMU_TEST_TYPE, &CAMU_TEST_ADDR, CAMU_PORT)) {
@@ -174,11 +214,19 @@ s32 main(s32 argc, char *argv[])
nn_event_loop_run(&s.loop);
+#ifdef CMSRV_LOCAL_SOCKET
+ nn_socket_close(&s.local.sock);
+#endif
#ifdef CMSRV_USE_UI
cmsrv_ui_close(&s.ui);
#endif
+ camu_server_free(&s.server);
+ nn_event_loop_destroy(&s.loop);
nn_common_close();
+ (void)argc;
+ (void)argv;
+
return EXIT_SUCCESS;
}
diff --git a/src/fruits/cmsrv/ui.c b/src/fruits/cmsrv/ui.c
index e8fbc41..d96c09d 100644
--- a/src/fruits/cmsrv/ui.c
+++ b/src/fruits/cmsrv/ui.c
@@ -81,18 +81,22 @@ static void render_log(struct cmsrv_ui *ui)
u32 max_height = ncplane_dim_y(n) - 2;
u32 size = ui->log.messages.count;
- u32 index = (size > max_height) ? size - max_height : 0;
- for (u32 i = index; i < size; i++) {
+ if (size > max_height) {
+ u32 index = size - max_height;
+ for (u32 i = 0; i < index; i++) {
+ al_free(al_array_at(ui->log.messages, i));
+ }
+ al_array_remove_range(ui->log.messages, 0, index);
+ }
+ size = ui->log.messages.count;
+ al_assert(size <= max_height);
+ for (u32 i = 0; i < size; i++) {
u32 x = 1;
- u32 y = (i - index) + 1;
- // We can't use putnstr here to control the width because lots of
- // these messages will have wide characters.
+ u32 y = i + 1;
+ // We can't use putnstr here to control the width because lots of these
+ // messages will have wide characters.
ncplane_putstr_yx(n, y, x, al_array_at(ui->log.messages, i));
}
- for (u32 i = 0; i < index; i++) {
- al_free(al_array_at(ui->log.messages, i));
- }
- al_array_remove_range(ui->log.messages, 0, index);
u64 c = 0;
ncchannels_set_fg_default(&c);
@@ -242,4 +246,9 @@ void cmsrv_ui_render(struct cmsrv_ui *ui)
void cmsrv_ui_close(struct cmsrv_ui *ui)
{
notcurses_stop(ui->nc);
+ char *message;
+ al_array_foreach(ui->log.messages, i, message) {
+ al_free(message);
+ }
+ al_array_free(ui->log.messages);
}
diff --git a/src/fruits/cmv/cmv.c b/src/fruits/cmv/cmv.c
index 1fce028..fe0fbd6 100644
--- a/src/fruits/cmv/cmv.c
+++ b/src/fruits/cmv/cmv.c
@@ -16,7 +16,9 @@
#include "../common.h"
#if !defined CAMU_SINK_ONLY && !defined NAUNET_ON_WINDOWS
-static str CMV_UNIX_PATH = al_str_c("/tmp/cmv_sock");
+// https://unix.stackexchange.com/a/16884
+#define PID_MAX_STR 7 // 0x400000 (2^22).
+static str CMV_UNIX_PATH = al_str_c("/tmp/cmv_sock_");
#endif
struct cmv {
@@ -66,7 +68,7 @@ static bool parse_exe_name_params(str *exe_name, str *addr, struct lia_prefs *pr
index = al_str_find(&sub, '-');
if (index == AL_STR_NO_POS) goto def;
- *addr = al_str_substr(&sub, 0, index);
+ al_str_clone(addr, &al_str_substr(&sub, 0, index));
for (;;) {
sub = al_str_substr(&sub, index + 1, sub.length);
@@ -118,12 +120,10 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
camu_ff_common_init();
#endif
- str home = al_str_null();
char *home_env = getenv("HOME");
if (home_env) {
- al_str_from(&home, home_env);
str color_palette;
- al_str_clone(&color_palette, &home);
+ al_str_from(&color_palette, home_env);
al_str_cat(&color_palette, &al_str_c("/.config/colors.json"));
camu_color_palette_init(&color_palette);
al_str_free(&color_palette);
@@ -145,16 +145,22 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
#ifndef CAMU_SINK_ONLY
if (local) {
#ifdef NAUNET_ON_WINDOWS
- type = NNWT_SOCKET_TCP; addr = CAMU_LOCALHOST;
+ type = NNWT_SOCKET_TCP;;
+ al_str_clone(&addr, &CAMU_LOCALHOST);
#else
- type = NNWT_SOCKET_UNIX; addr = CMV_UNIX_PATH;
+ type = NNWT_SOCKET_UNIX;
+ al_str_clone(&addr, &CMV_UNIX_PATH);
+ char pid_str[PID_MAX_STR];
+ al_snprintf(pid_str, PID_MAX_STR, "%x", getpid());
+ al_str_cat(&addr, &al_str_cs(pid_str));
#endif
} else {
type = CAMU_TEST_TYPE;
- addr = CAMU_TEST_ADDR;
+ al_str_clone(&addr, &CAMU_TEST_ADDR);
}
#else
- type = NNWT_SOCKET_TCP; addr = CAMU_TEST_ADDR;
+ type = NNWT_SOCKET_TCP;
+ al_str_clone(&addr, &CAMU_TEST_ADDR);
#endif
} else {
type = NNWT_SOCKET_TCP;
@@ -189,6 +195,8 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
return EXIT_FAILURE;
}
+ al_str_free(&addr);
+
#ifndef CAMU_SINK_ONLY
if (local) {
for (u32 i = 1; i < argc; i++) {
@@ -214,7 +222,6 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
camu_server_free(&c.server);
#endif
nn_event_loop_destroy(&c.loop);
- al_str_free(&home);
return EXIT_SUCCESS;
}
@@ -238,7 +245,10 @@ s32 wmain(s32 argc, wchar_t **argv)
s32 main(s32 argc, char *argv[])
#endif
{
- if (!nn_common_init("cmv_main")) return EXIT_FAILURE;
+ if (!nn_common_init("cmv_main")) {
+ return EXIT_FAILURE;
+ }
+
if (!stl_global_init(false)) {
nn_common_close();
return EXIT_FAILURE;
@@ -252,7 +262,7 @@ s32 main(s32 argc, char *argv[])
for (s32 i = 0; i < argc; i++) {
str arg;
#ifdef NAUNET_ON_WINDOWS
- if (!al_str_from_wstr(&arg, &al_wstr_cr(argv[i]))) {
+ if (!al_str_from_wstr(&arg, &al_wstr_cr(argv[i]))) { // This is so broken.
log_error("Failed to convert argument #%i from a wide string.", i);
continue;
}
diff --git a/src/fruits/common.h b/src/fruits/common.h
index 1f7870d..66a72bc 100644
--- a/src/fruits/common.h
+++ b/src/fruits/common.h
@@ -17,8 +17,8 @@ AL_IGNORE_WARNING_END
#define CAMU_TEST_TYPE NNWT_SOCKET_TCP
#define CAMU_TEST_ADDR CAMU_TEST_IP
#else
-#define CAMU_TEST_TYPE NNWT_SOCKET_UNIX
-#define CAMU_TEST_ADDR CAMU_TEST_PATH
-//#define CAMU_TEST_TYPE NNWT_SOCKET_TCP
-//#define CAMU_TEST_ADDR CAMU_TEST_IP
+//#define CAMU_TEST_TYPE NNWT_SOCKET_UNIX
+//#define CAMU_TEST_ADDR CAMU_TEST_PATH
+#define CAMU_TEST_TYPE NNWT_SOCKET_TCP
+#define CAMU_TEST_ADDR CAMU_TEST_IP
#endif