#include #include #include #include #include #include #include #include #include #include #include GtkWidget *addition_view, *server_view; GtkTextBuffer *addition_buffer, *server_buffer; int skt; GtkWidget *grid; // This is NOT in the GUI thread! // That means we can have a race condition // GTK has thread safety, but not when used this way void* listen_for_updates(void* arg){ int length = 0; char story[1025]; for(;;){ read(skt, &length, 4); if(length) recv(skt, story, length, MSG_WAITALL); story[length] = 0; int add_text(gpointer data){ server_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (server_view)); gtk_text_buffer_set_text (server_buffer, story, -1); return 0; } gdk_threads_add_idle(add_text, 0); // gtk_grid_attach(GTK_GRID(grid), server_view, 0, 7, 6, 3); printf("Succeeded in grid attach\n"); } } char* get_text_of_textview(GtkWidget *text_view) { GtkTextIter start, end; GtkTextBuffer *buffer = gtk_text_view_get_buffer((GtkTextView *)text_view); gchar *text; gtk_text_buffer_get_bounds(buffer, &start, &end); text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); return text; } static void send_addition (GtkWidget *widget, gpointer data) { char* the_text = get_text_of_textview(addition_view); g_print ("Sending Addition:\n"); g_print (the_text); g_print ("\n\n"); int textlen = strlen(the_text); write(skt, &textlen, 4); // TODO: All these should have the return value checked write(skt, the_text, textlen); } static void activate (GtkApplication *app, gpointer user_data){ GtkWidget *window; GtkWidget *button; printf("We're here\n"); /* create a new window, and set its title */ window = gtk_application_window_new (app); gtk_window_set_title (GTK_WINDOW (window), "Window"); gtk_container_set_border_width (GTK_CONTAINER (window), 10); /* Here we construct the container that is going pack our buttons */ grid = gtk_grid_new (); /* Pack the container in the window */ gtk_container_add (GTK_CONTAINER (window), grid); button = gtk_button_new_with_label ("Send Addition"); g_signal_connect (button, "clicked", G_CALLBACK (send_addition), NULL); /* Place the first button in the grid cell (0, 0), and make it fill * just 1 cell horizontally and vertically (ie no spanning) */ gtk_grid_attach (GTK_GRID (grid), button, 0, 6, 1, 1); button = gtk_button_new_with_label ("Quit"); g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window); /* Place the Quit button in the grid cell (0, 1), and make it * span 2 columns. */ gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 2, 1); addition_view = gtk_text_view_new (); addition_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (addition_view)); gtk_text_buffer_set_text (addition_buffer, "Add your addition here", -1); gtk_grid_attach(GTK_GRID(grid), addition_view, 0, 2, 6, 3); server_view = gtk_text_view_new (); server_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (server_view)); gtk_widget_set_hexpand(server_view, TRUE); gtk_widget_set_vexpand(server_view, TRUE); gtk_text_buffer_set_text (server_buffer, "Story from server goes here. It is really long. It will take up a lot of space, and it would be nice if it fit in our textview", -1); gtk_grid_attach(GTK_GRID(grid), server_view, 0, 7, 6, 3); /* Now you might put the view in a container and display it on the * screen; when the user edits the text, signals on the buffer * will be emitted, such as "changed", "insert_text", and so on. */ /* Now that we are done packing our widgets, we show them all * in one go, by calling gtk_widget_show_all() on the window. * This call recursively calls gtk_widget_show() on all widgets * that are contained in the window, directly or indirectly. */ gtk_widget_show_all (window); pthread_t T; pthread_create(&T, 0, listen_for_updates, 0); int length = 0; write(skt, &length, 4); } int main(int argc, char ** argv){ struct sockaddr_in sad; sad.sin_port = htons(atoi(argv[2])); sad.sin_family = AF_INET; skt = socket(AF_INET, SOCK_STREAM, 0); struct hostent* entry = gethostbyname(argv[1]); struct in_addr **addr_list = (struct in_addr**)entry->h_addr_list; struct in_addr* c_addr = addr_list[0]; char* ip_string = inet_ntoa(*c_addr); sad.sin_addr = *c_addr; printf("Connecting to: %s\n", ip_string); connect(skt, (struct sockaddr*)&sad, sizeof(struct sockaddr_in)); GtkApplication *app; int status; printf("About to start the GUI\n"); app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE); g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); printf("Calling g_application_run\n"); status = g_application_run (G_APPLICATION (app), 0, 0); g_object_unref (app); close(skt); return status; }