Fix multi-leg promotions
[xboard.git] / gtk / xtimer.c
1 /*
2  * xtimer.c -- timing functions for X front end of XBoard
3  *
4  * Copyright 1991 by Digital Equipment Corporation, Maynard,
5  * Massachusetts.
6  *
7  * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
8  * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free
9  * Software Foundation, Inc.
10  *
11  * The following terms apply to Digital Equipment Corporation's copyright
12  * interest in XBoard:
13  * ------------------------------------------------------------------------
14  * All Rights Reserved
15  *
16  * Permission to use, copy, modify, and distribute this software and its
17  * documentation for any purpose and without fee is hereby granted,
18  * provided that the above copyright notice appear in all copies and that
19  * both that copyright notice and this permission notice appear in
20  * supporting documentation, and that the name of Digital not be
21  * used in advertising or publicity pertaining to distribution of the
22  * software without specific, written prior permission.
23  *
24  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
26  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
27  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
28  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
29  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
30  * SOFTWARE.
31  * ------------------------------------------------------------------------
32  *
33  * The following terms apply to the enhanced version of XBoard
34  * distributed by the Free Software Foundation:
35  * ------------------------------------------------------------------------
36  *
37  * GNU XBoard is free software: you can redistribute it and/or modify
38  * it under the terms of the GNU General Public License as published by
39  * the Free Software Foundation, either version 3 of the License, or (at
40  * your option) any later version.
41  *
42  * GNU XBoard is distributed in the hope that it will be useful, but
43  * WITHOUT ANY WARRANTY; without even the implied warranty of
44  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
45  * General Public License for more details.
46  *
47  * You should have received a copy of the GNU General Public License
48  * along with this program. If not, see http://www.gnu.org/licenses/.  *
49  *
50  *------------------------------------------------------------------------
51  ** See the file ChangeLog for a revision history.  */
52
53 #define HIGHDRAG 1
54
55 #include "config.h"
56
57 #include <stdio.h>
58 #include <signal.h>
59 #include <sys/types.h>
60
61 #include <gtk/gtk.h>
62
63 #if STDC_HEADERS
64 # include <stdlib.h>
65 # include <string.h>
66 #else /* not STDC_HEADERS */
67 extern char *getenv();
68 # if HAVE_STRING_H
69 #  include <string.h>
70 # else /* not HAVE_STRING_H */
71 #  include <strings.h>
72 # endif /* not HAVE_STRING_H */
73 #endif /* not STDC_HEADERS */
74
75 #if HAVE_SYS_SYSTEMINFO_H
76 # include <sys/systeminfo.h>
77 #endif /* HAVE_SYS_SYSTEMINFO_H */
78
79 #if TIME_WITH_SYS_TIME
80 # include <sys/time.h>
81 # include <time.h>
82 #else
83 # if HAVE_SYS_TIME_H
84 #  include <sys/time.h>
85 # else
86 #  include <time.h>
87 # endif
88 #endif
89
90 #if HAVE_UNISTD_H
91 # include <unistd.h>
92 #endif
93
94 #if HAVE_SYS_WAIT_H
95 # include <sys/wait.h>
96 #endif
97
98 #include "common.h"
99 #include "backend.h"
100 #include "frontend.h"
101
102 #ifdef __EMX__
103 #ifndef HAVE_USLEEP
104 #define HAVE_USLEEP
105 #endif
106 #define usleep(t)   _sleep2(((t)+500)/1000)
107 #endif
108
109 guint delayedEventTimerTag = 0;
110 DelayedEventCallback delayedEventCallback = 0;
111
112 void
113 FireDelayedEvent(gpointer data)
114 {
115     g_source_remove(delayedEventTimerTag);
116     delayedEventTimerTag = 0;
117     delayedEventCallback();
118 }
119
120 void
121 ScheduleDelayedEvent (DelayedEventCallback cb, long millisec)
122 {
123     if(delayedEventTimerTag && delayedEventCallback == cb)
124         // [HGM] alive: replace, rather than add or flush identical event
125         g_source_remove(delayedEventTimerTag);
126     delayedEventCallback = cb;
127     delayedEventCallback = cb;
128     delayedEventTimerTag = g_timeout_add(millisec,(GSourceFunc) FireDelayedEvent, NULL);
129 }
130
131 DelayedEventCallback
132 GetDelayedEvent ()
133 {
134   if (delayedEventTimerTag) {
135     return delayedEventCallback;
136   } else {
137     return NULL;
138   }
139 }
140
141 void
142 CancelDelayedEvent ()
143 {
144   if (delayedEventTimerTag) {
145     g_source_remove(delayedEventTimerTag);
146     delayedEventTimerTag = 0;
147   }
148 }
149
150
151 guint loadGameTimerTag = 0;
152
153 int LoadGameTimerRunning()
154 {
155     return loadGameTimerTag != 0;
156 }
157
158 int
159 StopLoadGameTimer ()
160 {
161     if (loadGameTimerTag != 0) {
162         g_source_remove(loadGameTimerTag);
163         loadGameTimerTag = 0;
164         return TRUE;
165     } else {
166         return FALSE;
167     }
168 }
169
170 void
171 LoadGameTimerCallback(gpointer data)
172 {
173     g_source_remove(loadGameTimerTag);
174     loadGameTimerTag = 0;
175     AutoPlayGameLoop();
176 }
177
178 void
179 StartLoadGameTimer (long millisec)
180 {
181     loadGameTimerTag =
182         g_timeout_add( millisec, (GSourceFunc) LoadGameTimerCallback, NULL);
183 }
184
185 guint analysisClockTag = 0;
186
187 int
188 AnalysisClockCallback(gpointer data)
189 {
190     if (gameMode == AnalyzeMode || gameMode == AnalyzeFile
191          || appData.icsEngineAnalyze) { // [DM]
192         AnalysisPeriodicEvent(0);
193     }
194     return 1;
195 }
196
197 void
198 StartAnalysisClock ()
199 {
200     analysisClockTag =
201         g_timeout_add( 2000,(GSourceFunc) AnalysisClockCallback, NULL);
202 }
203
204 guint clockTimerTag = 0;
205
206 int
207 ClockTimerRunning ()
208 {
209     return clockTimerTag != 0;
210 }
211
212 int
213 StopClockTimer ()
214 {
215     if (clockTimerTag != 0)
216     {
217         g_source_remove(clockTimerTag);
218         clockTimerTag = 0;
219         return TRUE;
220     } else {
221         return FALSE;
222     }
223 }
224
225 void
226 ClockTimerCallback(gpointer data)
227 {
228     /* remove timer */
229     g_source_remove(clockTimerTag);
230     clockTimerTag = 0;
231
232     DecrementClocks();
233 }
234
235 void
236 StartClockTimer (long millisec)
237 {
238     clockTimerTag = g_timeout_add(millisec,(GSourceFunc) ClockTimerCallback,NULL);
239 }