1 /*
2  * gtkpanels.c
3  * by Jon Kinsey, 2004
4  *
5  * Panels/window code
6  *
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of version 3 or later of the GNU General Public License as
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * $Id: gtkpanels.c,v 1.88 2018/07/21 09:18:12 plm Exp $
22  */
23 
24 #include "config.h"
25 #include "gtklocdefs.h"
26 
27 #include <stdlib.h>
28 #include <ctype.h>
29 #include "backgammon.h"
30 #include <string.h>
31 #include "gtkboard.h"
32 #include "gtkgame.h"
33 #include "gtktoolbar.h"
34 #include "positionid.h"
35 #if defined(USE_BOARD3D)
36 #include "fun3d.h"
37 #endif
38 
39 static int fDisplayPanels = TRUE;
40 static int fDockPanels = TRUE;
41 
42 #define NUM_CMD_HISTORY 10
43 #define KEY_TAB -247
44 
45 typedef struct _CommandEntryData_T {
46     GtkWidget *pwEntry, *pwHelpText, *cmdEntryCombo;
47     int showHelp;
48     int numHistory;
49     int completing;
50     char *cmdString;
51     char *cmdHistory[NUM_CMD_HISTORY];
52 } CommandEntryData_T;
53 
54 static CommandEntryData_T cedPanel = {
55     NULL, NULL, NULL, 0, 0, 0, NULL,
56     {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
57 };
58 
59 
60 static GtkWidget *game_select_combo = NULL;
61 
62 typedef gboolean(*panelFun) (void);
63 
64 static gboolean DeleteMessage(void);
65 static gboolean DeleteAnalysis(void);
66 static gboolean DeleteAnnotation(void);
67 static gboolean DeleteGame(void);
68 static gboolean DeleteTheoryWindow(void);
69 static gboolean DeleteCommandWindow(void);
70 
71 static gboolean ShowAnnotation(void);
72 static gboolean ShowMessage(void);
73 static gboolean ShowAnalysis(void);
74 static gboolean ShowTheoryWindow(void);
75 static gboolean ShowCommandWindow(void);
76 
77 typedef struct _windowobject {
78     const char *winName;
79     int showing;
80     int docked;
81     int dockable;
82     int undockable;
83     panelFun showFun;
84     panelFun hideFun;
85     GtkWidget *pwWin;
86     windowgeometry wg;
87 } windowobject;
88 
89 /* Set up window and panel details */
90 static windowobject woPanel[NUM_WINDOWS] = {
91     /* main window */
92     {
93      "main",
94      TRUE, FALSE, FALSE, FALSE,
95      NULL, NULL,
96      0,
97      {0, 0, 20, 20, FALSE}
98      },
99     /* game list */
100     {
101      "game",
102      TRUE, TRUE, TRUE, TRUE,
103      ShowGameWindow, DeleteGame,
104      0,
105      {250, 200, 20, 20, FALSE}
106      },
107     /* analysis */
108     {
109      "analysis",
110      TRUE, TRUE, TRUE, TRUE,
111      ShowAnalysis, DeleteAnalysis,
112      0,
113      {0, 400, 20, 20, FALSE}
114      },
115     /* annotation */
116     {
117      "annotation",
118      FALSE, TRUE, TRUE, FALSE,
119      ShowAnnotation, DeleteAnnotation,
120      0,
121      {0, 400, 20, 20, FALSE}
122      },
123     /* hint */
124     {
125      "hint",
126      FALSE, FALSE, FALSE, FALSE,
127      NULL, NULL,
128      0,
129      {0, 450, 20, 20, FALSE}
130      },
131     /* message */
132     {
133      "message",
134      FALSE, TRUE, TRUE, TRUE,
135      ShowMessage, DeleteMessage,
136      0,
137      {0, 500, 20, 20, FALSE}
138      },
139     /* command */
140     {
141      "command",
142      FALSE, TRUE, TRUE, TRUE,
143      ShowCommandWindow, DeleteCommandWindow,
144      0,
145      {0, 0, 20, 20, FALSE}
146      },
147     /* theory */
148     {
149      "theory",
150      FALSE, TRUE, TRUE, TRUE,
151      ShowTheoryWindow, DeleteTheoryWindow,
152      0,
153      {0, 0, 20, 20, FALSE}
154      }
155 };
156 
157 
158 static gboolean
ShowPanel(gnubgwindow window)159 ShowPanel(gnubgwindow window)
160 {
161     setWindowGeometry(window);
162     if (!woPanel[window].docked && gtk_widget_get_window(woPanel[window].pwWin))
163         gdk_window_raise(gtk_widget_get_window(woPanel[window].pwWin));
164 
165     woPanel[window].showing = TRUE;
166     /* Avoid showing before main window */
167     if (gtk_widget_get_realized(pwMain))
168         gtk_widget_show_all(woPanel[window].pwWin);
169 
170     return TRUE;
171 }
172 
173 extern gboolean
ShowGameWindow(void)174 ShowGameWindow(void)
175 {
176     ShowPanel(WINDOW_GAME);
177 #if defined(USE_GTKUIMANAGER)
178     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
179                                                                                  "/MainMenu/ViewMenu/PanelsMenu/GameRecord")),
180                                    TRUE);
181 #else
182     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif,
183                                                                                    "/View/Panels/Game record")), TRUE);
184 #endif
185     return TRUE;
186 }
187 
188 static gboolean
ShowAnnotation(void)189 ShowAnnotation(void)
190 {
191 #if defined(USE_GTKUIMANAGER)
192     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
193                                                                                  "/MainMenu/ViewMenu/PanelsMenu/Commentary")),
194                                    TRUE);
195 #else
196     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif,
197                                                                                    "/View/Panels/Commentary")), TRUE);
198 #endif
199 
200     woPanel[WINDOW_ANNOTATION].showing = TRUE;
201     /* Avoid showing before main window */
202     if (gtk_widget_get_realized(pwMain))
203         gtk_widget_show_all(woPanel[WINDOW_ANNOTATION].pwWin);
204     return TRUE;
205 }
206 
207 static gboolean
ShowMessage(void)208 ShowMessage(void)
209 {
210     ShowPanel(WINDOW_MESSAGE);
211 #if defined(USE_GTKUIMANAGER)
212     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
213                                                                                  "/MainMenu/ViewMenu/PanelsMenu/Message")),
214                                    TRUE);
215 #else
216     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif, "/View/Panels/Message")), TRUE);
217 #endif
218     return TRUE;
219 }
220 
221 static gboolean
ShowAnalysis(void)222 ShowAnalysis(void)
223 {
224     ShowPanel(WINDOW_ANALYSIS);
225 #if defined(USE_GTKUIMANAGER)
226     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
227                                                                                  "/MainMenu/ViewMenu/PanelsMenu/Analysis")),
228                                    TRUE);
229 
230 #else
231     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif,
232                                                                                    "/View/Panels/Analysis")), TRUE);
233 #endif
234     return TRUE;
235 }
236 
237 static gboolean
ShowTheoryWindow(void)238 ShowTheoryWindow(void)
239 {
240     ShowPanel(WINDOW_THEORY);
241 #if defined(USE_GTKUIMANAGER)
242     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
243                                                                                  "/MainMenu/ViewMenu/PanelsMenu/Theory")),
244                                    TRUE);
245 #else
246     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif, "/View/Panels/Theory")), TRUE);
247 #endif
248     return TRUE;
249 }
250 
251 static gboolean
ShowCommandWindow(void)252 ShowCommandWindow(void)
253 {
254     ShowPanel(WINDOW_COMMAND);
255 #if defined(USE_GTKUIMANAGER)
256     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
257                                                                                  "/MainMenu/ViewMenu/PanelsMenu/Command")),
258                                    TRUE);
259 #else
260     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif, "/View/Panels/Command")), TRUE);
261 #endif
262     return TRUE;
263 }
264 
265 static void
CreatePanel(gnubgwindow window,GtkWidget * pWidget,char * winTitle,const char * windowRole)266 CreatePanel(gnubgwindow window, GtkWidget * pWidget, char *winTitle, const char *windowRole)
267 {
268     if (!woPanel[window].docked) {
269         woPanel[window].pwWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
270         gtk_window_set_title(GTK_WINDOW(woPanel[window].pwWin), winTitle);
271         gtk_window_set_role(GTK_WINDOW(woPanel[window].pwWin), windowRole);
272         gtk_window_set_type_hint(GTK_WINDOW(woPanel[window].pwWin), GDK_WINDOW_TYPE_HINT_UTILITY);
273 
274         setWindowGeometry(window);
275         gtk_container_add(GTK_CONTAINER(woPanel[window].pwWin), pWidget);
276         gtk_window_add_accel_group(GTK_WINDOW(woPanel[window].pwWin), pagMain);
277 
278         g_signal_connect(G_OBJECT(woPanel[window].pwWin), "delete_event", G_CALLBACK(woPanel[window].hideFun), NULL);
279     } else
280         woPanel[window].pwWin = pWidget;
281 }
282 
283 static void
CreateMessageWindow(void)284 CreateMessageWindow(void)
285 {
286     GtkWidget *psw;
287 
288     pwMessageText = gtk_text_view_new();
289     gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(pwMessageText), GTK_WRAP_WORD_CHAR);
290     gtk_text_view_set_editable(GTK_TEXT_VIEW(pwMessageText), FALSE);
291     psw = gtk_scrolled_window_new(NULL, NULL);
292     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(psw), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
293     gtk_widget_set_size_request(psw, -1, 150);
294     gtk_container_add(GTK_CONTAINER(psw), pwMessageText);
295     CreatePanel(WINDOW_MESSAGE, psw, _("GNU Backgammon - Messages"), "messages");
296 }
297 
298 static GtkWidget *pwTheoryView = NULL;
299 
300 
301 void
UpdateTheoryData(BoardData * bd,int UpdateType,const TanBoard points)302 UpdateTheoryData(BoardData * bd, int UpdateType, const TanBoard points)
303 {
304     char *pc;
305     GtkTreeIter iter;
306     GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(pwTheoryView)));
307 
308     if (!pwTheoryView)
309         return;
310 
311     if (UpdateType & TT_PIPCOUNT) {
312         if (ms.gs != GAME_NONE) {
313             int diff;
314             unsigned int anPip[2];
315             PipCount(points, anPip);
316 
317             diff = anPip[0] - anPip[1];
318             if (diff == 0)
319                 pc = g_strdup_printf(_("equal"));
320             else
321                 pc = g_strdup_printf("%d %s", abs(diff), (diff > 0) ? _("ahead") : _("behind"));
322 
323             gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, 0);
324             gtk_list_store_set(store, &iter, 1, pc, -1);
325             g_free(pc);
326         }
327     }
328     if (UpdateType & TT_EPC) {
329         if (ms.gs != GAME_NONE) {
330             float arEPC[2];
331 
332             if (EPC(points, arEPC, NULL, NULL, NULL, TRUE)) {   /* no EPCs available */
333                 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, 1);
334                 gtk_list_store_set(store, &iter, 1, "", -1);
335             } else {
336                 pc = g_strdup_printf("%.2f (%+.1f)", arEPC[1], arEPC[1] - arEPC[0]);
337                 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, 1);
338                 gtk_list_store_set(store, &iter, 1, pc, -1);
339                 g_free(pc);
340             }
341         }
342     }
343 
344     if (UpdateType & TT_RETURNHITS) {
345         TanBoard anBoard;
346         pc = NULL;
347         if (bd->valid_move) {
348             PositionFromKey(anBoard, &bd->valid_move->key);
349             pc = ReturnHits(anBoard);
350         }
351         if (pc) {
352             gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, 2);
353             gtk_list_store_set(store, &iter, 1, pc, -1);
354             g_free(pc);
355         } else {
356             gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, 2);
357             gtk_list_store_set(store, &iter, 1, "", -1);
358         }
359     }
360 
361     if (UpdateType & TT_KLEINCOUNT) {
362         if (ms.gs != GAME_NONE) {
363             float fKC;
364             unsigned int anPip[2];
365             PipCount(points, anPip);
366 
367             fKC = KleinmanCount(anPip[1], anPip[0]);
368             if (fKC >= 0) {
369                 pc = g_strdup_printf("%.4f", fKC);
370                 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, 3);
371                 gtk_list_store_set(store, &iter, 1, pc, -1);
372                 g_free(pc);
373             } else {
374                 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, 3);
375                 gtk_list_store_set(store, &iter, 1, "", -1);
376             }
377         }
378     }
379 }
380 
381 static GtkWidget *
CreateTheoryWindow(void)382 CreateTheoryWindow(void)
383 {
384     GtkListStore *store;
385     GtkTreeIter iter;
386     GtkCellRenderer *renderer;
387 
388     store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING, -1);
389     gtk_list_store_append(store, &iter);
390     gtk_list_store_set(store, &iter, 0, _("Pip count"), 1, "", -1);
391     gtk_list_store_append(store, &iter);
392     gtk_list_store_set(store, &iter, 0, _("EPC"), 1, "", -1);
393     gtk_list_store_append(store, &iter);
394     gtk_list_store_set(store, &iter, 0, _("Return hits"), 1, "", -1);
395     gtk_list_store_append(store, &iter);
396     gtk_list_store_set(store, &iter, 0, _("Kleinman count"), 1, "", -1);
397 
398     pwTheoryView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
399     g_object_unref(store);
400     renderer = gtk_cell_renderer_text_new();
401     gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(pwTheoryView), -1, NULL, renderer, "text", 0, NULL);
402     renderer = gtk_cell_renderer_text_new();
403     gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(pwTheoryView), -1, NULL, renderer, "text", 1, NULL);
404     gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(pwTheoryView), FALSE);
405 
406     CreatePanel(WINDOW_THEORY, pwTheoryView, _("GNU Backgammon - Theory"), "theory");
407     return woPanel[WINDOW_THEORY].pwWin;
408 }
409 
410 /* Display help for command (pStr) in widget (pwText) */
411 static void
ShowHelp(GtkWidget * pwText,char * pStr)412 ShowHelp(GtkWidget * pwText, char *pStr)
413 {
414     command *pc, *pcFull;
415     char szCommand[128], szUsage[128], szBuf[255], *cc, *pTemp;
416     command cTop = { NULL, NULL, NULL, NULL, acTop };
417     GtkTextBuffer *buffer;
418     GtkTextIter iter;
419 
420     /* Copy string as token striping corrupts string */
421     pTemp = malloc(strlen(pStr) + 1);
422     strcpy(pTemp, pStr);
423     cc = CheckCommand(pTemp, acTop);
424 
425     buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pwText));
426 
427     if (cc) {
428         sprintf(szBuf, _("Unknown keyword: %s\n"), cc);
429         gtk_text_buffer_set_text(buffer, szBuf, -1);
430     } else if ((pc = FindHelpCommand(&cTop, pStr, szCommand, szUsage)) != NULL) {
431         gtk_text_buffer_set_text(buffer, "", -1);
432         gtk_text_buffer_get_end_iter(buffer, &iter);
433         if (!*pStr) {
434             gtk_text_buffer_insert(buffer, &iter, _("Available commands:\n"), -1);
435         } else {
436             if (!pc->szHelp) {  /* The command is an abbreviation, search for the full version */
437                 for (pcFull = acTop; pcFull->sz; pcFull++) {
438                     if (pcFull->pf == pc->pf && pcFull->szHelp) {
439                         pc = pcFull;
440                         strcpy(szCommand, pc->sz);
441                         break;
442                     }
443                 }
444             }
445 
446             sprintf(szBuf, "Command: %s\n", szCommand);
447             gtk_text_buffer_insert(buffer, &iter, szBuf, -1);
448             gtk_text_buffer_insert(buffer, &iter, gettext(pc->szHelp), -1);
449             sprintf(szBuf, "\n\nUsage: %s", szUsage);
450             gtk_text_buffer_insert(buffer, &iter, szBuf, -1);
451 
452             if (!(pc->pc && pc->pc->sz))
453                 gtk_text_buffer_insert(buffer, &iter, "\n", -1);
454             else {
455                 gtk_text_buffer_insert(buffer, &iter, _("<subcommand>\n"), -1);
456                 gtk_text_buffer_insert(buffer, &iter, _("Available subcommands:\n"), -1);
457             }
458         }
459 
460         pc = pc->pc;
461 
462         while (pc && pc->sz) {
463             if (pc->szHelp) {
464                 sprintf(szBuf, "%-15s\t%s\n", pc->sz, gettext(pc->szHelp));
465                 gtk_text_buffer_insert(buffer, &iter, szBuf, -1);
466             }
467             pc++;
468         }
469     }
470     free(pTemp);
471 }
472 
473 static void
PopulateCommandHistory(CommandEntryData_T * pData)474 PopulateCommandHistory(CommandEntryData_T * pData)
475 {
476     int i;
477 
478     for (i = 0; i < pData->numHistory; i++) {
479         gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(pData->cmdEntryCombo), i);
480         gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(pData->cmdEntryCombo), i, pData->cmdHistory[i]);
481     }
482 }
483 
484 static void
CommandOK(GtkWidget * UNUSED (pw),CommandEntryData_T * pData)485 CommandOK(GtkWidget * UNUSED(pw), CommandEntryData_T * pData)
486 {
487     int i, found = -1;
488     pData->cmdString = gtk_editable_get_chars(GTK_EDITABLE(pData->pwEntry), 0, -1);
489 
490     /* Update command history */
491 
492     /* See if already in history */
493     for (i = 0; i < pData->numHistory; i++) {
494         if (!StrCaseCmp(pData->cmdString, pData->cmdHistory[i])) {
495             found = i;
496             break;
497         }
498     }
499     if (found != -1) {          /* Remove old entry */
500         free(pData->cmdHistory[found]);
501         pData->numHistory--;
502         for (i = found; i < pData->numHistory; i++)
503             pData->cmdHistory[i] = pData->cmdHistory[i + 1];
504     }
505 
506     if (pData->numHistory == NUM_CMD_HISTORY) {
507         free(pData->cmdHistory[NUM_CMD_HISTORY - 1]);
508         pData->numHistory--;
509     }
510     for (i = pData->numHistory; i > 0; i--)
511         pData->cmdHistory[i] = pData->cmdHistory[i - 1];
512 
513     pData->cmdHistory[0] = malloc(strlen(pData->cmdString) + 1);
514     strcpy(pData->cmdHistory[0], pData->cmdString);
515     pData->numHistory++;
516     PopulateCommandHistory(pData);
517     gtk_entry_set_text(GTK_ENTRY(pData->pwEntry), "");
518 
519     if (pData->cmdString) {
520         UserCommand(pData->cmdString);
521         g_free(pData->cmdString);
522     }
523 }
524 
525 static void
CommandTextChange(GtkEntry * entry,CommandEntryData_T * pData)526 CommandTextChange(GtkEntry * entry, CommandEntryData_T * pData)
527 {
528     if (pData->showHelp) {
529         /* Make sure the message window is showing */
530         if (!PanelShowing(WINDOW_MESSAGE))
531             PanelShow(WINDOW_MESSAGE);
532 
533         ShowHelp(pData->pwHelpText, gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1));
534     }
535 }
536 
537 static void
CreateHelpText(CommandEntryData_T * pData)538 CreateHelpText(CommandEntryData_T * pData)
539 {
540     GtkWidget *psw;
541     pData->pwHelpText = gtk_text_view_new();
542     gtk_widget_set_size_request(pData->pwHelpText, 400, 300);
543     psw = gtk_scrolled_window_new(NULL, NULL);
544     gtk_container_add(GTK_CONTAINER(psw), pData->pwHelpText);
545     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(psw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
546     CommandTextChange(GTK_ENTRY(pData->pwEntry), pData);
547 }
548 
549 static void
ShowHelpToggled(GtkWidget * widget,CommandEntryData_T * pData)550 ShowHelpToggled(GtkWidget * widget, CommandEntryData_T * pData)
551 {
552     if (!pData->pwHelpText)
553         CreateHelpText(pData);
554 
555     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
556         pData->showHelp = 1;
557         CommandTextChange(GTK_ENTRY(pData->pwEntry), pData);
558     } else
559         pData->showHelp = 0;
560     gtk_widget_grab_focus(pData->pwEntry);
561 }
562 
563 /* Capitalize first letter of each word */
564 static void
Capitalize(char * str)565 Capitalize(char *str)
566 {
567     int cap = 1;
568     while (*str) {
569         if (cap) {
570             *str = g_ascii_toupper(*str);
571             cap = 0;
572         } else {
573             if (*str == ' ')
574                 cap = 1;
575             *str = g_ascii_tolower(*str);
576         }
577         str++;
578     }
579 }
580 
581 static gboolean
CommandKeyPress(GtkWidget * UNUSED (widget),GdkEventKey * event,CommandEntryData_T * pData)582 CommandKeyPress(GtkWidget * UNUSED(widget), GdkEventKey * event, CommandEntryData_T * pData)
583 {
584     short k = (short) event->keyval;
585 
586     if (k == KEY_TAB) {         /* Tab press - auto complete */
587         char szCommand[128], szUsage[128];
588         command cTop = { NULL, NULL, NULL, NULL, acTop };
589         if (FindHelpCommand(&cTop, gtk_editable_get_chars(GTK_EDITABLE(pData->pwEntry), 0, -1), szCommand, szUsage) != NULL) {
590             Capitalize(szCommand);
591             gtk_entry_set_text(GTK_ENTRY(pData->pwEntry), szCommand);
592             gtk_editable_set_position(GTK_EDITABLE(pData->pwEntry), -1);
593             return TRUE;
594         }
595         /* Gtk 1 not good at stopping focus moving - so just move back later */
596         pData->completing = 1;
597     }
598     return FALSE;
599 }
600 
601 static gboolean
CommandFocusIn(GtkWidget * UNUSED (widget),GdkEventFocus * UNUSED (eventDetails),CommandEntryData_T * pData)602 CommandFocusIn(GtkWidget * UNUSED(widget), GdkEventFocus * UNUSED(eventDetails), CommandEntryData_T * pData)
603 {
604     if (pData->completing) {
605         /* Gtk 1 not good at stopping focus moving - so just move back now */
606         pData->completing = 0;
607         gtk_widget_grab_focus(pData->pwEntry);
608         gtk_editable_set_position(GTK_EDITABLE(pData->pwEntry),
609                                   (int) strlen(gtk_editable_get_chars(GTK_EDITABLE(pData->pwEntry), 0, -1)));
610         return TRUE;
611     } else
612         return FALSE;
613 }
614 
615 static GtkWidget *
CreateCommandWindow(void)616 CreateCommandWindow(void)
617 {
618     GtkWidget *pwhbox, *pwvbox;
619     GtkWidget *pwShowHelp;
620 
621 #if GTK_CHECK_VERSION(3,0,0)
622     pwvbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
623 #else
624     pwvbox = gtk_vbox_new(FALSE, 0);
625 #endif
626     CreatePanel(WINDOW_COMMAND, pwvbox, _("GNU Backgammon - Command"), "command");
627 
628     cedPanel.cmdString = NULL;
629     cedPanel.pwHelpText = pwMessageText;
630 
631     cedPanel.cmdEntryCombo = gtk_combo_box_text_new_with_entry();
632     cedPanel.pwEntry = gtk_bin_get_child(GTK_BIN(cedPanel.cmdEntryCombo));
633     gtk_entry_set_activates_default(GTK_ENTRY(cedPanel.pwEntry), FALSE);
634 
635     PopulateCommandHistory(&cedPanel);
636 
637     g_signal_connect(G_OBJECT(cedPanel.pwEntry), "changed", G_CALLBACK(CommandTextChange), &cedPanel);
638     g_signal_connect(G_OBJECT(cedPanel.pwEntry), "key-press-event", G_CALLBACK(CommandKeyPress), &cedPanel);
639     g_signal_connect(G_OBJECT(cedPanel.pwEntry), "activate", G_CALLBACK(CommandOK), &cedPanel);
640 
641 #if GTK_CHECK_VERSION(3,0,0)
642     pwhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
643 #else
644     pwhbox = gtk_hbox_new(FALSE, 0);
645 #endif
646     gtk_box_pack_start(GTK_BOX(pwvbox), pwhbox, FALSE, FALSE, 0);
647 
648     gtk_box_pack_start(GTK_BOX(pwhbox), cedPanel.cmdEntryCombo, TRUE, TRUE, 10);
649 
650     pwShowHelp = gtk_toggle_button_new_with_label(_("Help"));
651     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pwShowHelp), cedPanel.showHelp);
652     g_signal_connect(G_OBJECT(pwShowHelp), "toggled", G_CALLBACK(ShowHelpToggled), &cedPanel);
653 
654     gtk_box_pack_start(GTK_BOX(pwhbox), pwShowHelp, FALSE, FALSE, 5);
655     g_signal_connect(G_OBJECT(pwShowHelp), "focus-in-event", G_CALLBACK(CommandFocusIn), &cedPanel);
656 
657     return woPanel[WINDOW_COMMAND].pwWin;
658 }
659 
660 static GtkWidget *
CreateAnalysisWindow(void)661 CreateAnalysisWindow(void)
662 {
663     GtkWidget *pHbox, *sw;
664     GtkTextBuffer *buffer;
665     if (!woPanel[WINDOW_ANALYSIS].docked) {
666         GtkWidget *pwPaned;
667 
668 #if GTK_CHECK_VERSION(3,0,0)
669         pwPaned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
670 #else
671         pwPaned = gtk_vpaned_new();
672 #endif
673 
674         woPanel[WINDOW_ANALYSIS].pwWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
675 
676         gtk_window_set_title(GTK_WINDOW(woPanel[WINDOW_ANALYSIS].pwWin), _("GNU Backgammon - Annotation"));
677         gtk_window_set_role(GTK_WINDOW(woPanel[WINDOW_ANALYSIS].pwWin), "annotation");
678         gtk_window_set_type_hint(GTK_WINDOW(woPanel[WINDOW_ANALYSIS].pwWin), GDK_WINDOW_TYPE_HINT_UTILITY);
679 
680         setWindowGeometry(WINDOW_ANALYSIS);
681 
682         gtk_container_add(GTK_CONTAINER(woPanel[WINDOW_ANALYSIS].pwWin), pwPaned);
683         gtk_window_add_accel_group(GTK_WINDOW(woPanel[WINDOW_ANALYSIS].pwWin), pagMain);
684 
685         gtk_paned_pack1(GTK_PANED(pwPaned), pwAnalysis = gtk_label_new(NULL), TRUE, FALSE);
686 #if GTK_CHECK_VERSION(3,0,0)
687         pHbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
688 #else
689         pHbox = gtk_hbox_new(FALSE, 0);
690 #endif
691         gtk_paned_pack2(GTK_PANED(pwPaned), pHbox, FALSE, TRUE);
692     } else {
693 #if GTK_CHECK_VERSION(3,0,0)
694         pHbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
695 #else
696         pHbox = gtk_hbox_new(FALSE, 0);
697 #endif
698         gtk_box_pack_start(GTK_BOX(pHbox), pwAnalysis = gtk_label_new(NULL), TRUE, TRUE, 0);
699 #if GTK_CHECK_VERSION(3,0,0)
700         pHbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
701 #else
702         pHbox = gtk_hbox_new(FALSE, 0);
703 #endif
704     }
705 
706     pwCommentary = gtk_text_view_new();
707 
708     gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(pwCommentary), GTK_WRAP_WORD);
709     gtk_text_view_set_editable(GTK_TEXT_VIEW(pwCommentary), TRUE);
710     gtk_widget_set_sensitive(pwCommentary, FALSE);
711 
712     sw = gtk_scrolled_window_new(NULL, NULL);
713     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
714     gtk_container_add(GTK_CONTAINER(sw), pwCommentary);
715     gtk_box_pack_start(GTK_BOX(pHbox), sw, TRUE, TRUE, 0);
716     gtk_widget_set_size_request(sw, 100, 150);
717     buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pwCommentary));
718     g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(CommentaryChanged), buffer);
719 
720     if (!woPanel[WINDOW_ANALYSIS].docked) {
721         g_signal_connect(G_OBJECT(woPanel[WINDOW_ANALYSIS].pwWin), "delete_event",
722                          G_CALLBACK(woPanel[WINDOW_ANALYSIS].hideFun), NULL);
723         return woPanel[WINDOW_ANALYSIS].pwWin;
724     } else {
725         woPanel[WINDOW_ANALYSIS].pwWin = gtk_widget_get_parent(pwAnalysis);
726         return pHbox;
727     }
728 }
729 
730 extern void
GTKGameSelectDestroy(void)731 GTKGameSelectDestroy(void)
732 {
733     game_select_combo = NULL;
734 }
735 
736 extern void
GTKPopGame(int i)737 GTKPopGame(int i)
738 {
739     GtkTreeIter iter;
740     GtkTreeModel *model;
741 
742     model = gtk_combo_box_get_model(GTK_COMBO_BOX(game_select_combo));
743     while (gtk_tree_model_iter_nth_child(model, &iter, NULL, i))
744         gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
745 }
746 
747 extern void
GTKAddGame(moverecord * pmr)748 GTKAddGame(moverecord * pmr)
749 {
750     char sz[128];
751     GtkTreeModel *model;
752     gint last_game;
753 
754     if (pmr->g.fCrawford && pmr->g.fCrawfordGame)
755         sprintf(sz, _("Game %d: %d, %d Crawford"), pmr->g.i + 1, pmr->g.anScore[0], pmr->g.anScore[1]);
756     else
757         sprintf(sz, _("Game %d: %d, %d"), pmr->g.i + 1, pmr->g.anScore[0], pmr->g.anScore[1]);
758     gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(game_select_combo), sz);
759     model = gtk_combo_box_get_model(GTK_COMBO_BOX(game_select_combo));
760     last_game = gtk_tree_model_iter_n_children(model, NULL);
761     GTKSetGame(last_game - 1);
762 
763     /* Update Crawford flag on the board */
764     ms.fCrawford = pmr->g.fCrawford && pmr->g.fCrawfordGame;
765     GTKSet(&ms.fCrawford);
766 }
767 
768 extern void
GTKRegenerateGames(void)769 GTKRegenerateGames(void)
770 {
771     listOLD *pl;
772     int i = gtk_combo_box_get_active(GTK_COMBO_BOX(game_select_combo));
773 
774     GL_SetNames();
775     GTKPopGame(0);
776     for (pl = lMatch.plNext; pl->p; pl = pl->plNext) {
777         listOLD *plg = pl->p;
778         GTKAddGame(plg->plNext->p);
779     }
780 
781     GTKSetGame(i);
782 }
783 
784 extern void
GTKSetGame(int i)785 GTKSetGame(int i)
786 {
787     gtk_combo_box_set_active(GTK_COMBO_BOX(game_select_combo), i);
788 }
789 
790 static void
SelectGame(GtkWidget * pw,void * UNUSED (data))791 SelectGame(GtkWidget * pw, void *UNUSED(data))
792 {
793     listOLD *pl;
794     int i = 0;
795 
796     if (!plGame)
797         return;
798 
799     i = gtk_combo_box_get_active(GTK_COMBO_BOX(pw));
800     if (i == -1)
801         return;
802     for (pl = lMatch.plNext; i && pl->plNext->p; i--, pl = pl->plNext);
803 
804     if (pl->p == plGame)
805         return;
806 
807     ChangeGame(pl->p);
808 }
809 
810 static void
CreateGameWindow(void)811 CreateGameWindow(void)
812 {
813     GtkWidget *psw = gtk_scrolled_window_new(NULL, NULL);
814     GtkWidget *pvbox, *phbox;
815 
816 #if GTK_CHECK_VERSION(3,0,0)
817     g_object_set(G_OBJECT(psw), "expand", TRUE, NULL);
818     pvbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
819     phbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
820 #else
821     pvbox = gtk_vbox_new(FALSE, 0);
822     phbox = gtk_hbox_new(FALSE, 0);
823 #endif
824 
825     if (!woPanel[WINDOW_GAME].docked) {
826         woPanel[WINDOW_GAME].pwWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
827 
828         gtk_window_set_title(GTK_WINDOW(woPanel[WINDOW_GAME].pwWin), _("GNU Backgammon - Game record"));
829         gtk_window_set_role(GTK_WINDOW(woPanel[WINDOW_GAME].pwWin), "game record");
830         gtk_window_set_type_hint(GTK_WINDOW(woPanel[WINDOW_GAME].pwWin), GDK_WINDOW_TYPE_HINT_UTILITY);
831 
832         setWindowGeometry(WINDOW_GAME);
833 
834         gtk_container_add(GTK_CONTAINER(woPanel[WINDOW_GAME].pwWin), pvbox);
835         gtk_window_add_accel_group(GTK_WINDOW(woPanel[WINDOW_GAME].pwWin), pagMain);
836     }
837     gtk_box_pack_start(GTK_BOX(pvbox), phbox, FALSE, FALSE, 4);
838 
839     game_select_combo = gtk_combo_box_text_new();
840     g_signal_connect(G_OBJECT(game_select_combo), "changed", G_CALLBACK(SelectGame), NULL);
841     gtk_box_pack_start(GTK_BOX(phbox), game_select_combo, TRUE, TRUE, 4);
842 
843     gtk_box_pack_end(GTK_BOX(pvbox), psw, TRUE, TRUE, 0);
844     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(psw), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
845 
846     gtk_widget_set_size_request(psw, -1, 150);
847     gtk_container_add(GTK_CONTAINER(psw), GL_Create());
848 
849     if (!woPanel[WINDOW_GAME].docked) {
850         g_signal_connect(G_OBJECT(woPanel[WINDOW_GAME].pwWin), "delete_event",
851                          G_CALLBACK(woPanel[WINDOW_GAME].hideFun), NULL);
852     } else
853         woPanel[WINDOW_GAME].pwWin = pvbox;
854 }
855 
856 static void
CreateHeadWindow(gnubgwindow panel,const char * sz,GtkWidget * pwWidge)857 CreateHeadWindow(gnubgwindow panel, const char *sz, GtkWidget * pwWidge)
858 {
859     GtkWidget *pwLab = gtk_label_new(sz);
860     GtkWidget *pwVbox, *pwHbox;
861     GtkWidget *pwX = gtk_button_new();
862 
863 #if GTK_CHECK_VERSION(3,0,0)
864     pwVbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
865     pwHbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
866 #else
867     pwVbox = gtk_vbox_new(FALSE, 0);
868     pwHbox = gtk_hbox_new(FALSE, 0);
869 #endif
870 
871     gtk_button_set_image(GTK_BUTTON(pwX), gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU));
872     g_signal_connect(G_OBJECT(pwX), "clicked", G_CALLBACK(woPanel[panel].hideFun), NULL);
873 
874     gtk_box_pack_start(GTK_BOX(pwVbox), pwHbox, FALSE, FALSE, 0);
875     gtk_box_pack_start(GTK_BOX(pwHbox), pwLab, FALSE, FALSE, 10);
876     gtk_box_pack_end(GTK_BOX(pwHbox), pwX, FALSE, FALSE, 1);
877     gtk_box_pack_start(GTK_BOX(pwVbox), pwWidge, TRUE, TRUE, 0);
878 
879     woPanel[panel].pwWin = pwVbox;
880 }
881 
882 static void
CreatePanels(void)883 CreatePanels(void)
884 {
885     CreateGameWindow();
886     gtk_box_pack_start(GTK_BOX(pwPanelVbox), woPanel[WINDOW_GAME].pwWin, TRUE, TRUE, 0);
887 
888     CreateHeadWindow(WINDOW_ANNOTATION, _("Commentary"), CreateAnalysisWindow());
889     gtk_box_pack_start(GTK_BOX(pwPanelVbox), woPanel[WINDOW_ANALYSIS].pwWin, FALSE, FALSE, 0);
890     gtk_box_pack_start(GTK_BOX(pwPanelVbox), woPanel[WINDOW_ANNOTATION].pwWin, FALSE, FALSE, 0);
891 
892     CreateMessageWindow();
893     CreateHeadWindow(WINDOW_MESSAGE, _("Messages"), woPanel[WINDOW_MESSAGE].pwWin);
894     gtk_box_pack_start(GTK_BOX(pwPanelVbox), woPanel[WINDOW_MESSAGE].pwWin, FALSE, FALSE, 0);
895 
896     CreateHeadWindow(WINDOW_COMMAND, _("Command"), CreateCommandWindow());
897     gtk_box_pack_start(GTK_BOX(pwPanelVbox), woPanel[WINDOW_COMMAND].pwWin, FALSE, FALSE, 0);
898 
899     CreateHeadWindow(WINDOW_THEORY, _("Theory"), CreateTheoryWindow());
900     gtk_box_pack_start(GTK_BOX(pwPanelVbox), woPanel[WINDOW_THEORY].pwWin, FALSE, FALSE, 0);
901 }
902 
903 static gboolean
DeleteMessage(void)904 DeleteMessage(void)
905 {
906     HidePanel(WINDOW_MESSAGE);
907 #if defined(USE_GTKUIMANAGER)
908     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
909                                                                                  "/MainMenu/ViewMenu/PanelsMenu/Message")),
910                                    FALSE);
911 #else
912     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif,
913                                                                                    "/View/Panels/Message")), FALSE);
914 #endif
915     return TRUE;
916 }
917 
918 static gboolean
DeleteAnalysis(void)919 DeleteAnalysis(void)
920 {
921     HidePanel(WINDOW_ANALYSIS);
922 #if defined(USE_GTKUIMANAGER)
923     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
924                                                                                  "/MainMenu/ViewMenu/PanelsMenu/Analysis")),
925                                    FALSE);
926 #else
927     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif,
928                                                                                    "/View/Panels/Analysis")), FALSE);
929 #endif
930     return TRUE;
931 }
932 
933 static gboolean
DeleteAnnotation(void)934 DeleteAnnotation(void)
935 {
936     HidePanel(WINDOW_ANNOTATION);
937 #if defined(USE_GTKUIMANAGER)
938     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
939                                                                                  "/MainMenu/ViewMenu/PanelsMenu/Commentary")),
940                                    FALSE);
941 #else
942     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif,
943                                                                                    "/View/Panels/Commentary")), FALSE);
944 #endif
945     return TRUE;
946 }
947 
948 static gboolean
DeleteGame(void)949 DeleteGame(void)
950 {
951     HidePanel(WINDOW_GAME);
952 #if defined(USE_GTKUIMANAGER)
953     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
954                                                                                  "/MainMenu/ViewMenu/PanelsMenu/GameRecord")),
955                                    FALSE);
956 #else
957     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif,
958                                                                                    "/View/Panels/Game record")), FALSE);
959 #endif
960     return TRUE;
961 }
962 
963 static gboolean
DeleteTheoryWindow(void)964 DeleteTheoryWindow(void)
965 {
966     HidePanel(WINDOW_THEORY);
967 #if defined(USE_GTKUIMANAGER)
968     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
969                                                                                  "/MainMenu/ViewMenu/PanelsMenu/Theory")),
970                                    FALSE);
971 #else
972     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif, "/View/Panels/Theory")), FALSE);
973 #endif
974     return TRUE;
975 }
976 
977 static gboolean
DeleteCommandWindow(void)978 DeleteCommandWindow(void)
979 {
980     HidePanel(WINDOW_COMMAND);
981 #if defined(USE_GTKUIMANAGER)
982     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
983                                                                                  "/MainMenu/ViewMenu/PanelsMenu/Command")),
984                                    FALSE);
985 #else
986     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif,
987                                                                                    "/View/Panels/Command")), FALSE);
988 #endif
989     return TRUE;
990 }
991 
992 static void
GetGeometryString(char * buf,windowobject * pwo)993 GetGeometryString(char *buf, windowobject * pwo)
994 {
995     sprintf(buf, "set geometry %s width %d\n"
996             "set geometry %s height %d\n"
997             "set geometry %s xpos %d\n"
998             "set geometry %s ypos %d\n"
999             "set geometry %s max %s\n",
1000             pwo->winName, pwo->wg.nWidth,
1001             pwo->winName, pwo->wg.nHeight,
1002             pwo->winName, pwo->wg.nPosX, pwo->winName, pwo->wg.nPosY, pwo->winName, pwo->wg.max ? "yes" : "no");
1003 }
1004 
1005 extern void
SaveWindowSettings(FILE * pf)1006 SaveWindowSettings(FILE * pf)
1007 {
1008     char szTemp[1024];
1009     int i;
1010 
1011     int saveShowingPanels, dummy;
1012     if (fFullScreen)
1013         GetFullscreenWindowSettings(&saveShowingPanels, &dummy, &woPanel[WINDOW_MAIN].wg.max);
1014     else
1015         saveShowingPanels = fDisplayPanels;
1016 
1017     fprintf(pf, "set annotation %s\n", woPanel[WINDOW_ANNOTATION].showing ? "yes" : "no");
1018     fprintf(pf, "set message %s\n", woPanel[WINDOW_MESSAGE].showing ? "yes" : "no");
1019     fprintf(pf, "set gamelist %s\n", woPanel[WINDOW_GAME].showing ? "yes" : "no");
1020     fprintf(pf, "set analysis window %s\n", woPanel[WINDOW_ANALYSIS].showing ? "yes" : "no");
1021     fprintf(pf, "set theorywindow %s\n", woPanel[WINDOW_THEORY].showing ? "yes" : "no");
1022     fprintf(pf, "set commandwindow %s\n", woPanel[WINDOW_COMMAND].showing ? "yes" : "no");
1023 
1024     fprintf(pf, "set panels %s\n", saveShowingPanels ? "yes" : "no");
1025 
1026     for (i = 0; i < NUM_WINDOWS; i++) {
1027         if (i != WINDOW_ANNOTATION) {
1028             GetGeometryString(szTemp, &woPanel[i]);
1029             fputs(szTemp, pf);
1030         }
1031     }
1032     /* Save docked slider position */
1033     fprintf(pf, "set panelwidth %d\n", GetPanelSize());
1034 
1035     /* Save panel dock state (if not docked - default is docked) */
1036     if (!fDockPanels)
1037         fputs("set dockpanels off\n", pf);
1038 
1039     if (fFullScreen)
1040         woPanel[WINDOW_MAIN].wg.max = TRUE;
1041 }
1042 
1043 extern void
HidePanel(gnubgwindow window)1044 HidePanel(gnubgwindow window)
1045 {
1046     if (gtk_widget_get_visible(woPanel[window].pwWin)) {
1047         getWindowGeometry(window);
1048         woPanel[window].showing = FALSE;
1049         gtk_widget_hide(woPanel[window].pwWin);
1050     }
1051 }
1052 
1053 extern void
getWindowGeometry(gnubgwindow window)1054 getWindowGeometry(gnubgwindow window)
1055 {
1056     windowobject *pwo = &woPanel[window];
1057     if (pwo->docked || !pwo->pwWin)
1058         return;
1059 
1060 
1061     if (gtk_widget_get_realized(pwo->pwWin)) {
1062         GdkWindowState state = gdk_window_get_state(gtk_widget_get_window(pwo->pwWin));
1063         pwo->wg.max = ((state & GDK_WINDOW_STATE_MAXIMIZED) == GDK_WINDOW_STATE_MAXIMIZED);
1064         if (pwo->wg.max)
1065             return;             /* Could restore window to get correct restore size - just use previous for now */
1066 
1067         gtk_window_get_position(GTK_WINDOW(pwo->pwWin), &pwo->wg.nPosX, &pwo->wg.nPosY);
1068 
1069         gtk_window_get_size(GTK_WINDOW(pwo->pwWin), &pwo->wg.nWidth, &pwo->wg.nHeight);
1070     }
1071 
1072 }
1073 
1074 void
DockPanels(void)1075 DockPanels(void)
1076 {
1077     int i;
1078     int currentSelectedGame = -1;
1079     if (!fX)
1080         return;
1081 
1082     if (game_select_combo)
1083         currentSelectedGame = gtk_combo_box_get_active(GTK_COMBO_BOX(game_select_combo));
1084 
1085     if (fDockPanels) {
1086         RefreshGeometries();    /* Get the current window positions */
1087 
1088 #if defined(USE_GTKUIMANAGER)
1089         gtk_widget_show((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Commentary")));
1090 
1091         if (fDisplayPanels) {
1092             gtk_widget_show((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/HidePanels")));
1093             gtk_widget_hide((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/RestorePanels")));
1094         } else {
1095             gtk_widget_hide((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/HidePanels")));
1096             gtk_widget_show((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/RestorePanels")));
1097         }
1098 #else
1099         gtk_widget_show(gtk_item_factory_get_widget(pif, "/View/Panels/Commentary"));
1100         if (fDisplayPanels) {
1101             gtk_widget_show(gtk_item_factory_get_widget(pif, "/View/Hide panels"));
1102             gtk_widget_hide(gtk_item_factory_get_widget(pif, "/View/Restore panels"));
1103         } else {
1104             gtk_widget_hide(gtk_item_factory_get_widget(pif, "/View/Hide panels"));
1105             gtk_widget_show(gtk_item_factory_get_widget(pif, "/View/Restore panels"));
1106         }
1107 #endif
1108 
1109         for (i = 0; i < NUM_WINDOWS; i++) {
1110             if (woPanel[i].undockable && woPanel[i].pwWin)
1111                 gtk_widget_destroy(woPanel[i].pwWin);
1112 
1113             if (woPanel[i].dockable)
1114                 woPanel[i].docked = TRUE;
1115         }
1116         CreatePanels();
1117         if (fDisplayPanels)
1118             SwapBoardToPanel(TRUE, TRUE);
1119     } else {
1120         if (fDisplayPanels)
1121             SwapBoardToPanel(FALSE, TRUE);
1122 
1123 #if defined(USE_GTKUIMANAGER)
1124         gtk_widget_hide((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Commentary")));
1125         gtk_widget_hide((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/HidePanels")));
1126         gtk_widget_hide((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/RestorePanels")));
1127 #else
1128         gtk_widget_hide(gtk_item_factory_get_widget(pif, "/View/Panels/Commentary"));
1129         gtk_widget_hide(gtk_item_factory_get_widget(pif, "/View/Hide panels"));
1130         gtk_widget_hide(gtk_item_factory_get_widget(pif, "/View/Restore panels"));
1131 #endif
1132 
1133         for (i = 0; i < NUM_WINDOWS; i++) {
1134             if (woPanel[i].dockable && woPanel[i].pwWin) {
1135                 gtk_widget_destroy(woPanel[i].pwWin);
1136                 woPanel[i].pwWin = NULL;
1137                 woPanel[i].docked = FALSE;
1138             }
1139         }
1140         CreateGameWindow();
1141         CreateAnalysisWindow();
1142         CreateMessageWindow();
1143         CreateTheoryWindow();
1144         CreateCommandWindow();
1145     }
1146 #if defined(USE_GTKUIMANAGER)
1147     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim,
1148                                                        "/MainMenu/ViewMenu/PanelsMenu/Message"), !fDockPanels
1149                              || fDisplayPanels);
1150     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/GameRecord"), !fDockPanels
1151                              || fDisplayPanels);
1152     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Commentary"), !fDockPanels
1153                              || fDisplayPanels);
1154     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Analysis"), !fDockPanels
1155                              || fDisplayPanels);
1156     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Command"), !fDockPanels
1157                              || fDisplayPanels);
1158     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Theory"), !fDockPanels
1159                              || fDisplayPanels);
1160 #else
1161     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Message"), !fDockPanels || fDisplayPanels);
1162     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Game record"), !fDockPanels
1163                              || fDisplayPanels);
1164     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Commentary"), !fDockPanels
1165                              || fDisplayPanels);
1166     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Analysis"), !fDockPanels || fDisplayPanels);
1167     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Command"), !fDockPanels || fDisplayPanels);
1168     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Theory"), !fDockPanels || fDisplayPanels);
1169 #endif
1170     if (!fDockPanels || fDisplayPanels) {
1171         for (i = 0; i < NUM_WINDOWS; i++) {
1172             if (woPanel[i].dockable && woPanel[i].showing)
1173                 woPanel[i].showFun();
1174         }
1175     }
1176     /* Refresh panel contents */
1177     GTKRegenerateGames();
1178     ChangeGame(NULL);
1179     if (currentSelectedGame != -1)
1180         GTKSetGame(currentSelectedGame);
1181 
1182     /* Make sure check item is correct */
1183 #if defined(USE_GTKUIMANAGER)
1184     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_ui_manager_get_widget(puim,
1185                                                                                  "/MainMenu/ViewMenu/DockPanels")),
1186                                    fDockPanels);
1187 #else
1188     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(pif, "/View/Dock panels")),
1189                                    fDockPanels);
1190 #endif
1191     /* Resize screen */
1192     SetMainWindowSize();
1193 }
1194 
1195 extern void
ShowAllPanels(gpointer UNUSED (p),guint UNUSED (n),GtkWidget * UNUSED (pw))1196 ShowAllPanels(gpointer UNUSED(p), guint UNUSED(n), GtkWidget * UNUSED(pw))
1197 {
1198     BoardData *bd = BOARD(pwBoard)->board_data;
1199     int i;
1200     /* Only valid if panels docked */
1201     if (!fDockPanels)
1202         return;
1203 
1204     /* Hide for smoother appearance */
1205 #if defined(USE_BOARD3D)
1206     if (display_is_3d(bd->rd))
1207         gtk_widget_hide(GetDrawingArea3d(bd->bd3d));
1208     else
1209 #endif
1210         gtk_widget_hide(bd->drawing_area);
1211 
1212     fDisplayPanels = 1;
1213 
1214     for (i = 0; i < NUM_WINDOWS; i++) {
1215         if (woPanel[i].dockable && woPanel[i].showing)
1216             woPanel[i].showFun();
1217     }
1218 
1219 #if defined(USE_GTKUIMANAGER)
1220     gtk_widget_show((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/HidePanels")));
1221     gtk_widget_hide((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/RestorePanels")));
1222     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Message"), TRUE);
1223     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/GameRecord"), TRUE);
1224     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Commentary"), TRUE);
1225     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Analysis"), TRUE);
1226     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Command"), TRUE);
1227     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Theory"), TRUE);
1228 #else
1229     gtk_widget_show(gtk_item_factory_get_widget(pif, "/View/Hide panels"));
1230     gtk_widget_hide(gtk_item_factory_get_widget(pif, "/View/Restore panels"));
1231 
1232     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Message"), TRUE);
1233     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Game record"), TRUE);
1234     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Commentary"), TRUE);
1235     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Analysis"), TRUE);
1236     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Command"), TRUE);
1237     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Theory"), TRUE);
1238 #endif
1239     SwapBoardToPanel(TRUE, TRUE);
1240 
1241 #if defined(USE_BOARD3D)
1242     if (display_is_3d(bd->rd))
1243         gtk_widget_show(GetDrawingArea3d(bd->bd3d));
1244     else
1245 #endif
1246         gtk_widget_show(bd->drawing_area);
1247 }
1248 
1249 void
DoHideAllPanels(int updateEvents)1250 DoHideAllPanels(int updateEvents)
1251 {
1252     BoardData *bd = BOARD(pwBoard)->board_data;
1253     int i;
1254     /* Only valid if panels docked */
1255     if (!fDockPanels)
1256         return;
1257 
1258     /* Hide for smoother appearance */
1259 #if defined(USE_BOARD3D)
1260     if (display_is_3d(bd->rd))
1261         gtk_widget_hide(GetDrawingArea3d(bd->bd3d));
1262     else
1263 #endif
1264         gtk_widget_hide(bd->drawing_area);
1265 
1266     fDisplayPanels = 0;
1267 
1268     for (i = 0; i < NUM_WINDOWS; i++) {
1269         if (woPanel[i].dockable && woPanel[i].showing) {
1270             woPanel[i].hideFun();
1271             woPanel[i].showing = TRUE;
1272         }
1273     }
1274 
1275 #if defined(USE_GTKUIMANAGER)
1276     gtk_widget_show((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/RestorePanels")));
1277     gtk_widget_set_sensitive((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/RestorePanels")), TRUE);
1278     gtk_widget_hide((gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/HidePanels")));
1279 
1280     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Message"), FALSE);
1281     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/GameRecord"), FALSE);
1282     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Commentary"), FALSE);
1283     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Analysis"), FALSE);
1284     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Command"), FALSE);
1285     gtk_widget_set_sensitive(gtk_ui_manager_get_widget(puim, "/MainMenu/ViewMenu/PanelsMenu/Theory"), FALSE);
1286 #else
1287     gtk_widget_show(gtk_item_factory_get_widget(pif, "/View/Restore panels"));
1288     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Restore panels"), TRUE);
1289     gtk_widget_hide(gtk_item_factory_get_widget(pif, "/View/Hide panels"));
1290 
1291     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Message"), FALSE);
1292     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Game record"), FALSE);
1293     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Commentary"), FALSE);
1294     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Analysis"), FALSE);
1295     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Theory"), FALSE);
1296     gtk_widget_set_sensitive(gtk_item_factory_get_widget(pif, "/View/Panels/Command"), FALSE);
1297 #endif
1298     SwapBoardToPanel(FALSE, updateEvents);
1299 
1300     /* Resize screen */
1301     SetMainWindowSize();
1302 
1303 #if defined(USE_BOARD3D)
1304     if (display_is_3d(bd->rd))
1305         gtk_widget_show(GetDrawingArea3d(bd->bd3d));
1306     else
1307 #endif
1308         gtk_widget_show(bd->drawing_area);
1309 }
1310 
1311 extern void
HideAllPanels(gpointer UNUSED (p),guint UNUSED (n),GtkWidget * UNUSED (pw))1312 HideAllPanels(gpointer UNUSED(p), guint UNUSED(n), GtkWidget * UNUSED(pw))
1313 {
1314     DoHideAllPanels(TRUE);
1315 }
1316 
1317 #if defined(USE_GTKUIMANAGER)
1318 void
ToggleDockPanels(GtkToggleAction * action,gpointer UNUSED (user_data))1319 ToggleDockPanels(GtkToggleAction * action, gpointer UNUSED(user_data))
1320 {
1321     int newValue = gtk_toggle_action_get_active(action);
1322     if (fDockPanels != newValue) {
1323         fDockPanels = newValue;
1324         DockPanels();
1325     }
1326 }
1327 #else
1328 extern void
ToggleDockPanels(gpointer UNUSED (p),guint UNUSED (n),GtkWidget * pw)1329 ToggleDockPanels(gpointer UNUSED(p), guint UNUSED(n), GtkWidget * pw)
1330 {
1331     int newValue = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(pw));
1332     if (fDockPanels != newValue) {
1333         fDockPanels = newValue;
1334         DockPanels();
1335     }
1336 }
1337 #endif
1338 
1339 extern void
DisplayWindows(void)1340 DisplayWindows(void)
1341 {
1342     int i;
1343     /* Display any other windows now */
1344     for (i = 0; i < NUM_WINDOWS; i++) {
1345         if (woPanel[i].pwWin && woPanel[i].dockable) {
1346             if (woPanel[i].showing)
1347                 gtk_widget_show_all(woPanel[i].pwWin);
1348             else
1349                 gtk_widget_hide(woPanel[i].pwWin);
1350         }
1351     }
1352     if (!fDisplayPanels) {
1353         gtk_widget_hide(hpaned);        /* Need to stop wrong panel position getting set - gtk 2.6 */
1354         HideAllPanels(0, 0, 0);
1355     }
1356 }
1357 
1358 void
DestroyPanel(gnubgwindow window)1359 DestroyPanel(gnubgwindow window)
1360 {
1361     if (woPanel[window].pwWin) {
1362         gtk_widget_destroy(woPanel[window].pwWin);
1363         woPanel[window].pwWin = NULL;
1364         woPanel[window].showing = FALSE;
1365     }
1366 }
1367 
1368 GtkWidget *
GetPanelWidget(gnubgwindow window)1369 GetPanelWidget(gnubgwindow window)
1370 {
1371     return woPanel[window].pwWin;
1372 }
1373 
1374 void
SetPanelWidget(gnubgwindow window,GtkWidget * pWin)1375 SetPanelWidget(gnubgwindow window, GtkWidget * pWin)
1376 {
1377     woPanel[window].pwWin = pWin;
1378     woPanel[WINDOW_HINT].showing = pWin ? TRUE : FALSE;
1379 }
1380 
1381 extern void
setWindowGeometry(gnubgwindow window)1382 setWindowGeometry(gnubgwindow window)
1383 {
1384     windowobject *pwo = &woPanel[window];
1385 
1386     if (pwo->docked || !pwo->pwWin || !fGUISetWindowPos)
1387         return;
1388 
1389 
1390     gtk_window_set_default_size(GTK_WINDOW(pwo->pwWin),
1391                                 (pwo->wg.nWidth > 0) ? pwo->wg.nWidth : -1,
1392                                 (pwo->wg.nHeight > 0) ? pwo->wg.nHeight : -1);
1393 
1394     gtk_window_move(GTK_WINDOW(pwo->pwWin),
1395                     (pwo->wg.nPosX >= 0) ? pwo->wg.nPosX : 0, (pwo->wg.nPosY >= 0) ? pwo->wg.nPosY : 0);
1396 
1397     if (pwo->wg.max)
1398         gtk_window_maximize(GTK_WINDOW(pwo->pwWin));
1399     else
1400         gtk_window_unmaximize(GTK_WINDOW(pwo->pwWin));
1401 }
1402 
1403 void
ShowHidePanel(gnubgwindow panel)1404 ShowHidePanel(gnubgwindow panel)
1405 {
1406     if (woPanel[panel].showing)
1407         woPanel[panel].showFun();
1408     else
1409         woPanel[panel].hideFun();
1410 }
1411 
1412 int
SetMainWindowSize(void)1413 SetMainWindowSize(void)
1414 {
1415     if (woPanel[WINDOW_MAIN].wg.nWidth && woPanel[WINDOW_MAIN].wg.nHeight) {
1416         gtk_window_set_default_size(GTK_WINDOW(pwMain),
1417                                     woPanel[WINDOW_MAIN].wg.nWidth, woPanel[WINDOW_MAIN].wg.nHeight);
1418         return 1;
1419     } else
1420         return 0;
1421 }
1422 
1423 void
PanelShow(gnubgwindow panel)1424 PanelShow(gnubgwindow panel)
1425 {
1426     woPanel[panel].showFun();
1427 }
1428 
1429 void
PanelHide(gnubgwindow panel)1430 PanelHide(gnubgwindow panel)
1431 {
1432     woPanel[panel].hideFun();
1433 }
1434 
1435 extern void
RefreshGeometries(void)1436 RefreshGeometries(void)
1437 {
1438     int i;
1439     for (i = 0; i < NUM_WINDOWS; i++)
1440         getWindowGeometry((gnubgwindow) i);
1441 }
1442 
1443 extern void
CommandSetAnnotation(char * sz)1444 CommandSetAnnotation(char *sz)
1445 {
1446 
1447     SetToggle("annotation", &woPanel[WINDOW_ANNOTATION].showing, sz,
1448               _("Move analysis and commentary will be displayed."),
1449               _("Move analysis and commentary will not be displayed."));
1450 }
1451 
1452 extern void
CommandSetMessage(char * sz)1453 CommandSetMessage(char *sz)
1454 {
1455 
1456     SetToggle("message", &woPanel[WINDOW_MESSAGE].showing, sz,
1457               _("Show window with messages"), _("Do not show window with messages."));
1458 }
1459 
1460 extern void
CommandSetTheoryWindow(char * sz)1461 CommandSetTheoryWindow(char *sz)
1462 {
1463 
1464     SetToggle("theorywindow", &woPanel[WINDOW_THEORY].showing, sz,
1465               _("Show window with theory"), _("Do not show window with theory."));
1466 }
1467 
1468 extern void
CommandSetCommandWindow(char * sz)1469 CommandSetCommandWindow(char *sz)
1470 {
1471 
1472     SetToggle("commandwindow", &woPanel[WINDOW_COMMAND].showing, sz,
1473               _("Show window to enter commands"), _("Do not show window to enter commands."));
1474 }
1475 
1476 extern void
CommandSetGameList(char * sz)1477 CommandSetGameList(char *sz)
1478 {
1479 
1480     SetToggle("gamelist", &woPanel[WINDOW_GAME].showing, sz,
1481               _("Show game window with moves"), _("Do not show game window with moves."));
1482 }
1483 
1484 extern void
CommandSetAnalysisWindows(char * sz)1485 CommandSetAnalysisWindows(char *sz)
1486 {
1487 
1488     SetToggle("analysis window", &woPanel[WINDOW_ANALYSIS].showing, sz,
1489               _("Show window with analysis"), _("Do not show window with analysis."));
1490 }
1491 
1492 static gnubgwindow pwoSetPanel;
1493 
1494 extern void
CommandSetGeometryAnalysis(char * sz)1495 CommandSetGeometryAnalysis(char *sz)
1496 {
1497     pwoSetPanel = WINDOW_ANALYSIS;
1498     HandleCommand(sz, acSetGeometryValues);
1499 }
1500 
1501 extern void
CommandSetGeometryHint(char * sz)1502 CommandSetGeometryHint(char *sz)
1503 {
1504     pwoSetPanel = WINDOW_HINT;
1505     HandleCommand(sz, acSetGeometryValues);
1506 }
1507 
1508 extern void
CommandSetGeometryGame(char * sz)1509 CommandSetGeometryGame(char *sz)
1510 {
1511     pwoSetPanel = WINDOW_GAME;
1512     HandleCommand(sz, acSetGeometryValues);
1513 }
1514 
1515 extern void
CommandSetGeometryMain(char * sz)1516 CommandSetGeometryMain(char *sz)
1517 {
1518     pwoSetPanel = WINDOW_MAIN;
1519     HandleCommand(sz, acSetGeometryValues);
1520 }
1521 
1522 extern void
CommandSetGeometryMessage(char * sz)1523 CommandSetGeometryMessage(char *sz)
1524 {
1525     pwoSetPanel = WINDOW_MESSAGE;
1526     HandleCommand(sz, acSetGeometryValues);
1527 }
1528 
1529 extern void
CommandSetGeometryCommand(char * sz)1530 CommandSetGeometryCommand(char *sz)
1531 {
1532     pwoSetPanel = WINDOW_COMMAND;
1533     HandleCommand(sz, acSetGeometryValues);
1534 }
1535 
1536 extern void
CommandSetGeometryTheory(char * sz)1537 CommandSetGeometryTheory(char *sz)
1538 {
1539     pwoSetPanel = WINDOW_THEORY;
1540     HandleCommand(sz, acSetGeometryValues);
1541 }
1542 
1543 extern void
CommandSetGeometryWidth(char * sz)1544 CommandSetGeometryWidth(char *sz)
1545 {
1546 
1547     int n;
1548 
1549     if ((n = ParseNumber(&sz)) == INT_MIN)
1550         outputf(_("Illegal value. " "See 'help set geometry %s width'.\n"), woPanel[pwoSetPanel].winName);
1551     else {
1552 
1553         woPanel[pwoSetPanel].wg.nWidth = n;
1554         outputf(_("Width of %s window set to %d.\n"), woPanel[pwoSetPanel].winName, n);
1555 
1556         if (fX)
1557             setWindowGeometry(pwoSetPanel);
1558 
1559     }
1560 
1561 }
1562 
1563 extern void
CommandSetGeometryHeight(char * sz)1564 CommandSetGeometryHeight(char *sz)
1565 {
1566 
1567     int n;
1568 
1569     if ((n = ParseNumber(&sz)) == INT_MIN)
1570         outputf(_("Illegal value. " "See 'help set geometry %s height'.\n"), woPanel[pwoSetPanel].winName);
1571     else {
1572 
1573         woPanel[pwoSetPanel].wg.nHeight = n;
1574         outputf(_("Height of %s window set to %d.\n"), woPanel[pwoSetPanel].winName, n);
1575 
1576         if (fX)
1577             setWindowGeometry(pwoSetPanel);
1578     }
1579 
1580 }
1581 
1582 extern void
CommandSetGeometryPosX(char * sz)1583 CommandSetGeometryPosX(char *sz)
1584 {
1585 
1586     int n;
1587 
1588     if ((n = ParseNumber(&sz)) == INT_MIN)
1589         outputf(_("Illegal value. " "See 'help set geometry %s xpos'.\n"), woPanel[pwoSetPanel].winName);
1590     else {
1591 
1592         woPanel[pwoSetPanel].wg.nPosX = n;
1593         outputf(_("X-position of %s window set to %d.\n"), woPanel[pwoSetPanel].winName, n);
1594 
1595         if (fX)
1596             setWindowGeometry(pwoSetPanel);
1597 
1598     }
1599 
1600 }
1601 
1602 extern void
CommandSetGeometryPosY(char * sz)1603 CommandSetGeometryPosY(char *sz)
1604 {
1605 
1606     int n;
1607 
1608     if ((n = ParseNumber(&sz)) == INT_MIN)
1609         outputf(_("Illegal value. " "See 'help set geometry %s ypos'.\n"), woPanel[pwoSetPanel].winName);
1610     else {
1611 
1612         woPanel[pwoSetPanel].wg.nPosY = n;
1613         outputf(_("Y-position of %s window set to %d.\n"), woPanel[pwoSetPanel].winName, n);
1614 
1615         if (fX)
1616             setWindowGeometry(pwoSetPanel);
1617     }
1618 
1619 }
1620 
1621 extern void
CommandSetGeometryMax(char * sz)1622 CommandSetGeometryMax(char *sz)
1623 {
1624     int maxed = (StrCaseCmp(sz, "yes") == 0);
1625     woPanel[pwoSetPanel].wg.max = maxed;
1626     outputf(maxed ? _("%s window maximised.\n") : _("%s window unmaximised.\n"), woPanel[pwoSetPanel].winName);
1627 
1628     if (fX)
1629         setWindowGeometry(pwoSetPanel);
1630 }
1631 
1632 extern void
CommandSetPanels(char * sz)1633 CommandSetPanels(char *sz)
1634 {
1635 
1636     SetToggle("panels", &fDisplayPanels, sz,
1637               _("Game list, Annotation and Message panels/windows will be displayed."),
1638               _("Game list, Annotation and Message panels/windows will not be displayed.")
1639         );
1640 
1641     if (fX) {
1642         if (fDisplayPanels)
1643             ShowAllPanels(0, 0, 0);
1644         else
1645             HideAllPanels(0, 0, 0);
1646     }
1647 
1648 }
1649 
1650 extern void
CommandShowPanels(char * UNUSED (sz))1651 CommandShowPanels(char *UNUSED(sz))
1652 {
1653     if (fDisplayPanels)
1654         outputl(_("Game list, Annotation and Message panels/windows " "will be displayed."));
1655     else
1656         outputl(_("Game list, Annotation and Message panels/windows " "will not be displayed."));
1657 }
1658 
1659 extern void
CommandSetDockPanels(char * sz)1660 CommandSetDockPanels(char *sz)
1661 {
1662 
1663     SetToggle("dockdisplay", &fDockPanels, sz, _("Windows will be docked."), _("Windows will be detached."));
1664     DockPanels();
1665 }
1666 
1667 static void
GetGeometryDisplayString(char * buf,windowobject * pwo)1668 GetGeometryDisplayString(char *buf, windowobject * pwo)
1669 {
1670     char dispName[50];
1671     sprintf(dispName, "%c%s %s", toupper(pwo->winName[0]), &pwo->winName[1], _("window"));
1672 
1673     sprintf(buf, "%-17s : size %dx%d, position (%d,%d)\n",
1674             dispName, pwo->wg.nWidth, pwo->wg.nHeight, pwo->wg.nPosX, pwo->wg.nPosY);
1675 }
1676 
1677 extern void
CommandShowGeometry(char * UNUSED (sz))1678 CommandShowGeometry(char *UNUSED(sz))
1679 {
1680     int i;
1681     char szBuf[1024];
1682     output(_("Default geometries:\n\n"));
1683 
1684     for (i = 0; i < NUM_WINDOWS; i++) {
1685         GetGeometryDisplayString(szBuf, &woPanel[i]);
1686         output(szBuf);
1687     }
1688 }
1689 
1690 int
DockedPanelsShowing(void)1691 DockedPanelsShowing(void)
1692 {
1693     return fDockPanels && fDisplayPanels;
1694 }
1695 
1696 int
ArePanelsShowing(void)1697 ArePanelsShowing(void)
1698 {
1699     return fDisplayPanels;
1700 }
1701 
1702 int
ArePanelsDocked(void)1703 ArePanelsDocked(void)
1704 {
1705     return fDockPanels;
1706 }
1707 
1708 int
IsPanelDocked(gnubgwindow window)1709 IsPanelDocked(gnubgwindow window)
1710 {
1711     return woPanel[window].docked;
1712 }
1713 
1714 #if ! GTK_CHECK_VERSION(3,0,0)
1715 int
GetPanelWidth(gnubgwindow panel)1716 GetPanelWidth(gnubgwindow panel)
1717 {
1718     return woPanel[panel].wg.nWidth;
1719 }
1720 #endif
1721 
1722 int
IsPanelShowVar(gnubgwindow panel,void * p)1723 IsPanelShowVar(gnubgwindow panel, void *p)
1724 {
1725     return (p == &woPanel[panel].showing);
1726 }
1727 
1728 int
PanelShowing(gnubgwindow window)1729 PanelShowing(gnubgwindow window)
1730 {
1731     return woPanel[window].showing && (fDisplayPanels || !woPanel[window].docked);
1732 }
1733 
1734 extern void
ClosePanels(void)1735 ClosePanels(void)
1736 {
1737     /* loop through and close each panel (not main window) */
1738     int window;
1739     for (window = 0; window < NUM_WINDOWS; window++) {
1740         if (window != WINDOW_MAIN) {
1741             if (woPanel[window].pwWin) {
1742                 gtk_widget_destroy(woPanel[window].pwWin);
1743                 woPanel[window].pwWin = NULL;
1744             }
1745         }
1746     }
1747     pwTheoryView = NULL;        /* Reset this to stop errors - may be other ones that need reseting? */
1748 }
1749