ddat interop with dat js cable interop with cabal js ddat's frontend = dat-thang cable fe = cable-thang dillo support based on cel's dillo-dat bootstrap node xplatform support Signed-off-by: divo <418@cryspace.space>
105 lines
4.0 KiB
C
105 lines
4.0 KiB
C
#define _POSIX_C_SOURCE 200809L
|
|
#define main cable_thang_embedded_main
|
|
#include "../src/ddat_gui.c"
|
|
#undef main
|
|
|
|
#include <assert.h>
|
|
#include <sys/select.h>
|
|
#include <time.h>
|
|
|
|
static void announce_new_messages(gui_state_t *state, size_t *seen)
|
|
{
|
|
uint8_t self[32];
|
|
size_t i;
|
|
if (cable_hex_key(state->cable_feed_key, self)) return;
|
|
for (i = *seen; i < state->cable_line_count; i++) {
|
|
const cable_room_event_t *event = &state->cable_lines[i].event;
|
|
if (event->type == CABLE_ROOM_TEXT && memcmp(event->sender, self, sizeof(self)) != 0) {
|
|
printf("RX\t%s\t%s\n", event->nick, event->text);
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
*seen = state->cable_line_count;
|
|
}
|
|
|
|
static void read_command(gui_state_t *state, char *line, int *running)
|
|
{
|
|
size_t length = strlen(line);
|
|
while (length && (line[length - 1] == '\n' || line[length - 1] == '\r')) line[--length] = '\0';
|
|
if (!strcmp(line, "QUIT")) { *running = 0; return; }
|
|
if (!strncmp(line, "SEND ", 5)) {
|
|
if (strlen(line + 5) > CABLE_CHAT_TEXT_BYTES) { puts("ERR message-too-long"); fflush(stdout); return; }
|
|
strcpy(state->cable_input, line + 5);
|
|
if (cable_room_submit(state)) { puts("ERR send-failed"); fflush(stdout); }
|
|
else { puts("SENT"); fflush(stdout); }
|
|
return;
|
|
}
|
|
if (!strncmp(line, "NICK ", 5)) {
|
|
if (strlen(line + 5) > CABLE_ROOM_NICK_BYTES) { puts("ERR nick-too-long"); fflush(stdout); return; }
|
|
snprintf(state->cable_input, sizeof(state->cable_input), "/nick %s", line + 5);
|
|
if (cable_room_submit(state)) { puts("ERR nick-failed"); fflush(stdout); }
|
|
else { puts("NICKED"); fflush(stdout); }
|
|
return;
|
|
}
|
|
if (!strncmp(line, "JOIN ", 5)) {
|
|
if (strlen(line + 5) > CABLE_ROOM_CHANNEL_BYTES) { puts("ERR channel-too-long"); fflush(stdout); return; }
|
|
snprintf(state->cable_input, sizeof(state->cable_input), "/join %s", line + 5);
|
|
if (cable_room_submit(state)) { puts("ERR join-failed"); fflush(stdout); }
|
|
else { puts("JOINED"); fflush(stdout); }
|
|
return;
|
|
}
|
|
puts("ERR unknown-command");
|
|
fflush(stdout);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
static gui_state_t state;
|
|
SDL_Window *window;
|
|
SDL_Renderer *renderer;
|
|
char input[2048];
|
|
size_t seen_lines = 0;
|
|
int running = 1, ready_reported = 0, peer_reported = 0;
|
|
if (argc != 2) { fputs("usage: test_cable_thang <cabal-room-address>\n", stderr); return 2; }
|
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { fprintf(stderr, "SDL init: %s\n", SDL_GetError()); return 1; }
|
|
window = SDL_CreateWindow("cable-thang live test", SDL_WINDOWPOS_UNDEFINED,
|
|
SDL_WINDOWPOS_UNDEFINED, 1000, 640,
|
|
SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE);
|
|
if (!window) { fprintf(stderr, "SDL window: %s\n", SDL_GetError()); SDL_Quit(); return 1; }
|
|
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
|
|
if (!renderer) {
|
|
fprintf(stderr, "SDL renderer: %s\n", SDL_GetError());
|
|
SDL_DestroyWindow(window); SDL_Quit(); return 1;
|
|
}
|
|
state.cable_thang_mode = 1;
|
|
if (cable_thang_room_init(&state, argv[1]) || cable_thang_network_start(&state)) {
|
|
perror("Cable SDL room startup"); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 1;
|
|
}
|
|
while (running) {
|
|
fd_set reads;
|
|
struct timeval tick = {0, 10000};
|
|
int result;
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event)) if (event.type == SDL_QUIT) running = 0;
|
|
network_pump(&state, SDL_GetTicks());
|
|
if (!ready_reported && state.cable_feed_key[0]) {
|
|
printf("C_READY %s\n", state.cable_feed_key); fflush(stdout); ready_reported = 1;
|
|
}
|
|
if (!peer_reported && state.connected_peers) { puts("PEER_UP"); fflush(stdout); peer_reported = 1; }
|
|
announce_new_messages(&state, &seen_lines);
|
|
cable_thang_draw(renderer, 1000, 640, &state);
|
|
SDL_RenderPresent(renderer);
|
|
FD_ZERO(&reads); FD_SET(STDIN_FILENO, &reads);
|
|
result = select(STDIN_FILENO + 1, &reads, NULL, NULL, &tick);
|
|
if (result > 0 && FD_ISSET(STDIN_FILENO, &reads)) {
|
|
if (!fgets(input, sizeof(input), stdin)) running = 0;
|
|
else read_command(&state, input, &running);
|
|
} else if (result < 0 && errno != EINTR) running = 0;
|
|
}
|
|
network_stop(&state);
|
|
SDL_DestroyRenderer(renderer);
|
|
SDL_DestroyWindow(window);
|
|
SDL_Quit();
|
|
return 0;
|
|
}
|