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