#include #include #include #include "inet.h" #include "common.h" #include "network.h" #include "logic.h" #define MAXSIZE 512 int wait = 0; int c = 1; int sockfd; GtkWidget *boardwidget; static GdkPixmap *pixmap = NULL; void update_board() { for (int i = 0; i < SIZE; i++) for (int j = 0; j < SIZE; j++) if (board[i][j] == 1) { gdk_draw_rectangle(pixmap, boardwidget->style->white_gc, TRUE, i * 50, j * 50, 49, 49); gdk_draw_arc(pixmap, boardwidget->style->black_gc, FALSE, i * 50 + 5, j * 50 + 5, 40, 40, 0, 23040); gtk_widget_queue_draw_area(boardwidget, i * 50, j * 50, 50, 50); } else if (board[i][j] == 2) { gdk_draw_arc(pixmap, boardwidget->style->black_gc, TRUE, i * 50 + 5, j * 50 + 5, 40, 40, 0, 23040); gtk_widget_queue_draw_area(boardwidget, i * 50, j * 50, 50, 50); } else { gdk_draw_rectangle(pixmap, boardwidget->style->white_gc, TRUE, i * 50, j * 50, 49, 49); gtk_widget_queue_draw_area(boardwidget, i * 50, j * 50, 50, 50); } } static gboolean configure_event(GtkWidget *widget, GdkEventConfigure *event) { if (pixmap) g_object_unref(pixmap); pixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1); gdk_draw_rectangle (pixmap, widget->style->white_gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); for (int i = 0; i < 7; i++) { gdk_draw_line(pixmap, widget->style->black_gc, i*50 + 49, 0, i * 50 + 49, 400); gdk_draw_line(pixmap, widget->style->black_gc, 0, i*50 + 49, 400, i * 50 + 49); } return TRUE; } static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event) { gdk_draw_drawable(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return FALSE; } char **board2buf(int board[SIZE][SIZE]) { char **buf = malloc(SIZE * sizeof(char *)); for (int i = 0; i < SIZE; i++) buf[i] = malloc((SIZE + 2) * sizeof(char)); for(int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { // Coordinates alternation buf[i][j] = board[j][i] + '0'; } buf[i][SIZE] = '\n'; buf[i][SIZE+1] = '\0'; } return buf; } void senddata(int sockfd, int code, char **buf) { char out[MAXSIZE]; int n; if (code == rp_ok) { sprintf(out, "1\n"); for (int i = 0; i < SIZE; i++) { strcat(out, buf[i]); } } else { sprintf(out, "0\n"); } fprintf(stderr, "Sending: %s", out); n = strlen(out); if (writen(sockfd, out, n) != n) fprintf(stderr, "str_echo: writen error\n"); } void input_callback(gpointer data, gint sockfd, GdkInputCondition condition) { int n; int res; int x, y, c; char line[MAXSIZE + 1]; n = readline(sockfd, line, MAXSIZE); if (n == 0) { g_error("Connection terminated\n"); return; /* connection terminated */ } else if (n < 0) g_error("str_echo: readline error\n"); g_print("Received: %s", line); if (!wait) { if (line[0] == '0') { res = init(); } else if (line[0] == '1') { res = 0; wait = 1; } } else { sscanf(line, "%d,%d,%d", &x, &y, &c); res = place(x, y, c); wait = 0; } if (res) { senddata(sockfd, rp_ok, board2buf(board)); } else { senddata(sockfd, rp_error, NULL); } update_board(); } static gboolean board_clicked(GtkWidget *widget, GdkEventButton *event) { g_print("Received: %d,%d,%d\n", (int)event->x / 50, (int)event->y / 50, 2); int res = place((int)event->x / 50, (int)event->y / 50, 2); if (res) { senddata(sockfd, rp_ok, board2buf(board)); } else { senddata(sockfd, rp_error, NULL); } update_board(); return TRUE; } static void destroy(GtkWidget *widget, GdkEventButton *event) { gtk_main_quit(); } int main(int argc, char **argv) { GtkWidget *window; int newsockfd; unsigned int clilen; /* GtkWidget *vbox; GtkWidget *hbox[8]; */ struct sockaddr_in serv_addr, cli_addr; gtk_init (&argc, &argv); /* if (strstr(argv[1], "-s")) { ; } else { ; } */ /* * Fill in the structure "serv_addr" with the address of the * server that we want to connect with. */ memset((char *) &serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SERV_TCP_PORT); /* * Open a TCP socket (an Internet stream socket). */ if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) g_error("client: can't open stream socket"); /* * Bind our local address so that the client can send to us. */ if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) g_error("server: can't bind local address"); listen(sockfd, 5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) g_error("server: accept error"); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); /* vbox = gtk_vbox_new(TRUE, 0); gtk_widget_show(vbox); */ /* This packs the canvas into the window (a gtk container). */ /* gtk_container_add(GTK_CONTAINER(window), vbox); */ /* Here we connect the "destroy" event to a signal handler. * This event occurs when we call gtk_widget_destroy() on the window, * or if we return FALSE in the "delete_event" callback. */ g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL); /* Sets the border width of the window. */ gtk_container_set_border_width(GTK_CONTAINER(window), 10); boardwidget = gtk_drawing_area_new(); gtk_widget_set_size_request(boardwidget, 400, 400); g_signal_connect (G_OBJECT (boardwidget), "button_release_event", (GtkSignalFunc) board_clicked, NULL); gtk_signal_connect (GTK_OBJECT (boardwidget), "expose_event", (GtkSignalFunc) expose_event, NULL); gtk_signal_connect (GTK_OBJECT(boardwidget),"configure_event", (GtkSignalFunc) configure_event, NULL); gtk_widget_set_events(boardwidget, GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY); gtk_container_add(GTK_CONTAINER (window), boardwidget); gtk_widget_show(boardwidget); /* for (int i = 0; i < 8; i++) { hbox[i] = gtk_hbox_new(TRUE, 0); gtk_widget_show(hbox[i]); gtk_box_pack_start(GTK_BOX(vbox), hbox[i], TRUE, TRUE, 0); for (int j = 0; j < 8; j++) { button[i][j] = gtk_button_new_with_label("X"); g_signal_connect(G_OBJECT(button[i][j]), "clicked", G_CALLBACK(button_clicked), GINT_TO_POINTER(i*8+j)); */ /* The final step is to display this newly created widget. */ /* gtk_widget_show(button[i][j]); gtk_box_pack_start(GTK_BOX(hbox[i]), button[i][j], TRUE, TRUE, 0); } } */ /* and the window */ gtk_widget_show(window); gdk_input_add(newsockfd, GDK_INPUT_READ, input_callback, NULL); gtk_main(); close(sockfd); close(newsockfd); return 0; }