first version of xedittags in gtk.
[xboard.git] / callback.c
1 #include <gtk/gtk.h>
2 #include "common.h"
3 #include "xboard.h"
4 #include <errno.h>
5 #include "backend.h"
6
7 #ifdef ENABLE_NLS
8 # define  _(s) gettext (s)
9 # define N_(s) gettext_noop (s)
10 #else
11 # define  _(s) (s)
12 # define N_(s)  s
13 #endif
14
15 extern GtkWidget  *about;
16 extern GtkWidget  *GUI_Window;
17 extern GtkWidget  *GUI_Aspect;
18 extern GtkWidget  *GUI_Menubar;
19 extern GtkWidget  *GUI_Timer;
20 extern GtkWidget  *GUI_Buttonbar;
21 extern GtkWidget  *GUI_Board;
22
23 extern char *programVersion;
24 extern int errorExitStatus;
25 extern int promotionUp;
26 extern int fromX;
27 extern int fromY;
28 extern int toX;
29 extern int toY;
30 extern int squareSize,lineGap;
31
32 extern int LoadGamePopUp P((FILE *f, int gameNumber, char *title));
33 extern int LoadPosition P((FILE *f, int gameNumber, char *title));
34 extern int SaveGame P((FILE *f, int gameNumber, char *title));
35 extern int SavePosition P((FILE *f, int gameNumber, char *title));
36
37 gboolean
38 ExposeProc(object, user_data)
39      GtkObject *object;
40      gpointer user_data;
41 {
42   /* do resizing to a fixed aspect ratio */
43   GtkRequisition w;
44   int totalh=0,nw,nh;
45   float ratio;
46   int boardWidth,boardHeight,old,new;
47
48   nw=GTK_WIDGET(object)->allocation.width;
49   nh=GTK_WIDGET(object)->allocation.height;
50
51   old=squareSize;
52   squareSize  = nw/(BOARD_WIDTH*1.05+0.05);
53
54   if(old!=squareSize)
55     {
56       lineGap = squareSize*0.05;
57
58       boardWidth  = lineGap + BOARD_WIDTH  * (squareSize + lineGap);
59       boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
60
61       /* get the height of the menus, etc. and calculate the aspect ratio */
62       gtk_widget_size_request(GTK_WIDGET(GUI_Menubar),   &w);
63       totalh += w.height;
64       gtk_widget_size_request(GTK_WIDGET(GUI_Timer),   &w);
65       totalh += w.height;
66       gtk_widget_size_request(GTK_WIDGET(GUI_Buttonbar),   &w);
67       totalh += w.height;
68
69       ratio  = ((float)totalh+boardHeight)/((float)boardWidth) ;
70
71       gtk_widget_set_size_request(GTK_WIDGET(GUI_Board),
72                                   boardWidth,boardHeight);
73
74       gtk_aspect_frame_set (GTK_ASPECT_FRAME(GUI_Aspect),0,0,ratio,TRUE);
75
76       /* recreate pieces with new size... TODO: keep svg in memory and just recreate pixmap instead of reloading files */
77       CreatePieces();
78     }
79   return FALSE; /* return false, so that other expose events are called too */
80 }
81
82 void
83 QuitProc (object, user_data)
84      GtkObject *object;
85      gpointer user_data;
86 {
87   gtk_main_quit();
88   ExitEvent(0);
89 }
90
91 /* Help Menu */
92 void InfoProc(object, user_data)
93      GtkObject *object;
94      gpointer user_data;
95 {
96     char buf[MSG_SIZ];
97     snprintf(buf, sizeof(buf), "xterm -e info --directory %s --directory . -f %s &",
98             INFODIR, INFOFILE);
99     system(buf);
100     return;
101 }
102
103 void ManProc(object, user_data)
104      GtkObject *object;
105      gpointer user_data;
106 {
107     char buf[MSG_SIZ];
108     snprintf(buf, sizeof(buf), "xterm -e man xboard &");
109     system(buf);
110     return;
111 }
112
113 void HintProc(object, user_data)
114      GtkObject *object;
115      gpointer user_data;
116 {
117     HintEvent();
118     return;
119 }
120
121 void BookProc(object, user_data)
122      GtkObject *object;
123      gpointer user_data;
124 {
125     BookEvent();
126     return;
127 }
128
129 void AboutProc (object, user_data)
130      GtkObject *object;
131      gpointer user_data;
132 {
133   GtkWidget               *about;
134
135   const gchar *authors[] = {"Tim Mann <tim@tim-mann.org>",
136                             "John Chanak",
137                             "Evan Welsh <Evan.Welsh@msdw.com>",
138                             "Elmar Bartel <bartel@informatik.tu-muenchen.de>",
139                             "Jochen Wiedmann",
140                             "Frank McIngvale",
141                             "Hugh Fisher <Hugh.Fisher@cs.anu.edu.au>",
142                             "Allessandro Scotti",
143                             "H.G. Muller <h.g.muller AT hccnet DOT nl>",
144                             "Eric Mullins <emwine AT earthlink DOT net>",
145                             "Arun Persaud <arun@nubati.net>"};
146
147   /* set up about window */
148   about =  GTK_WIDGET(gtk_about_dialog_new());
149
150   /* fill in some information */
151   char buf[MSG_SIZ];
152 #if ZIPPY
153   char *zippy = " (with Zippy code)";
154 #else
155   char *zippy = "";
156 #endif
157   sprintf(buf, "%s%s",  programVersion, zippy);
158
159   gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),buf);
160
161   gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about),
162                                  "Copyright 1991 Digital Equipment Corporation\n"
163                                  "Enhancements Copyright 1992-2009 Free Software Foundation\n"
164                                  "Enhancements Copyright 2005 Alessandro Scotti");
165   gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),"http://www.gnu.org/software/xboard/");
166   gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about),authors);
167   gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(about),
168                                           " A. Alper (turkish)\n"
169                                           " A. Persaud (german)\n");
170
171   /* end set up about window */
172   gtk_dialog_run(GTK_DIALOG (about));
173   gtk_widget_destroy(about);
174 }
175
176 /* End Help Menu */
177
178 void IcsClientProc(object, user_data)
179      GtkObject *object;
180      gpointer user_data;
181 {
182     IcsClientEvent();
183     return;
184 }
185
186 /*
187  * File menu
188  */
189
190 void
191 LoadNextGameProc(object, user_data)
192      GtkObject *object;
193      gpointer user_data;
194 {
195     ReloadGame(1);
196     return;
197 }
198
199 void
200 LoadPrevGameProc(object, user_data)
201      GtkObject *object;
202      gpointer user_data;
203 {
204     ReloadGame(-1);
205     return;
206 }
207
208 void
209 ReloadGameProc(object, user_data)
210      GtkObject *object;
211      gpointer user_data;
212 {
213     ReloadGame(0);
214     return;
215 }
216
217 void
218 LoadNextPositionProc(object, user_data)
219      GtkObject *object;
220      gpointer user_data;
221 {
222     ReloadPosition(1);
223     return;
224 }
225
226 void
227 LoadPrevPositionProc(object, user_data)
228      GtkObject *object;
229      gpointer user_data;
230 {
231     ReloadPosition(-1);
232     return;
233 }
234
235 void
236 ReloadPositionProc(object, user_data)
237      GtkObject *object;
238      gpointer user_data;
239 {
240     ReloadPosition(0);
241     return;
242 }
243
244 void
245 LoadPositionProc(object, user_data)
246      GtkObject *object;
247      gpointer user_data;
248 {
249   if (gameMode == AnalyzeMode || gameMode == AnalyzeFile)
250     {
251       Reset(FALSE, TRUE);
252     };
253
254   FileNamePopUp(_("Load position file name?"), "", LoadPosition, "rb");
255   return;
256 }
257
258 void
259 SaveGameProc(object, user_data)
260      GtkObject *object;
261      gpointer user_data;
262 {
263   FileNamePopUp(_("Save game file name?"),
264                 DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"),
265                 SaveGame, "a");
266   return;
267 }
268
269 void
270 SavePositionProc(object, user_data)
271      GtkObject *object;
272      gpointer user_data;
273 {
274   FileNamePopUp(_("Save position file name?"),
275                 DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"),
276                 SavePosition, "a");
277   return;
278 }
279
280 void
281 AnalyzeFileProc(object, user_data)
282      GtkObject *object;
283      gpointer user_data;
284 {
285   if (!first.analysisSupport)
286     {
287       char buf[MSG_SIZ];
288       snprintf(buf, sizeof(buf), _("%s does not support analysis"), first.tidy);
289       DisplayError(buf, 0);
290       return;
291     };
292   Reset(FALSE, TRUE);
293
294   if (!appData.showThinking)
295     ShowThinkingProc(NULL,NULL);
296
297   AnalyzeFileEvent();
298   FileNamePopUp(_("File to analyze"), "", LoadGamePopUp, "rb");
299   AnalysisPeriodicEvent(1);
300   return;
301 }
302
303
304 /* End File Menu */
305
306 void MachineWhiteProc(object, user_data)
307      GtkObject *object;
308      gpointer user_data;
309 {
310     MachineWhiteEvent();
311     return;
312 }
313
314 void MachineBlackProc(object, user_data)
315      GtkObject *object;
316      gpointer user_data;
317 {
318     MachineBlackEvent();
319     return;
320 }
321
322 void TwoMachinesProc(object, user_data)
323      GtkObject *object;
324      gpointer user_data;
325 {
326     TwoMachinesEvent();
327     return;
328 }
329
330 void AcceptProc(object, user_data)
331      GtkObject *object;
332      gpointer user_data;
333 {
334     AcceptEvent();
335     return;
336 }
337
338 void DeclineProc(object, user_data)
339      GtkObject *object;
340      gpointer user_data;
341 {
342     DeclineEvent();
343     return;
344 }
345
346 void RematchProc(object, user_data)
347      GtkObject *object;
348      gpointer user_data;
349 {
350     RematchEvent();
351     return;
352 }
353
354 void CallFlagProc(object, user_data)
355      GtkObject *object;
356      gpointer user_data;
357 {
358     CallFlagEvent();
359     return;
360 }
361
362 void DrawProc(object, user_data)
363      GtkObject *object;
364      gpointer user_data;
365 {
366     DrawEvent();
367     return;
368 }
369
370 void AbortProc(object, user_data)
371      GtkObject *object;
372      gpointer user_data;
373 {
374     AbortEvent();
375     return;
376 }
377
378 void AdjournProc(object, user_data)
379      GtkObject *object;
380      gpointer user_data;
381 {
382     AdjournEvent();
383     return;
384 }
385
386 void ResignProc(object, user_data)
387      GtkObject *object;
388      gpointer user_data;
389 {
390     ResignEvent();
391     return;
392 }
393
394 void StopObservingProc(object, user_data)
395      GtkObject *object;
396      gpointer user_data;
397 {
398     StopObservingEvent();
399     return;
400 }
401
402 void StopExaminingProc(object, user_data)
403      GtkObject *object;
404      gpointer user_data;
405 {
406     StopExaminingEvent();
407     return;
408 }
409
410 void AdjuWhiteProc(object, user_data)
411      GtkObject *object;
412      gpointer user_data;
413 {
414     UserAdjudicationEvent(+1);
415     return;
416 }
417
418 void AdjuBlackProc(object, user_data)
419      GtkObject *object;
420      gpointer user_data;
421 {
422     UserAdjudicationEvent(-1);
423     return;
424 }
425
426 void AdjuDrawProc(object, user_data)
427      GtkObject *object;
428      gpointer user_data;
429 {
430     UserAdjudicationEvent(0);
431     return;
432 }
433
434 void BackwardProc(object, user_data)
435      GtkObject *object;
436      gpointer user_data;
437 {
438     BackwardEvent();
439     return;
440 }
441
442 void ForwardProc(object, user_data)
443      GtkObject *object;
444      gpointer user_data;
445 {
446     ForwardEvent();
447     return;
448 }
449
450 void ToStartProc(object, user_data)
451      GtkObject *object;
452      gpointer user_data;
453 {
454     ToStartEvent();
455     return;
456 }
457
458 void ToEndProc(object, user_data)
459      GtkObject *object;
460      gpointer user_data;
461 {
462     ToEndEvent();
463     return;
464 }
465
466 void RevertProc(object, user_data)
467      GtkObject *object;
468      gpointer user_data;
469 {
470     RevertEvent();
471     return;
472 }
473
474 void TruncateGameProc(object, user_data)
475      GtkObject *object;
476      gpointer user_data;
477 {
478     TruncateGameEvent();
479     return;
480 }
481
482 void MoveNowProc(object, user_data)
483      GtkObject *object;
484      gpointer user_data;
485 {
486     MoveNowEvent();
487     return;
488 }
489
490 void RetractMoveProc(object, user_data)
491      GtkObject *object;
492      gpointer user_data;
493 {
494     RetractMoveEvent();
495     return;
496 }
497
498 /* Option Menu */
499 void 
500 AutocommProc(object, user_data)
501      GtkObject *object;
502      gpointer user_data;
503 {
504     appData.autoComment = !appData.autoComment;
505     return;
506 }
507
508 void 
509 AutoflagProc(object, user_data)
510      GtkObject *object;
511      gpointer user_data;
512 {
513     appData.autoCallFlag = !appData.autoCallFlag;
514     return;
515 }
516
517 void 
518 AutoflipProc(object, user_data)
519      GtkObject *object;
520      gpointer user_data;
521 {
522     appData.autoFlipView = !appData.autoFlipView;
523     return;
524 }
525
526 void 
527 ShowThinkingProc(object, user_data)
528      GtkObject *object;
529      gpointer user_data;
530 {
531     appData.showThinking = !appData.showThinking;
532     ShowThinkingEvent();
533
534     return;
535 }
536
537 void 
538 HideThinkingProc(object, user_data)
539      GtkObject *object;
540      gpointer user_data;
541 {
542     appData.hideThinkingFromHuman = !appData.hideThinkingFromHuman;
543     ShowThinkingEvent();
544
545     return;
546 }
547
548 void 
549 FlipViewProc(object, user_data)
550      GtkObject *object;
551      gpointer user_data;
552 {
553     flipView = !flipView;
554     DrawPosition(True, NULL);
555     return;
556 }
557
558 void 
559 AlwaysQueenProc(object, user_data)
560      GtkObject *object;
561      gpointer user_data;
562 {
563   appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen;
564   return;
565 }
566
567 void 
568 AnimateDraggingProc(object, user_data)
569      GtkObject *object;
570      gpointer user_data;
571 {
572   appData.animateDragging = !appData.animateDragging;
573
574   if (appData.animateDragging) 
575     {
576       // TODO convert to gtk
577       //      CreateAnimVars();
578     };
579
580   return;
581 }
582
583 void 
584 AnimateMovingProc(object, user_data)
585      GtkObject *object;
586      gpointer user_data;
587 {
588   appData.animate = !appData.animate;
589   
590   if (appData.animate) 
591     {
592       // TODO convert to gtk
593       //      CreateAnimVars();
594     };
595
596   return;
597 }
598
599 void 
600 AutobsProc(object, user_data)
601      GtkObject *object;
602      gpointer user_data;
603 {
604   appData.autoObserve = !appData.autoObserve;
605   return;
606 }
607
608 void 
609 AutoraiseProc(object, user_data)
610      GtkObject *object;
611      gpointer user_data;
612 {
613   appData.autoRaiseBoard = !appData.autoRaiseBoard;
614   return;
615 }
616
617 void 
618 AutosaveProc(object, user_data)
619      GtkObject *object;
620      gpointer user_data;
621 {
622   appData.autoSaveGames = !appData.autoSaveGames;
623   return;
624 }
625
626 void 
627 BlindfoldProc(object, user_data)
628      GtkObject *object;
629      gpointer user_data;
630 {
631   appData.blindfold = !appData.blindfold;
632   DrawPosition(True, NULL);
633   return;
634 }
635
636 void 
637 TestLegalityProc(object, user_data)
638      GtkObject *object;
639      gpointer user_data;
640 {
641   appData.testLegality = !appData.testLegality;
642   return;
643 }
644
645 void 
646 FlashMovesProc(object, user_data)
647      GtkObject *object;
648      gpointer user_data;
649 {
650   if (appData.flashCount == 0) 
651     {
652       appData.flashCount = 3;
653     }
654   else 
655     {
656       appData.flashCount = -appData.flashCount;
657     };
658   
659     // TODO: check if this is working correct*/
660     return;
661 }
662
663 #if HIGHDRAG
664 void 
665 HighlightDraggingProc(object, user_data)
666      GtkObject *object;
667      gpointer user_data;
668 {
669   /* TODO: connect to option menu */
670   appData.highlightDragging = !appData.highlightDragging;
671   return;
672 }
673 #endif
674
675 void 
676 HighlightLastMoveProc(object, user_data)
677      GtkObject *object;
678      gpointer user_data;
679 {
680   appData.highlightLastMove = !appData.highlightLastMove;
681   return;
682 }
683
684 void 
685 IcsAlarmProc(object, user_data)
686      GtkObject *object;
687      gpointer user_data;
688 {
689   appData.icsAlarm = !appData.icsAlarm;
690   return;
691 }
692
693 void 
694 MoveSoundProc(object, user_data)
695      GtkObject *object;
696      gpointer user_data;
697 {
698   appData.ringBellAfterMoves = !appData.ringBellAfterMoves;
699   return;
700 }
701
702 void 
703 OldSaveStyleProc(object, user_data)
704      GtkObject *object;
705      gpointer user_data;
706 {
707   appData.oldSaveStyle = !appData.oldSaveStyle;
708   return;
709 }
710
711 void 
712 PeriodicUpdatesProc(object, user_data)
713      GtkObject *object;
714      gpointer user_data;
715 {
716   PeriodicUpdatesEvent(!appData.periodicUpdates);
717   return;
718 }
719
720 /* end option menu */
721
722 gboolean CloseWindowProc(GtkWidget *button)
723 {
724     gtk_widget_destroy(gtk_widget_get_toplevel(button));
725     return TRUE;
726 }
727
728 void
729 ResetProc (object, user_data)
730      GtkObject *object;
731      gpointer user_data;
732 {
733   ResetGameEvent();
734   EngineOutputPopDown();
735 }
736
737 void WhiteClockProc(object, user_data)
738      GtkObject *object;
739      gpointer user_data;
740 {
741     if (gameMode == EditPosition || gameMode == IcsExamining) {
742         SetWhiteToPlayEvent();
743     } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) {
744         CallFlagEvent();
745     }
746 }
747
748 void BlackClockProc(object, user_data)
749      GtkObject *object;
750      gpointer user_data;
751 {
752     if (gameMode == EditPosition || gameMode == IcsExamining) {
753         SetBlackToPlayEvent();
754     } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) {
755         CallFlagEvent();
756     }
757 }
758
759
760 void ShowCoordsProc(object, user_data)
761      GtkObject *object;
762      gpointer user_data;
763 {
764     appData.showCoords = !appData.showCoords;
765
766     DrawPosition(True, NULL);
767 }
768
769 void ErrorPopDownProc(object, user_data)
770      GtkObject *object;
771      gpointer user_data;
772 {
773   gtk_widget_destroy(GTK_WIDGET(object));
774   ErrorPopDown();
775 }
776
777 void PauseProc(object, user_data)
778      GtkObject *object;
779      gpointer user_data;
780 {
781     // todo this toggling of the pause button doesn't seem to work?
782     // e.g. select pause from buttonbar doesn't activate menumode.pause
783   PauseEvent();
784 }
785
786
787 void LoadGameProc(object, user_data)
788      GtkObject *object;
789      gpointer user_data;
790 {
791   FileNamePopUp(_("Load game file name?"),"",LoadGamePopUp,"rb");
792   return;
793 }
794
795
796 /*************
797  * EVENTS
798  *************/
799
800 void EventProc(window, event, data)
801      GtkWindow *window;
802      GdkEvent *event;
803      gpointer data;
804 {
805   /* todo do we still need this?
806     if (!XtIsRealized(widget))
807       return;
808   */
809
810     switch (event->type) {
811       case GDK_EXPOSE:
812         if (event->expose.count > 0) return;  /* no clipping is done */
813         DrawPosition(True, NULL);
814         break;
815       default:
816         return;
817     }
818 }
819
820
821 /*
822  * event handler for parsing user moves
823  */
824 void UserMoveProc(window, event, data)
825      GtkWindow *window;
826      GdkEvent *event;
827      gpointer data;
828 {
829     int x, y;
830     Boolean saveAnimate;
831     static int second = 0;
832
833     if (errorExitStatus != -1) return;
834
835     if (event->type == GDK_BUTTON_PRESS) ErrorPopDown();
836
837     if (promotionUp)
838       {
839         if (event->type == GDK_BUTTON_PRESS)
840           {
841             /* todo add promotionshellwidget
842                XtPopdown(promotionShell);
843                XtDestroyWidget(promotionShell); */
844             promotionUp = False;
845             ClearHighlights();
846             fromX = fromY = -1;
847           }
848         else
849           {
850             return;
851           }
852       }
853
854     x = EventToSquare( (int)event->button.x, BOARD_WIDTH  );
855     y = EventToSquare( (int)event->button.y, BOARD_HEIGHT );
856     if (!flipView && y >= 0)
857       {
858         y = BOARD_HEIGHT - 1 - y;
859       }
860     if (flipView && x >= 0)
861       {
862         x = BOARD_WIDTH - 1 - x;
863       }
864
865     if (fromX == -1)
866       {
867         if (event->type == ButtonPress)
868           {
869             /* First square */
870             if (OKToStartUserMove(x, y))
871               {
872                 fromX = x;
873                 fromY = y;
874                 second = 0;
875                 DragPieceBegin(event->button.x, event->button.y);
876                 if (appData.highlightDragging)
877                   {
878                     SetHighlights(x, y, -1, -1);
879                   }
880               }
881           }
882         return;
883       }
884
885     /* fromX != -1 */
886     if (event->type == GDK_BUTTON_PRESS && gameMode != EditPosition &&
887         x >= 0 && y >= 0) {
888         ChessSquare fromP;
889         ChessSquare toP;
890         /* Check if clicking again on the same color piece */
891         fromP = boards[currentMove][fromY][fromX];
892         toP = boards[currentMove][y][x];
893         if ((WhitePawn <= fromP && fromP <= WhiteKing &&
894              WhitePawn <= toP && toP <= WhiteKing) ||
895             (BlackPawn <= fromP && fromP <= BlackKing &&
896              BlackPawn <= toP && toP <= BlackKing)) {
897             /* Clicked again on same color piece -- changed his mind */
898             second = (x == fromX && y == fromY);
899             if (appData.highlightDragging) {
900                 SetHighlights(x, y, -1, -1);
901             } else {
902                 ClearHighlights();
903             }
904             if (OKToStartUserMove(x, y)) {
905                 fromX = x;
906                 fromY = y;
907                 DragPieceBegin(event->button.x, event->button.y);
908             }
909             return;
910         }
911     }
912
913     if (event->type == GDK_BUTTON_RELEASE &&    x == fromX && y == fromY)
914       {
915         DragPieceEnd(event->button.x, event->button.y);
916         if (appData.animateDragging)
917           {
918             /* Undo animation damage if any */
919             DrawPosition(FALSE, NULL);
920           }
921         if (second)
922           {
923             /* Second up/down in same square; just abort move */
924             second = 0;
925             fromX = fromY = -1;
926             ClearHighlights();
927             gotPremove = 0;
928             ClearPremoveHighlights();
929           }
930         else
931           {
932             /* First upclick in same square; start click-click mode */
933             SetHighlights(x, y, -1, -1);
934           }
935         return;
936       }
937
938     /* Completed move */
939     toX = x;
940     toY = y;
941     saveAnimate = appData.animate;
942
943     if (event->type == GDK_BUTTON_PRESS)
944       {
945         /* Finish clickclick move */
946         if (appData.animate || appData.highlightLastMove)
947           {
948             SetHighlights(fromX, fromY, toX, toY);
949           }
950         else
951           {
952             ClearHighlights();
953           }
954       }
955     else
956       {
957         /* Finish drag move */
958         if (appData.highlightLastMove)
959           {
960             SetHighlights(fromX, fromY, toX, toY);
961           }
962         else
963           {
964             ClearHighlights();
965           }
966         DragPieceEnd(event->button.x, event->button.y);
967         /* Don't animate move and drag both */
968         appData.animate = FALSE;
969       }
970
971     if (IsPromotion(fromX, fromY, toX, toY))
972       {
973         if (appData.alwaysPromoteToQueen)
974           {
975             UserMoveEvent(fromX, fromY, toX, toY, 'q');
976             if (!appData.highlightLastMove || gotPremove) ClearHighlights();
977             if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
978             fromX = fromY = -1;
979           }
980         else
981           {
982             SetHighlights(fromX, fromY, toX, toY);
983             PromotionPopUp();
984           }
985       }
986     else
987       {
988         UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);
989
990         if (!appData.highlightLastMove || gotPremove) ClearHighlights();
991         if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
992         fromX = fromY = -1;
993       }
994
995     appData.animate = saveAnimate;
996     if (appData.animate || appData.animateDragging) {
997         /* Undo animation damage if needed */
998         DrawPosition(FALSE, NULL);
999     }
1000
1001     return;
1002 }
1003
1004 void GetMoveListProc(object, user_data)
1005      GtkObject *object;
1006      gpointer user_data;
1007 {
1008   appData.getMoveList = !appData.getMoveList;
1009
1010   if (appData.getMoveList)
1011     {
1012       GetMoveListEvent();
1013     }
1014
1015   // gets set automatically? if we set it with set_active we end up in an endless loop switching between 0 and 1
1016   //  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (object),(gboolean) appData.getMoveList );
1017
1018   return;
1019 }