1 /* grrobot - Ricochet Robot using GTK+ and Xr
3 * Copyright © 2003 Carl Worth
5 * Permission to use, copy, modify, distribute, and sell this software
6 * and its documentation for any purpose is hereby granted without
7 * fee, provided that the above copyright notice appear in all copies
8 * and that both that copyright notice and this permission notice
9 * appear in supporting documentation, and that the name of Carl Worth
10 * not be used in advertising or publicity pertaining to distribution
11 * of the software without specific, written prior permission.
12 * Carl Worth makes no representations about the suitability of this
13 * software for any purpose. It is provided "as is" without express
14 * or implied warranty.
16 * CARL WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
18 * NO EVENT SHALL CARL WORTH BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
20 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
21 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 * Author: Carl Worth <carl@theworths.org>
35 #include "grr_board_view.h"
38 typedef struct grr_game {
43 GtkWidget *board_view;
44 GtkTextBuffer *message_buffer;
45 GtkWidget *message_view;
46 GtkWidget *command_entry;
50 do_gui (grr_game_t *game);
53 game_callback (gpointer data,
55 GdkInputCondition condition);
58 main (int argc, char **argv)
66 gtk_init (&argc, &argv);
68 args_parse (&args, argc, argv);
70 game.client = rr_client_create (args.host, args.port, args.user);
71 if (game.client == NULL) {
72 fprintf (stderr, "Failed connecting to %s:%s as %s\n",
73 args.host, args.port, args.user);
77 status = rr_client_join (game.client, args.game);
78 if (status == RR_STATUS_NO_GAME) {
79 status = rr_client_new (game.client, args.game);
82 game.board = rr_board_create (16, 16);
84 gdk_input_add (rr_client_fd (game.client),
89 rr_client_show (game.client, &diagram);
90 rr_board_parse (game.board, diagram);
93 return do_gui (&game);
97 game_callback (gpointer data,
99 GdkInputCondition condition)
101 grr_game_t *game = data;
102 rr_board_t *board = game->board;
107 while (rr_client_notice_pending (game->client)) {
108 status = rr_client_next_notice (game->client, ¬ice_s);
110 fprintf (stderr, "Error during rr_client_notice: %s\n",
111 rr_status_str (status));
115 notice = rr_client_parse_notice (game->client, notice_s);
116 switch (notice->type) {
120 case RR_NOTICE_DISPOSE:
121 case RR_NOTICE_MESSAGE:
122 case RR_NOTICE_GAMESTATE:
125 case RR_NOTICE_WATCH:
128 case RR_NOTICE_REVOKE:
129 case RR_NOTICE_TIMER:
130 case RR_NOTICE_ABANDON:
131 case RR_NOTICE_NOBID:
132 case RR_NOTICE_ACTIVE:
135 case RR_NOTICE_RESET:
136 case RR_NOTICE_SCORE:
137 case RR_NOTICE_ACTIVATE:
138 /* Ignore these requests */
140 case RR_NOTICE_POSITION:
141 rr_board_position (board, notice->u.position.robot,
142 notice->u.position.x, notice->u.position.y);
143 gtk_widget_queue_draw (GTK_WIDGET (game->window));
151 command_callback (GtkWidget *widget,
154 const gchar *entry_text;
157 entry_text = gtk_entry_get_text (GTK_ENTRY (widget));
158 rr_client_request (game->client, entry_text, &response);
159 gtk_entry_set_text (GTK_ENTRY (widget), "");
160 gtk_text_buffer_insert_at_cursor (game->message_buffer, entry_text, -1);
162 /* XXX: Huh? Why is this triggering valgrind?
169 do_gui (grr_game_t *game)
171 GtkWidget *board_frame;
176 GtkWidget *message_view;
177 GtkWidget *command_entry;
179 game->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
180 window = game->window;
182 gtk_window_set_title (GTK_WINDOW (window), "Ricochet Robot");
183 gtk_window_set_default_size (GTK_WINDOW (window), 512, 512);
185 g_signal_connect (G_OBJECT (window), "destroy",
186 G_CALLBACK (exit), NULL);
187 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
189 vpaned = gtk_vpaned_new ();
190 gtk_container_set_border_width (GTK_CONTAINER (vpaned), 5);
191 gtk_container_add (GTK_CONTAINER (window), vpaned);
193 board_frame = gtk_aspect_frame_new (NULL, 0.5, 0.5, 1.0, FALSE);
194 gtk_paned_pack1 (GTK_PANED (vpaned), board_frame, TRUE, TRUE);
196 game->board_view = grr_board_view_new (game->board);
198 gtk_container_add (GTK_CONTAINER (board_frame), game->board_view);
199 gtk_widget_show (game->board_view);
201 gtk_widget_show (board_frame);
203 vbox = gtk_vbox_new (FALSE, 1);
204 gtk_paned_pack2 (GTK_PANED (vpaned), vbox, FALSE, TRUE);
206 sw = gtk_scrolled_window_new (NULL, NULL);
207 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
209 GTK_POLICY_AUTOMATIC);
210 gtk_container_add (GTK_CONTAINER (vbox), sw);
211 gtk_widget_show (sw);
213 game->message_buffer = gtk_text_buffer_new (NULL);
214 game->message_view = gtk_text_view_new_with_buffer (game->message_buffer);
215 message_view = game->message_view;
216 gtk_text_view_set_editable (GTK_TEXT_VIEW (message_view), FALSE);
217 gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (message_view), FALSE);
218 gtk_container_add (GTK_CONTAINER (sw), message_view);
219 gtk_widget_show (message_view);
221 game->command_entry = gtk_entry_new ();
222 command_entry = game->command_entry;
223 gtk_container_add (GTK_CONTAINER (vbox), command_entry);
224 gtk_widget_show (command_entry);
225 g_signal_connect (G_OBJECT (command_entry), "activate",
226 G_CALLBACK (command_callback),
229 gtk_widget_show (vbox);
231 gtk_widget_show (vpaned);
233 gtk_widget_show (window);