1 /*
2  * Evaluation graph
3  *
4  * Author: Alessandro Scotti (Dec 2005)
5  * Translated to X by H.G.Muller (Nov 2009)
6  *
7  * Copyright 2005 Alessandro Scotti
8  *
9  * Enhancements Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015 Free Software Foundation, Inc.
10  *
11  * ------------------------------------------------------------------------
12  *
13  * GNU XBoard is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation, either version 3 of the License, or (at
16  * your option) any later version.
17  *
18  * GNU XBoard is distributed in the hope that it will be useful, but
19  * WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  * General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program. If not, see http://www.gnu.org/licenses/.
25  *
26  * ------------------------------------------------------------------------
27  ** See the file ChangeLog for a revision history.  */
28 
29 #include "config.h"
30 
31 #include <stdio.h>
32 #include <ctype.h>
33 #include <errno.h>
34 #include <sys/types.h>
35 
36 #if STDC_HEADERS
37 # include <stdlib.h>
38 # include <string.h>
39 #else /* not STDC_HEADERS */
40 extern char *getenv();
41 # if HAVE_STRING_H
42 #  include <string.h>
43 # else /* not HAVE_STRING_H */
44 #  include <strings.h>
45 # endif /* not HAVE_STRING_H */
46 #endif /* not STDC_HEADERS */
47 
48 #if HAVE_UNISTD_H
49 # include <unistd.h>
50 #endif
51 
52 #include "common.h"
53 #include "backend.h"
54 #include "dialogs.h"
55 #include "menus.h"
56 #include "evalgraph.h"
57 #include "draw.h"
58 #include "gettext.h"
59 
60 #ifdef ENABLE_NLS
61 # define  _(s) gettext (s)
62 # define N_(s) gettext_noop (s)
63 #else
64 # define  _(s) (s)
65 # define N_(s)  s
66 #endif
67 
68 static char *title[2] = { N_("Evaluation graph"), N_("Blunder graph") };
69 Option *disp;
70 
71 /* Module variables */
72 
73 static Option *EvalCallback P((int button, int x, int y));
74 
75 static int initDone = FALSE;
76 
77 static void
InitializeEvalGraph(Option * opt,int w,int h)78 InitializeEvalGraph (Option *opt, int w, int h)
79 {
80   nWidthPB = w, nHeightPB = h;
81 
82   initDone = TRUE;
83 }
84 
85 // The following stuff is really back-end (but too little to bother with a separate file)
86 
87 static void
EvalClick(int x,int y)88 EvalClick (int x, int y)
89 {
90     int index = GetMoveIndexFromPoint( x, y );
91 
92     if( index >= 0 && index < currLast ) ToNrEvent( index + 1 );
93 }
94 
95 static Option graphOptions[] = {
96 { 150, 0x9C, 300, NULL, (void*) &EvalCallback, NULL, NULL, Graph , "" },
97 { 0, 2, 0, NULL, NULL, "", NULL, EndMark , "" }
98 };
99 
100 static void
DisplayEvalGraph()101 DisplayEvalGraph ()
102 {   // back-end painting; calls back front-end primitives for lines, rectangles and text
103     char *t = MakeEvalTitle(_(title[differentialView]));
104     nWidthPB = disp->max; nHeightPB = disp->value;
105     if(t != title[differentialView] && nWidthPB < 340)
106 	t = MakeEvalTitle(nWidthPB < 240 ? "" : differentialView ? _("Blunder") : _("Eval"));
107     PaintEvalGraph();
108     GraphExpose(graphOptions, 0, 0, nWidthPB, nHeightPB);
109     SetDialogTitle(EvalGraphDlg, t);
110 }
111 
112 static Option *
EvalCallback(int button,int x,int y)113 EvalCallback (int button, int x, int y)
114 {
115     int dir = appData.zoom + 1;
116     if(!initDone) return NULL;
117 
118     switch(button) {
119 	case 3: dir = 0; differentialView = !differentialView;
120 	case 4: dir -= 2;
121 	case 5: if(dir > 0) appData.zoom = dir;
122 	case 10: // expose event
123 	    /* Create or recreate paint box if needed */
124 	    if(x != nWidthPB || y != nHeightPB) {
125 		InitializeEvalGraph(&graphOptions[0], x, y);
126 	    }
127 	    nWidthPB = x;
128 	    nHeightPB = y;
129 	    DisplayEvalGraph();
130 	    break;
131 	case 1: EvalClick(x, y); // left button
132 	default: break; // other buttons ignored
133     }
134     return NULL; // no context menu!
135 }
136 
137 void
EvalGraphPopUp()138 EvalGraphPopUp ()
139 {
140     if (GenericPopUp(graphOptions, _(title[differentialView]), EvalGraphDlg, BoardWindow, NONMODAL, appData.topLevel)) {
141 	InitializeEvalGraph(&graphOptions[0], wpEvalGraph.width, wpEvalGraph.height); // first time: add callbacks and initialize pens
142 	disp = graphOptions;
143     } else {
144 	SetDialogTitle(EvalGraphDlg, _(title[differentialView]));
145 	SetIconName(EvalGraphDlg, _(title[differentialView]));
146     }
147 
148     MarkMenu("View.EvaluationGraph", EvalGraphDlg);
149 
150 //    ShowThinkingEvent(); // [HGM] thinking: might need to prompt engine for thinking output
151 }
152 
153 void
EvalGraphPopDown()154 EvalGraphPopDown ()
155 {
156     PopDown(EvalGraphDlg);
157 
158 //    ShowThinkingEvent(); // [HGM] thinking: might need to shut off thinking output
159 }
160 
161 Boolean
EvalGraphIsUp()162 EvalGraphIsUp ()
163 {
164     return shellUp[EvalGraphDlg];
165 }
166 
167 int
EvalGraphDialogExists()168 EvalGraphDialogExists ()
169 {
170     return DialogExists(EvalGraphDlg);
171 }
172 
173 void
EvalGraphProc()174 EvalGraphProc ()
175 {
176   if (!PopDown(EvalGraphDlg)) EvalGraphPopUp();
177 }
178 
179 // This function is the interface to the back-end.
180 
181 void
EvalGraphSet(int first,int last,int current,ChessProgramStats_Move * pvInfo)182 EvalGraphSet (int first, int last, int current, ChessProgramStats_Move * pvInfo)
183 {
184     /* [AS] Danger! For now we rely on the pvInfo parameter being a static variable! */
185 
186     currFirst = first;
187     currLast = last;
188     currCurrent = current;
189     currPvInfo = pvInfo;
190 
191     if( DialogExists(EvalGraphDlg) ) {
192         DisplayEvalGraph();
193     }
194 }
195