Streamline
This commit is contained in:
parent
5026b22172
commit
93b305e35b
191
autistdraw.c
191
autistdraw.c
|
@ -46,7 +46,6 @@ enum
|
||||||
MESSAGE_COUNT ///< Total number of messages
|
MESSAGE_COUNT ///< Total number of messages
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum network_mode network_mode_t;
|
|
||||||
enum network_mode
|
enum network_mode
|
||||||
{
|
{
|
||||||
NETWORK_MODE_STANDALONE, ///< No networking taking place
|
NETWORK_MODE_STANDALONE, ///< No networking taking place
|
||||||
|
@ -54,10 +53,9 @@ enum network_mode
|
||||||
NETWORK_MODE_CLIENT ///< We're a client
|
NETWORK_MODE_CLIENT ///< We're a client
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct client client_t;
|
|
||||||
struct client
|
struct client
|
||||||
{
|
{
|
||||||
LIST_HEADER (client_t)
|
LIST_HEADER (struct client)
|
||||||
|
|
||||||
int fd; ///< Client connection
|
int fd; ///< Client connection
|
||||||
ev_io read_watcher; ///< Client readability watcher
|
ev_io read_watcher; ///< Client readability watcher
|
||||||
|
@ -68,7 +66,6 @@ struct client
|
||||||
|
|
||||||
#define BITMAP_PIXEL(app, x, y) (app)->bitmap[(y) * (app)->bitmap_w + (x)]
|
#define BITMAP_PIXEL(app, x, y) (app)->bitmap[(y) * (app)->bitmap_w + (x)]
|
||||||
|
|
||||||
typedef struct app_context app_context_t;
|
|
||||||
struct app_context
|
struct app_context
|
||||||
{
|
{
|
||||||
termo_t *tk; ///< Termo instance
|
termo_t *tk; ///< Termo instance
|
||||||
|
@ -77,7 +74,7 @@ struct app_context
|
||||||
ev_timer tty_timer; ///< TTY timeout timer
|
ev_timer tty_timer; ///< TTY timeout timer
|
||||||
ev_signal winch_watcher; ///< SIGWINCH watcher
|
ev_signal winch_watcher; ///< SIGWINCH watcher
|
||||||
|
|
||||||
network_mode_t mode; ///< Networking mode
|
enum network_mode mode; ///< Networking mode
|
||||||
|
|
||||||
// Client:
|
// Client:
|
||||||
int server_fd; ///< Server connection
|
int server_fd; ///< Server connection
|
||||||
|
@ -91,7 +88,7 @@ struct app_context
|
||||||
// Server:
|
// Server:
|
||||||
int listen_fd; ///< Listening FD
|
int listen_fd; ///< Listening FD
|
||||||
ev_io listen_watcher; ///< Listening FD watcher
|
ev_io listen_watcher; ///< Listening FD watcher
|
||||||
client_t *clients; ///< Client connections
|
struct client *clients; ///< Client connections
|
||||||
|
|
||||||
chtype palette[2 * 9]; ///< Attribute palette
|
chtype palette[2 * 9]; ///< Attribute palette
|
||||||
|
|
||||||
|
@ -116,11 +113,11 @@ struct app_context
|
||||||
uint8_t current_color_right; ///< Right mouse button color
|
uint8_t current_color_right; ///< Right mouse button color
|
||||||
};
|
};
|
||||||
|
|
||||||
static void remove_client (app_context_t *app, client_t *client);
|
static void remove_client (struct app_context *app, struct client *client);
|
||||||
static void on_server_disconnected (app_context_t *app);
|
static void on_server_disconnected (struct app_context *app);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
app_init (app_context_t *self)
|
app_init (struct app_context *self)
|
||||||
{
|
{
|
||||||
memset (self, 0, sizeof *self);
|
memset (self, 0, sizeof *self);
|
||||||
self->server_fd = -1;
|
self->server_fd = -1;
|
||||||
|
@ -130,7 +127,7 @@ app_init (app_context_t *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
app_free (app_context_t *self)
|
app_free (struct app_context *self)
|
||||||
{
|
{
|
||||||
if (self->tk)
|
if (self->tk)
|
||||||
termo_destroy (self->tk);
|
termo_destroy (self->tk);
|
||||||
|
@ -204,21 +201,21 @@ flush_writer (struct msg_writer *writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
flush_writer_to_client (struct msg_writer *writer, client_t *client)
|
flush_writer_to_client (struct msg_writer *writer, struct client *client)
|
||||||
{
|
{
|
||||||
write_queue_add (&client->write_queue, flush_writer (writer));
|
write_queue_add (&client->write_queue, flush_writer (writer));
|
||||||
ev_io_start (EV_DEFAULT_ &client->write_watcher);
|
ev_io_start (EV_DEFAULT_ &client->write_watcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
flush_writer_to_server (struct msg_writer *writer, app_context_t *app)
|
flush_writer_to_server (struct msg_writer *writer, struct app_context *app)
|
||||||
{
|
{
|
||||||
write_queue_add (&app->write_queue, flush_writer (writer));
|
write_queue_add (&app->write_queue, flush_writer (writer));
|
||||||
ev_io_start (EV_DEFAULT_ &app->server_write_watcher);
|
ev_io_start (EV_DEFAULT_ &app->server_write_watcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_draw_point_response (client_t *client, int x, int y, uint8_t color)
|
send_draw_point_response (struct client *client, int x, int y, uint8_t color)
|
||||||
{
|
{
|
||||||
struct msg_writer writer;
|
struct msg_writer writer;
|
||||||
msg_writer_init (&writer);
|
msg_writer_init (&writer);
|
||||||
|
@ -231,7 +228,7 @@ send_draw_point_response (client_t *client, int x, int y, uint8_t color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_draw_point_request (app_context_t *app, int x, int y, uint8_t color)
|
send_draw_point_request (struct app_context *app, int x, int y, uint8_t color)
|
||||||
{
|
{
|
||||||
struct msg_writer writer;
|
struct msg_writer writer;
|
||||||
msg_writer_init (&writer);
|
msg_writer_init (&writer);
|
||||||
|
@ -244,7 +241,7 @@ send_draw_point_request (app_context_t *app, int x, int y, uint8_t color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_hello_request (app_context_t *app)
|
send_hello_request (struct app_context *app)
|
||||||
{
|
{
|
||||||
struct msg_writer writer;
|
struct msg_writer writer;
|
||||||
msg_writer_init (&writer);
|
msg_writer_init (&writer);
|
||||||
|
@ -255,7 +252,7 @@ send_hello_request (app_context_t *app)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_hello_response (client_t *client)
|
send_hello_response (struct client *client)
|
||||||
{
|
{
|
||||||
struct msg_writer writer;
|
struct msg_writer writer;
|
||||||
msg_writer_init (&writer);
|
msg_writer_init (&writer);
|
||||||
|
@ -266,7 +263,7 @@ send_hello_response (client_t *client)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_get_bitmap_request (app_context_t *app)
|
send_get_bitmap_request (struct app_context *app)
|
||||||
{
|
{
|
||||||
struct msg_writer writer;
|
struct msg_writer writer;
|
||||||
msg_writer_init (&writer);
|
msg_writer_init (&writer);
|
||||||
|
@ -276,7 +273,7 @@ send_get_bitmap_request (app_context_t *app)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_get_bitmap_response (client_t *client, app_context_t *app)
|
send_get_bitmap_response (struct client *client, struct app_context *app)
|
||||||
{
|
{
|
||||||
struct msg_writer writer;
|
struct msg_writer writer;
|
||||||
msg_writer_init (&writer);
|
msg_writer_init (&writer);
|
||||||
|
@ -329,7 +326,7 @@ display (const char *format, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_palette (app_context_t *app)
|
init_palette (struct app_context *app)
|
||||||
{
|
{
|
||||||
start_color ();
|
start_color ();
|
||||||
|
|
||||||
|
@ -358,14 +355,14 @@ init_palette (app_context_t *app)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_canvas_for_screen (app_context_t *app)
|
update_canvas_for_screen (struct app_context *app)
|
||||||
{
|
{
|
||||||
app->corner_x = app->center_x - COLS / 2;
|
app->corner_x = app->center_x - COLS / 2;
|
||||||
app->corner_y = app->center_y - (LINES - TOP_BAR_CUTOFF) / 2;
|
app->corner_y = app->center_y - (LINES - TOP_BAR_CUTOFF) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
redraw (app_context_t *app)
|
redraw (struct app_context *app)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -385,7 +382,7 @@ redraw (app_context_t *app)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
is_in_bitmap_data (app_context_t *app, int x, int y)
|
is_in_bitmap_data (struct app_context *app, int x, int y)
|
||||||
{
|
{
|
||||||
return x >= app->bitmap_x
|
return x >= app->bitmap_x
|
||||||
&& y >= app->bitmap_y
|
&& y >= app->bitmap_y
|
||||||
|
@ -394,7 +391,7 @@ is_in_bitmap_data (app_context_t *app, int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
redraw_canvas (app_context_t *app)
|
redraw_canvas (struct app_context *app)
|
||||||
{
|
{
|
||||||
int y = app->corner_y;
|
int y = app->corner_y;
|
||||||
for (int screen_y = TOP_BAR_CUTOFF; screen_y < LINES; screen_y++, y++)
|
for (int screen_y = TOP_BAR_CUTOFF; screen_y < LINES; screen_y++, y++)
|
||||||
|
@ -416,7 +413,7 @@ redraw_canvas (app_context_t *app)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
is_visible (app_context_t *app, int x, int y)
|
is_visible (struct app_context *app, int x, int y)
|
||||||
{
|
{
|
||||||
return x >= app->corner_x
|
return x >= app->corner_x
|
||||||
&& y >= app->corner_y
|
&& y >= app->corner_y
|
||||||
|
@ -425,7 +422,7 @@ is_visible (app_context_t *app, int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
make_place_for_point (app_context_t *app, int x, int y)
|
make_place_for_point (struct app_context *app, int x, int y)
|
||||||
{
|
{
|
||||||
if (is_in_bitmap_data (app, x, y))
|
if (is_in_bitmap_data (app, x, y))
|
||||||
return;
|
return;
|
||||||
|
@ -471,7 +468,7 @@ make_place_for_point (app_context_t *app, int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
draw_point_internal (app_context_t *app, int x, int y, uint8_t color)
|
draw_point_internal (struct app_context *app, int x, int y, uint8_t color)
|
||||||
{
|
{
|
||||||
make_place_for_point (app, x, y);
|
make_place_for_point (app, x, y);
|
||||||
BITMAP_PIXEL (app, x - app->bitmap_x, y - app->bitmap_y) = color;
|
BITMAP_PIXEL (app, x - app->bitmap_x, y - app->bitmap_y) = color;
|
||||||
|
@ -488,7 +485,7 @@ draw_point_internal (app_context_t *app, int x, int y, uint8_t color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
draw_point (app_context_t *app, int x, int y, uint8_t color)
|
draw_point (struct app_context *app, int x, int y, uint8_t color)
|
||||||
{
|
{
|
||||||
if (app->mode == NETWORK_MODE_CLIENT)
|
if (app->mode == NETWORK_MODE_CLIENT)
|
||||||
{
|
{
|
||||||
|
@ -504,12 +501,13 @@ draw_point (app_context_t *app, int x, int y, uint8_t color)
|
||||||
|
|
||||||
// Broadcast clients about the event
|
// Broadcast clients about the event
|
||||||
if (app->mode == NETWORK_MODE_SERVER)
|
if (app->mode == NETWORK_MODE_SERVER)
|
||||||
for (client_t *iter = app->clients; iter; iter = iter->next)
|
for (struct client *iter = app->clients; iter; iter = iter->next)
|
||||||
send_draw_point_response (iter, x, y, color);
|
send_draw_point_response (iter, x, y, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
draw_line (app_context_t *app, int x0, int x1, int y0, int y1, uint8_t color)
|
draw_line (struct app_context *app, int x0, int x1, int y0, int y1,
|
||||||
|
uint8_t color)
|
||||||
{
|
{
|
||||||
// Integer version of Bresenham's line drawing algorithm,
|
// Integer version of Bresenham's line drawing algorithm,
|
||||||
// loosely based on code from libcaca because screw math
|
// loosely based on code from libcaca because screw math
|
||||||
|
@ -555,7 +553,7 @@ draw_line (app_context_t *app, int x0, int x1, int y0, int y1, uint8_t color)
|
||||||
// --- Exports -----------------------------------------------------------------
|
// --- Exports -----------------------------------------------------------------
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
is_data_row_empty (app_context_t *app, int y)
|
is_data_row_empty (struct app_context *app, int y)
|
||||||
{
|
{
|
||||||
for (size_t x = 0; x < app->bitmap_w; x++)
|
for (size_t x = 0; x < app->bitmap_w; x++)
|
||||||
if (app->bitmap[y * app->bitmap_w + x])
|
if (app->bitmap[y * app->bitmap_w + x])
|
||||||
|
@ -564,7 +562,7 @@ is_data_row_empty (app_context_t *app, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
is_data_column_empty (app_context_t *app, int x)
|
is_data_column_empty (struct app_context *app, int x)
|
||||||
{
|
{
|
||||||
for (size_t y = 0; y < app->bitmap_h; y++)
|
for (size_t y = 0; y < app->bitmap_h; y++)
|
||||||
if (app->bitmap[y * app->bitmap_w + x])
|
if (app->bitmap[y * app->bitmap_w + x])
|
||||||
|
@ -573,7 +571,7 @@ is_data_column_empty (app_context_t *app, int x)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
find_data_bounding_rect (app_context_t *app,
|
find_data_bounding_rect (struct app_context *app,
|
||||||
size_t *x, size_t *y, size_t *w, size_t *h)
|
size_t *x, size_t *y, size_t *w, size_t *h)
|
||||||
{
|
{
|
||||||
size_t my_x = 0, my_y = 0;
|
size_t my_x = 0, my_y = 0;
|
||||||
|
@ -643,7 +641,7 @@ color_to_ansi (uint8_t color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
export_ansi (app_context_t *app)
|
export_ansi (struct app_context *app)
|
||||||
{
|
{
|
||||||
FILE *fp = fopen ("export-ansi.asc", "wb");
|
FILE *fp = fopen ("export-ansi.asc", "wb");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
|
@ -722,7 +720,7 @@ color_to_mirc (uint8_t color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
export_irc (app_context_t *app)
|
export_irc (struct app_context *app)
|
||||||
{
|
{
|
||||||
FILE *fp = fopen ("export-irc.asc", "wb");
|
FILE *fp = fopen ("export-irc.asc", "wb");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
|
@ -775,7 +773,7 @@ export_irc (app_context_t *app)
|
||||||
// --- Loading, saving ---------------------------------------------------------
|
// --- Loading, saving ---------------------------------------------------------
|
||||||
|
|
||||||
static void
|
static void
|
||||||
load (app_context_t *app)
|
load (struct app_context *app)
|
||||||
{
|
{
|
||||||
// Client cannot load at all, the server would have send the new bitmap out
|
// Client cannot load at all, the server would have send the new bitmap out
|
||||||
if (app->mode != NETWORK_MODE_STANDALONE)
|
if (app->mode != NETWORK_MODE_STANDALONE)
|
||||||
|
@ -839,7 +837,7 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
save (app_context_t *app)
|
save (struct app_context *app)
|
||||||
{
|
{
|
||||||
FILE *fp = fopen ("drawing.bin", "wb");
|
FILE *fp = fopen ("drawing.bin", "wb");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
|
@ -865,7 +863,7 @@ save (app_context_t *app)
|
||||||
// --- Event handlers ----------------------------------------------------------
|
// --- Event handlers ----------------------------------------------------------
|
||||||
|
|
||||||
static void
|
static void
|
||||||
move_canvas (app_context_t *app, int x, int y)
|
move_canvas (struct app_context *app, int x, int y)
|
||||||
{
|
{
|
||||||
app->corner_x += x;
|
app->corner_x += x;
|
||||||
app->corner_y += y;
|
app->corner_y += y;
|
||||||
|
@ -877,7 +875,7 @@ move_canvas (app_context_t *app, int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_mouse (app_context_t *app, termo_key_t *key)
|
on_mouse (struct app_context *app, termo_key_t *key)
|
||||||
{
|
{
|
||||||
int screen_y, screen_x, button;
|
int screen_y, screen_x, button;
|
||||||
termo_mouse_event_t event;
|
termo_mouse_event_t event;
|
||||||
|
@ -931,7 +929,7 @@ on_mouse (app_context_t *app, termo_key_t *key)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
on_key (app_context_t *app, termo_key_t *key)
|
on_key (struct app_context *app, termo_key_t *key)
|
||||||
{
|
{
|
||||||
if (key->type == TERMO_TYPE_KEYSYM)
|
if (key->type == TERMO_TYPE_KEYSYM)
|
||||||
{
|
{
|
||||||
|
@ -977,7 +975,7 @@ on_key (app_context_t *app, termo_key_t *key)
|
||||||
static void
|
static void
|
||||||
on_winch (EV_P_ ev_signal *handle, int revents)
|
on_winch (EV_P_ ev_signal *handle, int revents)
|
||||||
{
|
{
|
||||||
app_context_t *app = ev_userdata (loop);
|
struct app_context *app = ev_userdata (loop);
|
||||||
(void) handle;
|
(void) handle;
|
||||||
(void) revents;
|
(void) revents;
|
||||||
|
|
||||||
|
@ -1005,7 +1003,7 @@ on_winch (EV_P_ ev_signal *handle, int revents)
|
||||||
static void
|
static void
|
||||||
on_key_timer (EV_P_ ev_timer *handle, int revents)
|
on_key_timer (EV_P_ ev_timer *handle, int revents)
|
||||||
{
|
{
|
||||||
app_context_t *app = ev_userdata (loop);
|
struct app_context *app = ev_userdata (loop);
|
||||||
(void) handle;
|
(void) handle;
|
||||||
(void) revents;
|
(void) revents;
|
||||||
|
|
||||||
|
@ -1022,7 +1020,7 @@ on_tty_readable (EV_P_ ev_io *handle, int revents)
|
||||||
(void) handle;
|
(void) handle;
|
||||||
(void) revents;
|
(void) revents;
|
||||||
|
|
||||||
app_context_t *app = ev_userdata (loop);
|
struct app_context *app = ev_userdata (loop);
|
||||||
|
|
||||||
ev_timer_stop (EV_A_ &app->tty_timer);
|
ev_timer_stop (EV_A_ &app->tty_timer);
|
||||||
termo_advisereadable (app->tk);
|
termo_advisereadable (app->tk);
|
||||||
|
@ -1039,10 +1037,10 @@ on_tty_readable (EV_P_ ev_io *handle, int revents)
|
||||||
|
|
||||||
// --- Client-specific stuff ---------------------------------------------------
|
// --- Client-specific stuff ---------------------------------------------------
|
||||||
|
|
||||||
typedef bool (*server_handler_fn) (app_context_t *, struct msg_unpacker *);
|
typedef bool (*server_handler_fn) (struct app_context *, struct msg_unpacker *);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_server_disconnected (app_context_t *app)
|
on_server_disconnected (struct app_context *app)
|
||||||
{
|
{
|
||||||
write_queue_free (&app->write_queue);
|
write_queue_free (&app->write_queue);
|
||||||
write_queue_init (&app->write_queue);
|
write_queue_init (&app->write_queue);
|
||||||
|
@ -1061,7 +1059,7 @@ on_server_disconnected (app_context_t *app)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
on_server_hello (app_context_t *app, struct msg_unpacker *unpacker)
|
on_server_hello (struct app_context *app, struct msg_unpacker *unpacker)
|
||||||
{
|
{
|
||||||
(void) app;
|
(void) app;
|
||||||
|
|
||||||
|
@ -1074,7 +1072,7 @@ on_server_hello (app_context_t *app, struct msg_unpacker *unpacker)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
on_server_get_bitmap (app_context_t *app, struct msg_unpacker *unpacker)
|
on_server_get_bitmap (struct app_context *app, struct msg_unpacker *unpacker)
|
||||||
{
|
{
|
||||||
int32_t x, y;
|
int32_t x, y;
|
||||||
uint64_t w, h;
|
uint64_t w, h;
|
||||||
|
@ -1115,7 +1113,7 @@ on_server_get_bitmap (app_context_t *app, struct msg_unpacker *unpacker)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
on_server_put_point (app_context_t *app, struct msg_unpacker *unpacker)
|
on_server_put_point (struct app_context *app, struct msg_unpacker *unpacker)
|
||||||
{
|
{
|
||||||
int32_t x, y;
|
int32_t x, y;
|
||||||
uint8_t color;
|
uint8_t color;
|
||||||
|
@ -1134,7 +1132,7 @@ on_server_put_point (app_context_t *app, struct msg_unpacker *unpacker)
|
||||||
static bool
|
static bool
|
||||||
on_server_data (EV_P_ ev_io *watcher, const void *buf, ssize_t n_read)
|
on_server_data (EV_P_ ev_io *watcher, const void *buf, ssize_t n_read)
|
||||||
{
|
{
|
||||||
app_context_t *app = ev_userdata (loop);
|
struct app_context *app = ev_userdata (loop);
|
||||||
(void) watcher;
|
(void) watcher;
|
||||||
|
|
||||||
msg_reader_feed (&app->msg_reader, buf, n_read);
|
msg_reader_feed (&app->msg_reader, buf, n_read);
|
||||||
|
@ -1172,7 +1170,7 @@ on_server_data (EV_P_ ev_io *watcher, const void *buf, ssize_t n_read)
|
||||||
static void
|
static void
|
||||||
on_server_ready (EV_P_ ev_io *watcher, int revents)
|
on_server_ready (EV_P_ ev_io *watcher, int revents)
|
||||||
{
|
{
|
||||||
app_context_t *app = ev_userdata (loop);
|
struct app_context *app = ev_userdata (loop);
|
||||||
|
|
||||||
if (revents & EV_READ)
|
if (revents & EV_READ)
|
||||||
if (!read_loop (EV_A_ watcher, on_server_data))
|
if (!read_loop (EV_A_ watcher, on_server_data))
|
||||||
|
@ -1189,10 +1187,10 @@ error:
|
||||||
// --- Server-specific stuff ---------------------------------------------------
|
// --- Server-specific stuff ---------------------------------------------------
|
||||||
|
|
||||||
typedef bool (*client_handler_fn)
|
typedef bool (*client_handler_fn)
|
||||||
(app_context_t *, client_t *, struct msg_unpacker *);
|
(struct app_context *, struct client *, struct msg_unpacker *);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_client (app_context_t *app, client_t *client)
|
remove_client (struct app_context *app, struct client *client)
|
||||||
{
|
{
|
||||||
ev_io_stop (EV_DEFAULT_ &client->read_watcher);
|
ev_io_stop (EV_DEFAULT_ &client->read_watcher);
|
||||||
ev_io_stop (EV_DEFAULT_ &client->write_watcher);
|
ev_io_stop (EV_DEFAULT_ &client->write_watcher);
|
||||||
|
@ -1204,7 +1202,7 @@ remove_client (app_context_t *app, client_t *client)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
on_client_hello (app_context_t *app, client_t *client,
|
on_client_hello (struct app_context *app, struct client *client,
|
||||||
struct msg_unpacker *unpacker)
|
struct msg_unpacker *unpacker)
|
||||||
{
|
{
|
||||||
(void) app;
|
(void) app;
|
||||||
|
@ -1220,7 +1218,7 @@ on_client_hello (app_context_t *app, client_t *client,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
on_client_get_bitmap (app_context_t *app, client_t *client,
|
on_client_get_bitmap (struct app_context *app, struct client *client,
|
||||||
struct msg_unpacker *unpacker)
|
struct msg_unpacker *unpacker)
|
||||||
{
|
{
|
||||||
(void) unpacker;
|
(void) unpacker;
|
||||||
|
@ -1230,7 +1228,7 @@ on_client_get_bitmap (app_context_t *app, client_t *client,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
on_client_put_point (app_context_t *app, client_t *client,
|
on_client_put_point (struct app_context *app, struct client *client,
|
||||||
struct msg_unpacker *unpacker)
|
struct msg_unpacker *unpacker)
|
||||||
{
|
{
|
||||||
(void) client;
|
(void) client;
|
||||||
|
@ -1251,8 +1249,8 @@ on_client_put_point (app_context_t *app, client_t *client,
|
||||||
static bool
|
static bool
|
||||||
on_client_data (EV_P_ ev_io *watcher, const void *buf, ssize_t n_read)
|
on_client_data (EV_P_ ev_io *watcher, const void *buf, ssize_t n_read)
|
||||||
{
|
{
|
||||||
app_context_t *app = ev_userdata (loop);
|
struct app_context *app = ev_userdata (loop);
|
||||||
client_t *client = watcher->data;
|
struct client *client = watcher->data;
|
||||||
|
|
||||||
msg_reader_feed (&client->msg_reader, buf, n_read);
|
msg_reader_feed (&client->msg_reader, buf, n_read);
|
||||||
|
|
||||||
|
@ -1290,8 +1288,8 @@ on_client_data (EV_P_ ev_io *watcher, const void *buf, ssize_t n_read)
|
||||||
static void
|
static void
|
||||||
on_client_ready (EV_P_ ev_io *watcher, int revents)
|
on_client_ready (EV_P_ ev_io *watcher, int revents)
|
||||||
{
|
{
|
||||||
app_context_t *app = ev_userdata (loop);
|
struct app_context *app = ev_userdata (loop);
|
||||||
client_t *client = watcher->data;
|
struct client *client = watcher->data;
|
||||||
|
|
||||||
if (revents & EV_READ)
|
if (revents & EV_READ)
|
||||||
if (!read_loop (EV_A_ watcher, on_client_data))
|
if (!read_loop (EV_A_ watcher, on_client_data))
|
||||||
|
@ -1308,7 +1306,7 @@ error:
|
||||||
static void
|
static void
|
||||||
on_new_client (EV_P_ ev_io *watcher, int revents)
|
on_new_client (EV_P_ ev_io *watcher, int revents)
|
||||||
{
|
{
|
||||||
app_context_t *app = ev_userdata (loop);
|
struct app_context *app = ev_userdata (loop);
|
||||||
(void) revents;
|
(void) revents;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -1328,7 +1326,7 @@ on_new_client (EV_P_ ev_io *watcher, int revents)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
client_t *client = xcalloc (1, sizeof *client);
|
struct client *client = xcalloc (1, sizeof *client);
|
||||||
client->fd = sock_fd;
|
client->fd = sock_fd;
|
||||||
msg_reader_init (&client->msg_reader);
|
msg_reader_init (&client->msg_reader);
|
||||||
write_queue_init (&client->write_queue);
|
write_queue_init (&client->write_queue);
|
||||||
|
@ -1348,7 +1346,6 @@ on_new_client (EV_P_ ev_io *watcher, int revents)
|
||||||
|
|
||||||
// --- Program startup ---------------------------------------------------------
|
// --- Program startup ---------------------------------------------------------
|
||||||
|
|
||||||
typedef struct app_options app_options_t;
|
|
||||||
struct app_options
|
struct app_options
|
||||||
{
|
{
|
||||||
struct addrinfo *client_address; ///< Address to connect to
|
struct addrinfo *client_address; ///< Address to connect to
|
||||||
|
@ -1357,13 +1354,13 @@ struct app_options
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
app_options_init (app_options_t *self)
|
app_options_init (struct app_options *self)
|
||||||
{
|
{
|
||||||
memset (self, 0, sizeof *self);
|
memset (self, 0, sizeof *self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
app_options_free (app_options_t *self)
|
app_options_free (struct app_options *self)
|
||||||
{
|
{
|
||||||
if (self->client_address) freeaddrinfo (self->client_address);
|
if (self->client_address) freeaddrinfo (self->client_address);
|
||||||
if (self->server_address) freeaddrinfo (self->server_address);
|
if (self->server_address) freeaddrinfo (self->server_address);
|
||||||
|
@ -1378,7 +1375,7 @@ parse_address (const char *address, int flags)
|
||||||
char *colon = strrchr (address_copy, ':');
|
char *colon = strrchr (address_copy, ':');
|
||||||
if (!colon)
|
if (!colon)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "error: no port number specified in `%s'\n", address);
|
print_error ("no port number specified in `%s'", address);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1405,7 +1402,7 @@ parse_address (const char *address, int flags)
|
||||||
int err = getaddrinfo (host, service, &hints, &result);
|
int err = getaddrinfo (host, service, &hints, &result);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "error: cannot resolve `%s', port `%s': %s\n",
|
print_error ("cannot resolve `%s', port `%s': %s",
|
||||||
host, service, gai_strerror (err));
|
host, service, gai_strerror (err));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1413,7 +1410,7 @@ parse_address (const char *address, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_program_arguments (app_options_t *options, int argc, char **argv)
|
parse_program_arguments (struct app_options *options, int argc, char **argv)
|
||||||
{
|
{
|
||||||
static const struct opt opts[] =
|
static const struct opt opts[] =
|
||||||
{
|
{
|
||||||
|
@ -1442,21 +1439,13 @@ parse_program_arguments (app_options_t *options, int argc, char **argv)
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
case 's':
|
case 's':
|
||||||
if (options->server_address)
|
if (options->server_address)
|
||||||
{
|
exit_fatal ("cannot specify multiple listening addresses");
|
||||||
fprintf (stderr, "%s: %s\n",
|
|
||||||
"error", "cannot specify multiple listening addresses");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
if (!(options->server_address = parse_address (optarg, AI_PASSIVE)))
|
if (!(options->server_address = parse_address (optarg, AI_PASSIVE)))
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
if (options->client_address)
|
if (options->client_address)
|
||||||
{
|
exit_fatal ("cannot specify multiple addresses to connect to");
|
||||||
fprintf (stderr, "%s: %s\n",
|
|
||||||
"error", "cannot specify multiple addresses to connect to");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
if (!(options->client_address = parse_address (optarg, 0)))
|
if (!(options->client_address = parse_address (optarg, 0)))
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
break;
|
break;
|
||||||
|
@ -1464,17 +1453,13 @@ parse_program_arguments (app_options_t *options, int argc, char **argv)
|
||||||
options->no_wait = true;
|
options->no_wait = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf (stderr, "%s: %s\n", "error", "wrong options");
|
print_error ("wrong options");
|
||||||
opt_handler_usage (&oh, stderr);
|
opt_handler_usage (&oh, stderr);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options->client_address && options->server_address)
|
if (options->client_address && options->server_address)
|
||||||
{
|
exit_fatal ("cannot be both a server and a client");
|
||||||
fprintf (stderr, "%s: %s\n",
|
|
||||||
"error", "cannot be both a server and a client");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
@ -1489,7 +1474,7 @@ parse_program_arguments (app_options_t *options, int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
initialize_client (app_context_t *app, struct addrinfo *address)
|
initialize_client (struct app_context *app, struct addrinfo *address)
|
||||||
{
|
{
|
||||||
app->mode = NETWORK_MODE_CLIENT;
|
app->mode = NETWORK_MODE_CLIENT;
|
||||||
|
|
||||||
|
@ -1507,14 +1492,13 @@ initialize_client (app_context_t *app, struct addrinfo *address)
|
||||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s: %s: %s\n",
|
print_error ("%s: %s", "getnameinfo", gai_strerror (err));
|
||||||
"error", "getnameinfo", gai_strerror (err));
|
print_status ("connecting...");
|
||||||
fprintf (stderr, "connecting...\n");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *x = format_host_port_pair (host_buf, serv_buf);
|
char *x = format_host_port_pair (host_buf, serv_buf);
|
||||||
fprintf (stderr, "connecting to %s...\n", x);
|
print_status ("connecting to %s...", x);
|
||||||
free (x);
|
free (x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1525,10 +1509,7 @@ initialize_client (app_context_t *app, struct addrinfo *address)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!address)
|
if (!address)
|
||||||
{
|
exit_fatal ("connection failed");
|
||||||
fprintf (stderr, "%s: %s\n", "error", "connection failed");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int yes = 1;
|
int yes = 1;
|
||||||
(void) setsockopt (sock_fd, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof yes);
|
(void) setsockopt (sock_fd, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof yes);
|
||||||
|
@ -1546,7 +1527,7 @@ initialize_client (app_context_t *app, struct addrinfo *address)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
initialize_server (app_context_t *app, struct addrinfo *address)
|
initialize_server (struct app_context *app, struct addrinfo *address)
|
||||||
{
|
{
|
||||||
app->mode = NETWORK_MODE_SERVER;
|
app->mode = NETWORK_MODE_SERVER;
|
||||||
|
|
||||||
|
@ -1572,9 +1553,7 @@ initialize_server (app_context_t *app, struct addrinfo *address)
|
||||||
fail:
|
fail:
|
||||||
xclose (sock_fd);
|
xclose (sock_fd);
|
||||||
fail_socket:
|
fail_socket:
|
||||||
fprintf (stderr, "%s: %s: %s\n",
|
exit_fatal ("%s: %s", "initialization failed", strerror (errno));
|
||||||
"error", "initialization failed", strerror (errno));
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1583,17 +1562,14 @@ main (int argc, char *argv[])
|
||||||
TERMO_CHECK_VERSION;
|
TERMO_CHECK_VERSION;
|
||||||
setlocale (LC_CTYPE, "");
|
setlocale (LC_CTYPE, "");
|
||||||
|
|
||||||
app_context_t app;
|
struct app_context app;
|
||||||
app_init (&app);
|
app_init (&app);
|
||||||
|
|
||||||
struct ev_loop *loop = EV_DEFAULT;
|
struct ev_loop *loop = EV_DEFAULT;
|
||||||
if (!loop)
|
if (!loop)
|
||||||
{
|
exit_fatal ("cannot initialize libev");
|
||||||
fprintf (stderr, "%s: %s\n", "error", "cannot initialize libev");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
app_options_t options;
|
struct app_options options;
|
||||||
app_options_init (&options);
|
app_options_init (&options);
|
||||||
parse_program_arguments (&options, argc, argv);
|
parse_program_arguments (&options, argc, argv);
|
||||||
|
|
||||||
|
@ -1609,30 +1585,21 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
termo_t *tk = termo_new (STDIN_FILENO, NULL, 0);
|
termo_t *tk = termo_new (STDIN_FILENO, NULL, 0);
|
||||||
if (!tk)
|
if (!tk)
|
||||||
{
|
exit_fatal ("cannot allocate termo instance");
|
||||||
fprintf (stderr, "%s: %s\n",
|
|
||||||
"error", "cannot allocate termo instance\n");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
app.tk = tk;
|
app.tk = tk;
|
||||||
termo_set_mouse_tracking_mode (tk, TERMO_MOUSE_TRACKING_DRAG);
|
termo_set_mouse_tracking_mode (tk, TERMO_MOUSE_TRACKING_DRAG);
|
||||||
|
|
||||||
// Set up curses for our drawing needs
|
// Set up curses for our drawing needs
|
||||||
if (!initscr () || nonl () == ERR || curs_set (0) == ERR)
|
if (!initscr () || nonl () == ERR || curs_set (0) == ERR)
|
||||||
{
|
exit_fatal ("cannot initialize curses");
|
||||||
fprintf (stderr, "%s: %s\n", "error", "cannot initialize curses");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ev_set_userdata (loop, &app);
|
ev_set_userdata (loop, &app);
|
||||||
|
|
||||||
ev_signal_init (&app.winch_watcher, on_winch, SIGWINCH);
|
ev_signal_init (&app.winch_watcher, on_winch, SIGWINCH);
|
||||||
ev_signal_start (EV_DEFAULT_ &app.winch_watcher);
|
ev_signal_start (EV_DEFAULT_ &app.winch_watcher);
|
||||||
|
|
||||||
ev_io_init (&app.tty_watcher, on_tty_readable, STDIN_FILENO, EV_READ);
|
ev_io_init (&app.tty_watcher, on_tty_readable, STDIN_FILENO, EV_READ);
|
||||||
ev_io_start (EV_DEFAULT_ &app.tty_watcher);
|
ev_io_start (EV_DEFAULT_ &app.tty_watcher);
|
||||||
|
|
||||||
ev_timer_init (&app.tty_timer, on_key_timer,
|
ev_timer_init (&app.tty_timer, on_key_timer,
|
||||||
termo_get_waittime (app.tk) / 1000., 0);
|
termo_get_waittime (app.tk) / 1000., 0);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue