got the board to render halfway
[xboard.git] / callback.c
1 #include <gtk/gtk.h>
2 #include "common.h"
3 #include <errno.h>
4 #include "backend.h"
5
6 #ifdef ENABLE_NLS
7 # define  _(s) gettext (s)
8 # define N_(s) gettext_noop (s)
9 #else
10 # define  _(s) (s)
11 # define N_(s)  s
12 #endif
13
14
15 extern GtkWidget  *about;
16 extern GtkWidget  *GUI_Window;
17
18 extern char *programVersion;
19 extern int errorExitStatus;
20 extern int promotionUp;
21 extern int fromX;
22 extern int fromY;
23 extern int toX;
24 extern int toY;
25
26 void 
27 QuitProc (object, user_data)
28      GtkObject *object;
29      gpointer user_data;
30 {
31   gtk_main_quit();
32   ExitEvent(0);
33 }
34
35 void AboutProc (object, user_data)
36      GtkObject *object;
37      gpointer user_data;
38 {
39   GtkWidget               *about;
40
41   const gchar *authors[] = {"Tim Mann <tim@tim-mann.org>",
42                             "John Chanak",
43                             "Evan Welsh <Evan.Welsh@msdw.com>",
44                             "Elmar Bartel <bartel@informatik.tu-muenchen.de>",
45                             "Jochen Wiedmann",
46                             "Frank McIngvale",
47                             "Hugh Fisher <Hugh.Fisher@cs.anu.edu.au>",
48                             "Allessandro Scotti",
49                             "H.G. Muller <h.g.muller AT hccnet DOT nl>",
50                             "Eric Mullins <emwine AT earthlink DOT net>",
51                             "Arun Persaud <arun@nubati.net>"};
52   
53   /* set up about window */
54   about =  GTK_WIDGET(gtk_about_dialog_new());
55
56   /* fill in some information */
57   char buf[MSG_SIZ];
58 #if ZIPPY
59   char *zippy = " (with Zippy code)";
60 #else
61   char *zippy = "";
62 #endif
63   sprintf(buf, "%s%s",  programVersion, zippy);
64   
65   gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),buf);
66
67   gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about), 
68                                  "Copyright 1991 Digital Equipment Corporation\n"
69                                  "Enhancements Copyright 1992-2009 Free Software Foundation\n"
70                                  "Enhancements Copyright 2005 Alessandro Scotti");
71   gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),"http://www.gnu.org/software/xboard/");
72   gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about),authors);
73   gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(about),
74                                           " A. Alper (turkish)\n"
75                                           " A. Persaud (german)\n");
76   
77   /* end set up about window */
78   gtk_dialog_run(GTK_DIALOG (about));
79   gtk_widget_destroy(about);
80 }
81
82 void LoadNextGameProc(object, user_data)
83      GtkObject *object;
84      gpointer user_data;
85 {
86     ReloadGame(1);
87     return;
88 }
89
90 void LoadPrevGameProc(object, user_data)
91      GtkObject *object;
92      gpointer user_data;
93 {
94     ReloadGame(-1);
95     return;
96 }
97
98 void ReloadGameProc(object, user_data)
99      GtkObject *object;
100      gpointer user_data;
101 {
102     ReloadGame(0);
103     return;
104 }
105
106
107 gboolean CloseWindowProc(GtkWidget *button)
108 {
109     gtk_widget_destroy(gtk_widget_get_toplevel(button));
110     return TRUE;
111 }
112
113 void 
114 ResetProc (object, user_data)
115      GtkObject *object;
116      gpointer user_data;
117 {
118   ResetGameEvent(); 
119   AnalysisPopDown();
120 }
121
122 void WhiteClockProc(object, user_data)
123      GtkObject *object;
124      gpointer user_data;
125 {
126     if (gameMode == EditPosition || gameMode == IcsExamining) {
127         SetWhiteToPlayEvent();
128     } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) {
129         CallFlagEvent();
130     }
131 }
132
133 void BlackClockProc(object, user_data)
134      GtkObject *object;
135      gpointer user_data;
136 {
137     if (gameMode == EditPosition || gameMode == IcsExamining) {
138         SetBlackToPlayEvent();
139     } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) {
140         CallFlagEvent();
141     }
142 }
143
144
145 void ShowCoordsProc(object, user_data)
146      GtkObject *object;
147      gpointer user_data;
148 {
149     appData.showCoords = !appData.showCoords;
150
151     DrawPosition(True, NULL);
152 }
153
154 void ErrorPopDownProc(object, user_data)
155      GtkObject *object;
156      gpointer user_data;
157 {
158   gtk_widget_destroy(GTK_WIDGET(object));
159   ErrorPopDown();
160 }
161
162 void PauseProc(object, user_data)
163      GtkObject *object;
164      gpointer user_data;
165 {
166     // todo this toggling of the pause button doesn't seem to work?
167     // e.g. select pause from buttonbar doesn't activate menumode.pause
168   //  fprintf(stderr,"DEBUG: in pause\n");
169   //  fflush(stderr);
170   PauseEvent();
171 }
172
173
174 void LoadGameProc(object, user_data)
175      GtkObject *object;
176      gpointer user_data;
177 {
178   GtkWidget *dialog;
179   dialog = gtk_file_chooser_dialog_new (_("Load game file name?"),
180                                         GTK_WINDOW(GUI_Window),
181                                         GTK_FILE_CHOOSER_ACTION_OPEN,
182                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
183                                         GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
184                                         NULL);
185   if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
186     {
187       char *filename;
188       FILE *f;
189
190       filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
191
192       //see loadgamepopup
193       f = fopen(filename, "rb");
194       if (f == NULL) {
195         DisplayError(_("Failed to open file"), errno);
196       } else {
197         /* TODO add indec */
198         (void) LoadGamePopUp(f, 0, filename);
199       }
200       g_free (filename);
201     }
202   gtk_widget_destroy (dialog);
203   ModeHighlight();
204 }
205
206
207 /*************
208  * EVENTS
209  *************/
210
211 void EventProc(window, event, data)
212      GtkWindow *window;
213      GdkEvent *event;
214      gpointer data;
215 {
216   /* todo do we still need this? 
217     if (!XtIsRealized(widget))
218       return;
219   */
220   
221     switch (event->type) {
222       case GDK_EXPOSE:
223         if (event->expose.count > 0) return;  /* no clipping is done */
224         DrawPosition(True, NULL);
225         break;
226       default:
227         return;
228     }
229 }
230
231
232 /*
233  * event handler for parsing user moves
234  */
235 void UserMoveProc(window, event, data)
236      GtkWindow *window;
237      GdkEvent *event;
238      gpointer data;
239 {
240     int x, y;
241     Boolean saveAnimate;
242     static int second = 0;
243
244     if (errorExitStatus != -1) return;
245
246     if (event->type == GDK_BUTTON_PRESS) ErrorPopDown();
247
248     if (promotionUp) {
249         if (event->type == GDK_BUTTON_PRESS) {
250           /* todo add promotionshellwidget
251             XtPopdown(promotionShell);
252             XtDestroyWidget(promotionShell); */
253             promotionUp = False;
254             ClearHighlights();
255             fromX = fromY = -1;
256         } else {
257             return;
258         }
259     }
260     
261     x = EventToSquare((int)event->button.x, BOARD_WIDTH);
262     y = EventToSquare((int)event->button.y, BOARD_HEIGHT);
263     if (!flipView && y >= 0) {
264         y = BOARD_HEIGHT - 1 - y;
265     }
266     if (flipView && x >= 0) {
267         x = BOARD_WIDTH - 1 - x;
268     }
269     printf("DEBUG::UserMoveProc: x %d y %d\n",x,y);
270     
271     if (fromX == -1) {
272         if (event->type == ButtonPress) {
273             /* First square */
274             if (OKToStartUserMove(x, y)) {
275                 fromX = x;
276                 fromY = y;
277                 second = 0;
278     printf("DEBUG::UserMoveProc: a\n");
279                 DragPieceBegin(event->button.x, event->button.y);
280                 if (appData.highlightDragging) {
281                     SetHighlights(x, y, -1, -1);
282                 }
283             }
284         }
285         return;
286     }
287
288     /* fromX != -1 */
289     if (event->type == GDK_BUTTON_PRESS && gameMode != EditPosition &&
290         x >= 0 && y >= 0) {
291         ChessSquare fromP;
292         ChessSquare toP;
293         /* Check if clicking again on the same color piece */
294         fromP = boards[currentMove][fromY][fromX];
295         toP = boards[currentMove][y][x];
296     printf("DEBUG::UserMoveProc: b\n");
297         if ((WhitePawn <= fromP && fromP <= WhiteKing &&
298              WhitePawn <= toP && toP <= WhiteKing) ||
299             (BlackPawn <= fromP && fromP <= BlackKing &&
300              BlackPawn <= toP && toP <= BlackKing)) {
301             /* Clicked again on same color piece -- changed his mind */
302             second = (x == fromX && y == fromY);
303             if (appData.highlightDragging) {
304                 SetHighlights(x, y, -1, -1);
305             } else {
306                 ClearHighlights();
307             }
308             if (OKToStartUserMove(x, y)) {
309                 fromX = x;
310                 fromY = y;
311                 DragPieceBegin(event->button.x, event->button.y);
312             }
313             return;
314         }
315     }
316
317     if (event->type == GDK_BUTTON_RELEASE &&    x == fromX && y == fromY) {
318     printf("DEBUG::UserMoveProc: c\n");
319         DragPieceEnd(event->button.x, event->button.y);
320         if (appData.animateDragging) {
321             /* Undo animation damage if any */
322             DrawPosition(FALSE, NULL);
323         }
324         if (second) {
325             /* Second up/down in same square; just abort move */
326             second = 0;
327             fromX = fromY = -1;
328             ClearHighlights();
329             gotPremove = 0;
330             ClearPremoveHighlights();
331         } else {
332             /* First upclick in same square; start click-click mode */
333             SetHighlights(x, y, -1, -1);
334         }
335         return;
336     }
337
338     /* Completed move */
339     toX = x;
340     toY = y;
341     saveAnimate = appData.animate;
342     printf("DEBUG::UserMoveProc: d\n");
343     if (event->type == GDK_BUTTON_PRESS) {
344     printf("DEBUG::UserMoveProc: e\n");
345         /* Finish clickclick move */
346         if (appData.animate || appData.highlightLastMove) {
347             SetHighlights(fromX, fromY, toX, toY);
348         } else {
349             ClearHighlights();
350         }
351     } else {
352         /* Finish drag move */
353         if (appData.highlightLastMove) {
354             SetHighlights(fromX, fromY, toX, toY);
355         } else {
356             ClearHighlights();
357         }
358         DragPieceEnd(event->button.x, event->button.y);
359         /* Don't animate move and drag both */
360         appData.animate = FALSE;
361     }
362     printf("DEBUG::UserMoveProc: f\n");
363     if (IsPromotion(fromX, fromY, toX, toY)) {
364     printf("DEBUG::UserMoveProc: f1\n");
365         if (appData.alwaysPromoteToQueen) {
366             UserMoveEvent(fromX, fromY, toX, toY, 'q');
367             if (!appData.highlightLastMove || gotPremove) ClearHighlights();
368             if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
369             fromX = fromY = -1;
370         } else {
371             SetHighlights(fromX, fromY, toX, toY);
372             PromotionPopUp();
373         }
374     } else {
375     printf("DEBUG::UserMoveProc: f2\n");
376     
377         UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);
378     printf("DEBUG::UserMoveProc: f3\n");
379         if (!appData.highlightLastMove || gotPremove) ClearHighlights();
380         if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
381         fromX = fromY = -1;
382     }
383     appData.animate = saveAnimate;
384     printf("DEBUG::UserMoveProc: g\n");
385     if (appData.animate || appData.animateDragging) {
386         /* Undo animation damage if needed */
387         DrawPosition(FALSE, NULL);
388     }
389 }