diff --git a/control_tab.c b/control_tab.c index b6674a0..2a9eed5 100644 --- a/control_tab.c +++ b/control_tab.c @@ -1,15 +1,89 @@ +#include +#include #include +#include -static gboolean connected = FALSE; +#include "tcpsocket.h" +#include "sockaddr.h" -static void connect_cb(GtkWidget *widget, gpointer data) +enum { + STAT_DISCONNECTED = 0, + STAT_CONNECTING, + STAT_CONNECTED +}; + +static GtkWidget *button_connect; +static int connect_status = STAT_DISCONNECTED; + +static gint socket_tag; +static int socket_fd; + +static void update_connect_button(void) { - connected = !connected; - - if (connected) - gtk_button_set_label(GTK_BUTTON(widget), "Disconnect"); + if (connect_status == STAT_DISCONNECTED) + gtk_button_set_label(GTK_BUTTON(button_connect), "Connect"); else - gtk_button_set_label(GTK_BUTTON(widget), "Connect"); + gtk_button_set_label(GTK_BUTTON(button_connect), "Disconnect"); +} + +static void read_cb(gpointer data, gint source, GdkInputCondition condition) +{ + char buf[64]; + + int len = read(source, buf, sizeof(buf)); + if (len <= 0) { + g_warning("gtdc:read_cb:read:%s", g_strerror(errno)); + connect_status = STAT_DISCONNECTED; + update_connect_button(); + + gdk_input_remove(socket_tag); + close(socket_fd); + } +} + +static void connect_cb(gpointer data, gint source, GdkInputCondition condition) +{ + gdk_input_remove(socket_tag); + + if (tcp_connect_error(source) < 0) { + g_warning("gtdc:connect_cb:tcp_connect_error:%s", g_strerror(errno)); + connect_status = STAT_DISCONNECTED; + close(socket_fd); + + } else { + connect_status = STAT_CONNECTED; + socket_tag = gdk_input_add(socket_fd, GDK_INPUT_READ, read_cb, NULL); + + //TODO: clear variable data + //TODO: send TDC_HELLO + } + + update_connect_button(); +} + +static void connect_button_cb(GtkWidget *widget, gpointer data) +{ + switch (connect_status) { + case STAT_DISCONNECTED: + connect_status = STAT_CONNECTING; + + struct sockaddr_in sa; + parse_sockaddr("127.0.0.1:5000", &sa); + socket_fd = tcp_connect_nonblock(&sa); + + socket_tag = gdk_input_add(socket_fd, GDK_INPUT_WRITE, connect_cb, NULL); + break; + + case STAT_CONNECTING: + case STAT_CONNECTED: + connect_status = STAT_DISCONNECTED; + + gdk_input_remove(socket_tag); + close(socket_fd); + break; + } + + update_connect_button(); } gint control_tab_init(GtkNotebook *notebook) @@ -17,9 +91,9 @@ gint control_tab_init(GtkNotebook *notebook) GtkWidget *table = gtk_table_new(10, 10, FALSE); gtk_container_set_border_width(GTK_CONTAINER(table), 10); - GtkWidget *button = gtk_button_new_with_label("Connect"); - gtk_table_attach(GTK_TABLE(table), button, 0, 1, 0, 1, 0, 0, 10, 10); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(connect_cb), NULL); + button_connect = gtk_button_new_with_label("Connect"); + gtk_table_attach(GTK_TABLE(table), button_connect, 0, 1, 0, 1, 0, 0, 10, 10); + g_signal_connect(G_OBJECT(button_connect), "clicked", G_CALLBACK(connect_button_cb), NULL); GtkWidget *label = gtk_label_new(" Control "); return gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label);