Initial checkin. I created this by combining the XBoard 4.2.6 and
[xboard.git] / xedittags.c
1 /*
2  * xedittags.c -- Tags edit window, part of X front end for XBoard
3  * $Id$
4  *
5  * Copyright 1995 Free Software Foundation, Inc.
6  *
7  * The following terms apply to the enhanced version of XBoard distributed
8  * by the Free Software Foundation:
9  * ------------------------------------------------------------------------
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23  * ------------------------------------------------------------------------
24  *
25  * See the file ChangeLog for a revision history.
26  */
27
28 #include "config.h"
29
30 #include <stdio.h>
31 #include <ctype.h>
32 #include <errno.h>
33 #include <sys/types.h>
34
35 #if STDC_HEADERS
36 # include <stdlib.h>
37 # include <string.h>
38 #else /* not STDC_HEADERS */
39 extern char *getenv();
40 # if HAVE_STRING_H
41 #  include <string.h>
42 # else /* not HAVE_STRING_H */
43 #  include <strings.h>
44 # endif /* not HAVE_STRING_H */
45 #endif /* not STDC_HEADERS */
46
47 #if HAVE_UNISTD_H
48 # include <unistd.h>
49 #endif
50
51 #include <X11/Intrinsic.h>
52 #include <X11/StringDefs.h>
53 #include <X11/Shell.h>
54 #include <X11/cursorfont.h>
55 #if USE_XAW3D
56 #include <X11/Xaw3d/Dialog.h>
57 #include <X11/Xaw3d/Form.h>
58 #include <X11/Xaw3d/List.h>
59 #include <X11/Xaw3d/Label.h>
60 #include <X11/Xaw3d/SimpleMenu.h>
61 #include <X11/Xaw3d/SmeBSB.h>
62 #include <X11/Xaw3d/SmeLine.h>
63 #include <X11/Xaw3d/Box.h>
64 #include <X11/Xaw3d/MenuButton.h>
65 #include <X11/Xaw3d/Text.h>
66 #include <X11/Xaw3d/AsciiText.h>
67 #include <X11/Xaw3d/Viewport.h>
68 #else
69 #include <X11/Xaw/Dialog.h>
70 #include <X11/Xaw/Form.h>
71 #include <X11/Xaw/List.h>
72 #include <X11/Xaw/Label.h>
73 #include <X11/Xaw/SimpleMenu.h>
74 #include <X11/Xaw/SmeBSB.h>
75 #include <X11/Xaw/SmeLine.h>
76 #include <X11/Xaw/Box.h>
77 #include <X11/Xaw/MenuButton.h>
78 #include <X11/Xaw/Text.h>
79 #include <X11/Xaw/AsciiText.h>
80 #include <X11/Xaw/Viewport.h>
81 #endif
82
83 #include "common.h"
84 #include "frontend.h"
85 #include "backend.h"
86 #include "xboard.h"
87 #include "xedittags.h"
88
89 extern Widget formWidget, shellWidget, boardWidget, menuBarWidget;
90 extern Display *xDisplay;
91 extern int squareSize;
92 extern Pixmap xMarkPixmap;
93 extern char *layoutName;
94
95 Position tagsX = -1, tagsY = -1;
96 int tagsUp = False, editTagsUp = False;
97 Widget tagsShell, editTagsShell;
98
99 static Arg layoutArgs[] = {
100     { XtNborderWidth, 0 },
101     { XtNdefaultDistance, 0 }
102 };
103
104 void TagsCallback(w, client_data, call_data)
105      Widget w;
106      XtPointer client_data, call_data;
107 {
108     String name;
109     Arg args[16];
110     int j;
111
112     j = 0;
113     XtSetArg(args[j], XtNlabel, &name);  j++;
114     XtGetValues(w, args, j);
115
116     if (strcmp(name, "close") == 0) {
117         TagsPopDown();
118     } else if (strcmp(name, "edit") == 0) {
119         TagsPopDown();
120         EditTagsEvent();
121     }
122 }
123
124
125 void EditTagsCallback(w, client_data, call_data)
126      Widget w;
127      XtPointer client_data, call_data;
128 {
129     String name, val;
130     Arg args[16];
131     int j;
132     Widget textw;
133
134     j = 0;
135     XtSetArg(args[j], XtNlabel, &name);  j++;
136     XtGetValues(w, args, j);
137
138     if (strcmp(name, "ok") == 0) {
139         textw = XtNameToWidget(editTagsShell, "*form.text");
140         j = 0;
141         XtSetArg(args[j], XtNstring, &val); j++;
142         XtGetValues(textw, args, j);
143         ReplaceTags(val, &gameInfo);
144         TagsPopDown();
145     } else if (strcmp(name, "cancel") == 0) {
146         TagsPopDown();
147     } else if (strcmp(name, "clear") == 0) {
148         textw = XtNameToWidget(editTagsShell, "*form.text");
149         XtCallActionProc(textw, "select-all", NULL, NULL, 0);
150         XtCallActionProc(textw, "kill-selection", NULL, NULL, 0);
151     }
152 }
153
154 Widget TagsCreate(name, text, msg, mutable, callback)
155      char *name, *text, *msg;
156      int /*Boolean*/ mutable;
157      XtCallbackProc callback;
158 {
159     Arg args[16];
160     Widget shell, form, textw, msgw, layout;
161     Widget b_ok, b_cancel, b_close, b_edit, b;
162     Dimension bw_width, pw_width;
163     Dimension pw_height;
164     int j, xx, yy;
165     Window junk;
166
167     j = 0;
168     XtSetArg(args[j], XtNwidth, &bw_width);  j++;
169     XtGetValues(boardWidget, args, j);
170
171     j = 0;
172     XtSetArg(args[j], XtNresizable, True);  j++;
173 #if TOPLEVEL
174     shell =
175       XtCreatePopupShell(name, topLevelShellWidgetClass,
176                          shellWidget, args, j);
177 #else
178     shell =
179       XtCreatePopupShell(name, transientShellWidgetClass,
180                          shellWidget, args, j);
181 #endif
182     layout =
183       XtCreateManagedWidget(layoutName, formWidgetClass, shell,
184                             layoutArgs, XtNumber(layoutArgs));
185     j = 0;
186     XtSetArg(args[j], XtNborderWidth, 0); j++;
187     form =
188       XtCreateManagedWidget("form", formWidgetClass, layout, args, j);
189
190     j = 0;
191     if (mutable) {
192         XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;
193         XtSetArg(args[j], XtNuseStringInPlace, False);  j++;
194     }
195     XtSetArg(args[j], XtNstring, text);  j++;
196     XtSetArg(args[j], XtNtop, XtChainTop);  j++;
197     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
198     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
199     XtSetArg(args[j], XtNright, XtRubber);  j++;
200     XtSetArg(args[j], XtNresizable, True);  j++;
201     XtSetArg(args[j], XtNwidth, bw_width/2);  j++;
202     XtSetArg(args[j], XtNheight, bw_width/3);  j++;
203 #if 0
204     XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded);  j++;
205 #else
206     /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
207     XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways);  j++;
208 #endif
209     XtSetArg(args[j], XtNautoFill, False);  j++;
210     textw =
211       XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
212
213     if (cmailMsgLoaded && !mutable) {
214         j = 0;
215         XtSetArg(args[j], XtNfromVert, textw);  j++;
216         XtSetArg(args[j], XtNtop, XtChainBottom); j++;
217         XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
218         XtSetArg(args[j], XtNleft, XtChainLeft); j++;
219         XtSetArg(args[j], XtNright, XtChainRight); j++;
220         XtSetArg(args[j], XtNborderWidth, 0); j++;
221         XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
222         XtSetArg(args[j], XtNlabel, msg); j++;
223         msgw =
224           XtCreateManagedWidget("msg", labelWidgetClass, form, args, j);
225     } else {
226         msgw = textw;
227     }
228     if (mutable) {
229         j = 0;
230         XtSetArg(args[j], XtNfromVert, msgw);  j++;
231         XtSetArg(args[j], XtNtop, XtChainBottom); j++;
232         XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
233         XtSetArg(args[j], XtNleft, XtChainLeft); j++;
234         XtSetArg(args[j], XtNright, XtChainLeft); j++;
235         b_ok = b =
236           XtCreateManagedWidget("ok", commandWidgetClass, form, args, j);
237         XtAddCallback(b_ok, XtNcallback, callback, (XtPointer) 0);
238
239         j = 0;
240         XtSetArg(args[j], XtNfromVert, msgw);  j++;
241         XtSetArg(args[j], XtNfromHoriz, b);  j++;
242         XtSetArg(args[j], XtNtop, XtChainBottom); j++;
243         XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
244         XtSetArg(args[j], XtNleft, XtChainLeft); j++;
245         XtSetArg(args[j], XtNright, XtChainLeft); j++;
246         b_cancel = b =
247           XtCreateManagedWidget("cancel", commandWidgetClass, form, args, j);
248         XtAddCallback(b_cancel, XtNcallback, callback, (XtPointer) 0);
249
250 #if 0
251         j = 0;
252         XtSetArg(args[j], XtNfromVert, msgw);  j++;
253         XtSetArg(args[j], XtNfromHoriz, b);  j++;
254         XtSetArg(args[j], XtNtop, XtChainBottom); j++;
255         XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
256         XtSetArg(args[j], XtNleft, XtChainLeft); j++;
257         XtSetArg(args[j], XtNright, XtChainLeft); j++;
258         b_clear = b =
259           XtCreateManagedWidget("clear", commandWidgetClass, form, args, j);
260         XtAddCallback(b_clear, XtNcallback, callback, (XtPointer) 0);
261 #endif
262     } else {
263         j = 0;
264         XtSetArg(args[j], XtNfromVert, msgw);  j++;
265         XtSetArg(args[j], XtNtop, XtChainBottom); j++;
266         XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
267         XtSetArg(args[j], XtNleft, XtChainLeft); j++;
268         XtSetArg(args[j], XtNright, XtChainLeft); j++;
269         b_close = b =
270           XtCreateManagedWidget("close", commandWidgetClass, form, args, j);
271         XtAddCallback(b_close, XtNcallback, callback, (XtPointer) 0);
272
273         j = 0;
274         XtSetArg(args[j], XtNfromVert, msgw);  j++;
275         XtSetArg(args[j], XtNfromHoriz, b);  j++;
276         XtSetArg(args[j], XtNtop, XtChainBottom); j++;
277         XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
278         XtSetArg(args[j], XtNleft, XtChainLeft); j++;
279         XtSetArg(args[j], XtNright, XtChainLeft); j++;
280         b_edit = b =
281           XtCreateManagedWidget("edit", commandWidgetClass, form, args, j);
282         XtAddCallback(b_edit, XtNcallback, callback, (XtPointer) 0);
283     }
284
285     XtRealizeWidget(shell);
286     CatchDeleteWindow(shell, "TagsPopDown");
287
288     if (tagsX == -1) {
289         j = 0;
290         XtSetArg(args[j], XtNwidth, &bw_width);  j++;
291         XtGetValues(boardWidget, args, j);
292         j = 0;
293         XtSetArg(args[j], XtNwidth, &pw_width);  j++;
294         XtSetArg(args[j], XtNheight, &pw_height);  j++;
295         XtGetValues(shell, args, j);
296
297 #ifdef NOTDEF
298         /* This code seems to tickle an X bug if it is executed too soon
299            after xboard starts up.  The coordinates get transformed as if
300            the main window was positioned at (0, 0).
301            */
302         XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
303                           0 - pw_height + squareSize / 3, &x, &y);
304 #else
305         XTranslateCoordinates(xDisplay, XtWindow(boardWidget),
306                               RootWindowOfScreen(XtScreen(boardWidget)),
307                               (bw_width - pw_width) / 2,
308                               0 - pw_height + squareSize / 3, &xx, &yy, &junk);
309         tagsX = xx;
310         tagsY = yy;
311 #endif
312         if (tagsY < 0) tagsY = 0; /*avoid positioning top offscreen*/
313     }
314     j = 0;
315     XtSetArg(args[j], XtNx, tagsX - appData.borderXoffset);  j++;
316     XtSetArg(args[j], XtNy, tagsY - appData.borderYoffset);  j++;
317     XtSetValues(shell, args, j);
318     XtSetKeyboardFocus(shell, textw);
319
320     return shell;
321 }
322
323
324 void TagsPopUp(tags, msg)
325      char *tags, *msg;
326 {
327     Arg args[16];
328     int j;
329     Widget textw, msgw;
330
331     if (editTagsUp) TagsPopDown();
332     if (tagsShell == NULL) {
333         tagsShell =
334           TagsCreate("Tags", tags, msg, False, TagsCallback);
335     } else {
336         textw = XtNameToWidget(tagsShell, "*form.text");
337         j = 0;
338         XtSetArg(args[j], XtNstring, tags); j++;
339         XtSetValues(textw, args, j);
340         j = 0;
341         XtSetArg(args[j], XtNiconName, (XtArgVal) "Tags");  j++;
342         XtSetArg(args[j], XtNtitle, (XtArgVal) "Tags");  j++;
343         XtSetValues(tagsShell, args, j);
344         msgw = XtNameToWidget(tagsShell, "*form.msg");
345         if (msgw) {
346             j = 0;
347             XtSetArg(args[j], XtNlabel, msg); j++;
348             XtSetValues(msgw, args, j);
349         }
350     }
351
352     XtPopup(tagsShell, XtGrabNone);
353     XSync(xDisplay, False);
354
355     tagsUp = True;
356     j = 0;
357     XtSetArg(args[j], XtNleftBitmap, None); j++;
358     XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Tags"),
359                 args, j);
360 }
361
362
363 void EditTagsPopUp(tags)
364      char *tags;
365 {
366     Widget textw;
367     Arg args[16];
368     int j;
369
370     if (tagsUp) TagsPopDown();
371     if (editTagsShell == NULL) {
372         editTagsShell =
373           TagsCreate("Edit tags", tags, NULL, True, EditTagsCallback); 
374     } else {
375         textw = XtNameToWidget(editTagsShell, "*form.text");
376         j = 0;
377         XtSetArg(args[j], XtNstring, tags); j++;
378         XtSetValues(textw, args, j);
379         j = 0;
380         XtSetArg(args[j], XtNiconName, (XtArgVal) "Edit Tags");  j++;
381         XtSetArg(args[j], XtNtitle, (XtArgVal) "Edit Tags");  j++;
382         XtSetValues(editTagsShell, args, j);
383     }
384
385     XtPopup(editTagsShell, XtGrabNone);
386
387     editTagsUp = True;
388     j = 0;
389     XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
390     XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Tags"),
391                 args, j);
392 }
393
394 void TagsPopDown()
395 {
396     Arg args[16];
397     int j;
398     Widget w;
399
400     if (tagsUp) {
401         w = tagsShell;
402     } else if (editTagsUp) {
403         w = editTagsShell;
404     } else {
405         return;
406     }
407     j = 0;
408     XtSetArg(args[j], XtNx, &tagsX); j++;
409     XtSetArg(args[j], XtNy, &tagsY); j++;
410     XtGetValues(w, args, j);
411     XtPopdown(w);
412     XSync(xDisplay, False);
413     tagsUp = editTagsUp = False;
414     j = 0;
415     XtSetArg(args[j], XtNleftBitmap, None); j++;
416     XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Tags"),
417                 args, j);
418 }
419
420 void
421 EditTagsProc(w, event, prms, nprms)
422      Widget w;
423      XEvent *event;
424      String *prms;
425      Cardinal *nprms;
426 {
427     if (tagsUp) TagsPopDown();
428     if (editTagsUp) {
429         TagsPopDown();
430     } else {
431         EditTagsEvent();
432     }
433 }