commit some X-stuff out for the gtk-version, still need to adapt to GTK
[xboard.git] / xpromo.c
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 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 <X11/Intrinsic.h>
53 #include <X11/StringDefs.h>
54 #include <X11/Shell.h>
55 #include <X11/Xaw/Dialog.h>
56 #include <X11/Xaw/Form.h>
57 #include <X11/Xaw/List.h>
58 #include <X11/Xaw/Label.h>
59 #include <X11/Xaw/SimpleMenu.h>
60 #include <X11/Xaw/SmeBSB.h>
61 #include <X11/Xaw/SmeLine.h>
62 #include <X11/Xaw/Box.h>
63 #include <X11/Xaw/Paned.h>
64 #include <X11/Xaw/MenuButton.h>
65 #include <X11/cursorfont.h>
66 #include <X11/Xaw/Text.h>
67 #include <X11/Xaw/AsciiText.h>
68 #include <X11/Xaw/Viewport.h>
69
70 #include "common.h"
71 #include "frontend.h"
72 #include "backend.h"
73 #include "xboard.h"
74 #include "evalgraph.h"
75 #include "gettext.h"
76
77 #ifdef ENABLE_NLS
78 # define  _(s) gettext (s)
79 # define N_(s) gettext_noop (s)
80 #else
81 # define  _(s) (s)
82 # define N_(s)  s
83 #endif
84
85 #include <X11/xpm.h>
86
87 // [HGM] pixmaps of some ICONS used in the engine-outut window
88 #include "pixmaps/WHITE_14.xpm"
89 #include "pixmaps/BLACK_14.xpm"
90 #include "pixmaps/CLEAR_14.xpm"
91 #include "pixmaps/UNKNOWN_14.xpm"
92 #include "pixmaps/THINKING_14.xpm"
93 #include "pixmaps/PONDER_14.xpm"
94 #include "pixmaps/ANALYZING_14.xpm"
95
96 #ifdef SNAP
97 #include "wsnap.h"
98 #endif
99
100 #define _LL_ 100
101
102 typedef void (*DrawFunc)();
103 DrawFunc ChooseDrawFunc();
104
105 // imports from xboard.c
106 extern Widget formWidget, shellWidget, boardWidget, menuBarWidget;
107 extern Display *xDisplay;
108 extern Window xBoardWindow;
109 extern int squareSize;
110 extern Pixmap xMarkPixmap, wIconPixmap, bIconPixmap;
111 extern char *layoutName;
112 extern int lineGap;
113
114 Pixmap icons[8]; // [HGM] this front-end array translates back-end icon indicator to handle
115 Widget outputField[2][7]; // [HGM] front-end array to translate output field to window handle
116
117 /* Imports from backend.c */
118
119 /* Imports from xboard.c */
120 extern Arg layoutArgs[2], formArgs[2], messageArgs[4];
121 extern GC coordGC;
122
123 //extern WindowPlacement wpEvalGraph;
124
125 /* Module variables */
126
127 static Display *zDisplay;
128 static Window promoWindow;
129 static int nrow, ncol;
130 extern Board promoBoard;
131
132 static GC blackBrush;
133
134 Widget promoShell;
135
136 void PromoPopDown()
137 {
138   return;
139   //  TODO
140   
141     if (!promoShell) return;
142     XtPopdown(promoShell);
143     XtDestroyWidget(promoShell);
144     promoShell = NULL;
145 }
146
147 // front-end
148 static Pixel MakeColor(char *color )
149 {
150     XrmValue vFrom, vTo;
151
152     vFrom.addr = (caddr_t) color;
153     vFrom.size = strlen(color);
154     XtConvert(promoShell, XtRString, &vFrom, XtRPixel, &vTo);
155     // test for NULL?
156
157     return *(Pixel *) vTo.addr;
158 }
159
160 static GC CreateGC(int width, char *fg, char *bg, int style)
161 {
162     XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
163       | GCBackground | GCFunction | GCPlaneMask;
164     XGCValues gc_values;
165
166     gc_values.plane_mask = AllPlanes;
167     gc_values.line_width = width;
168     gc_values.line_style = style;
169     gc_values.function = GXcopy;
170
171     gc_values.foreground = MakeColor(fg);
172     gc_values.background = MakeColor(bg);
173
174     return XtGetGC(promoShell, value_mask, &gc_values);
175 }
176
177 void DrawPromoSquare(row, column, piece)
178      int row, column;
179      ChessSquare piece;
180 {
181     int square_color, x, y;
182     DrawFunc drawfunc;
183
184     x = lineGap + column * (squareSize + lineGap);
185     y = lineGap + row * (squareSize + lineGap);
186
187     square_color = 1;
188
189     if (piece == EmptySquare) {
190         BlankSquare(x, y, square_color, piece, promoWindow);
191     } else {
192      // drawfunc = ChooseDrawFunc();
193         drawfunc(piece, square_color, x, y, promoWindow);
194     }
195
196 }
197
198 // front-end. Create pens, device context and buffer bitmap for global use, copy result to display
199 // The back-end part n the middle has been taken out and moed to PainEvalGraph()
200 static void DisplayPromoDialog()
201 {
202     int j, r, f;
203     int width;
204     int height;
205     Dimension w, h;
206     Arg args[6];
207
208     /* Get client area */
209     j = 0;
210     XtSetArg(args[j], XtNwidth, &w); j++;
211     XtSetArg(args[j], XtNheight, &h); j++;
212     XtGetValues(promoShell, args, j);
213     width = w;
214     height = h;
215
216     /* Create or recreate paint box if needed */
217     if( width != nWidthPB || height != nHeightPB ) {
218
219         nWidthPB = width;
220         nHeightPB = height;
221     }
222
223     XFillRectangle(zDisplay, promoWindow, blackBrush, 0, 0, w, h);
224     for(r = 0; r<nrow; r++) for(f=0; f<ncol; f++) 
225         DrawPromoSquare(r, f, promoBoard[r][f+BOARD_LEFT]);
226
227     XSync(zDisplay, False);
228 }
229
230 static void InitializePromoDialog()
231 { int i;    XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
232       | GCBackground | GCFunction | GCPlaneMask;
233     XGCValues gc_values;
234
235     blackBrush = CreateGC(3, "#000000", "#000000", LineSolid);
236 }
237
238 void PromoClick(widget, unused, event)
239      Widget widget;
240      caddr_t unused;
241      XEvent *event;
242 {
243     int boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
244     int boardWidth  = lineGap + BOARD_WIDTH  * (squareSize + lineGap);
245     int boardLeft   = BOARD_LEFT  * (squareSize + lineGap);
246     int x = event->xbutton.x;
247     int y = event->xbutton.y;
248
249     // translate click to as if it was on main board near a1
250     if(flipView) x = boardWidth - x; else y = boardHeight - y;
251
252     if( widget) {
253         if(event->type == ButtonPress)   LeftClick(Press,   x + boardLeft, y);
254         if(event->type == ButtonRelease) RightClick(Release, x + boardLeft, y, &y, &y);
255     }
256     PromoPopDown();
257 }
258
259 // This (cloned from EventProc in xboard.c) is needed as event handler, to prevent
260 // the graph being wiped out after covering / uncovering by other windows.
261 void PromoEventProc(widget, unused, event)
262      Widget widget;
263      caddr_t unused;
264      XEvent *event;
265 {
266     if (!XtIsRealized(widget))
267       return;
268
269     switch (event->type) {
270       case Expose:
271         if (event->xexpose.count > 0) return;  /* no clipping is done */
272         DisplayPromoDialog();
273         break;
274       default:
275         return;
276     }
277 }
278
279 void PromoCallback(w, client_data, call_data)
280      Widget w;
281      XtPointer client_data, call_data;
282 {
283     String name;
284     Widget w2;
285     Arg args[16];
286     char buf[80];
287     VariantClass v;
288     
289     XtSetArg(args[0], XtNlabel, &name);
290     XtGetValues(w, args, 1);
291     
292     if (strcmp(name, _("clear board")) == 0) {
293         EditPositionMenuEvent(ClearBoard, 0, 0);
294     } else
295     if (strcmp(name, _("grant rights")) == 0) {
296         EditPositionMenuEvent(GrantRights, fromX, fromY);
297     } else
298     if (strcmp(name, _("revoke rights")) == 0) {
299         EditPositionMenuEvent(NoRights, fromX, fromY);
300     }
301     PromoPopDown();
302 }
303
304 Widget PromoCreate(name, x, y, clear)
305      char *name;
306      int x, y;
307      Boolean clear;
308 {
309   return;
310   //  TODO
311
312     Arg args[16];
313     Widget shell, layout, form, panel, b_clear, b_grant, b_revoke;
314     int j, h, w;
315
316     // define form within layout within shell.
317     j = 0;
318     XtSetArg(args[j], XtNresizable, True);  j++;
319     shell =
320       XtCreatePopupShell(name, transientShellWidgetClass,
321                          shellWidget, args, j);
322     layout =
323       XtCreateManagedWidget(layoutName, formWidgetClass, shell,
324                             layoutArgs, XtNumber(layoutArgs));
325     form =
326       XtCreateManagedWidget("form", formWidgetClass, layout,
327                             formArgs, XtNumber(formArgs));
328     panel =
329       XtCreateManagedWidget("panel", formWidgetClass, form,
330                             formArgs, XtNumber(formArgs));
331     // make sure width is known in advance, for better placement of child widgets
332     j = 0;
333     XtSetArg(args[j], XtNwidth,  (XtArgVal) (w = ncol*squareSize + (ncol+1)*lineGap)); j++;
334     XtSetArg(args[j], XtNheight, (XtArgVal) (h = nrow*squareSize + (nrow+1)*lineGap)); j++;
335     XtSetValues(panel, args, j);
336
337     if(clear) { // piece menu: add buttons
338         j=0;
339         XtSetArg(args[j], XtNfromVert, panel);  j++;
340         b_clear = XtCreateManagedWidget(_("clear board"), commandWidgetClass, form, args, j);
341         XtAddCallback(b_clear, XtNcallback, PromoCallback, (XtPointer) 0);
342
343         j=0;
344         XtSetArg(args[j], XtNfromHoriz, b_clear);  j++;
345         XtSetArg(args[j], XtNfromVert, panel);  j++;
346         b_grant = XtCreateManagedWidget(_("grant rights"), commandWidgetClass, form, args, j);
347         XtAddCallback(b_grant, XtNcallback, PromoCallback, (XtPointer) 0);
348
349         j=0;
350         XtSetArg(args[j], XtNfromHoriz, b_grant);  j++;
351         XtSetArg(args[j], XtNfromVert, panel);  j++;
352         b_revoke = XtCreateManagedWidget(_("revoke rights"), commandWidgetClass, form, args, j);
353         XtAddCallback(b_revoke, XtNcallback, PromoCallback, (XtPointer) 0);
354     }
355
356     if(y >= 0) {
357         Dimension bx, by;
358         if(y > h) y -= h - 5; else y += 60;
359         x -= w/2; if(x<10) x = 10;
360         j = 0;
361         XtSetArg(args[j], XtNx, &bx); j++;
362         XtSetArg(args[j], XtNy, &by); j++;
363         XtGetValues(boardWidget, args, j);
364         j = 0;
365         XtSetArg(args[j], XtNx, (XtArgVal) x+bx); j++;
366         XtSetArg(args[j], XtNy, (XtArgVal) y+by); j++;
367         XtSetValues(shell, args, j);
368     }
369
370     XtRealizeWidget(shell);
371
372     zDisplay = XtDisplay(shell);
373     promoWindow = XtWindow(panel);
374     XtAddEventHandler(panel, ExposureMask, False,
375                       (XtEventHandler) PromoEventProc, NULL);
376     XtAddEventHandler(panel, ButtonPressMask|ButtonReleaseMask, False,
377                       (XtEventHandler) PromoClick, NULL);
378
379     return shell;
380 }
381
382 void 
383 PromoDialog(int h, int w, Board b, Boolean clear, char *title, int x, int y)
384 {
385     Arg args[16];
386     int j;
387     Widget edit;
388     static int  needInit = TRUE;
389
390     nrow = h; ncol = w;
391
392     if (promoShell == NULL) {
393
394         promoShell =
395           PromoCreate(title, x, y, clear);
396         XtRealizeWidget(promoShell);
397         //      CatchDeleteWindow(promoShell, "PromoPopDown");
398         InitializePromoDialog();
399     }
400
401     XtPopup(promoShell, XtGrabExclusive);
402     XSync(zDisplay, False);
403 //    DisplayPromoDialog();
404 }
405