1 // $Id: Edit2.cxx 1116 2011-02-26 14:24:12Z martin $
2 //
3 // Edit2.cxx - routine for DRAWxtl V5.5 - the GUI version
4 //
5 // Coded using the FLTK 1.1.6 widget set
6 //
7 //     Larry W. Finger, Martin Kroeker and Brian Toby
8 //
9 // This module includes the majority of the edit screens for the GUI
10 //
11 // routines contained within this file:
12 //
13 //  Edit_Polyhedra_Close_cb - callback routine to dismiss Polyhedra Edit screen
14 //  Edit_Polyhedra_Save_cb - callback routine to update the polyhedral parameters
15 //  Edit_Spheres_cb - callback routine to load spheres edit screen
16 //  Edit_Spheres_Close_cb - callback routine to dismiss Sphere Edit screen
17 //  Edit_Spheres_Save_cb - callback routine to update the sphere parameters
18 //  Edit_STR_cb - callback routine to load Edit Str File screen
19 //  Edit_STR_Save_cb - callback routine to save "Edit Parameter" data
20 //  MapType_cb - callback routine to show or hide calculation button depending on map type
21 //  Map_Info_cb - callback routine to load map information screen
22 //  Lone_Pair_Combo_cb - updates widgets when atom in combo box is changed
23 //  LonePair_Frame_Combo_cb - callback routine enterd when frame combo box changed
24 //  Modify_Bonds_cb - callback routine entered when text selected in main text window
25 //  Modify_Bonds_Distance_cb - callback routine when text selected in "Bond To" distance panel
26 //  Modify_LonePair_cb - callback routine when LonePair text buffer modified
27 //  Modify_Maps_cb - callback routine entered when text selected in main text window
28 //  Modify_Polyhedra_cb - callback routine when text selected in PolyhedraBuffer
29 //  Modify_Polyhedra_Distance_cb - callback routine when text selected in "Polyhedra To" edit panel
30 //  Modify_Spheres_cb - callback routine when text selected in "Sphere Parameters" edit panel
31 //  New_Arrow_Add_cb - callback routine entered when 'Add' button pushed on Arrow Edit Screen
32 //  New_Arrow_Input_cb - callback routine entered when any of the entries on the arrow add section are changed
33 //  New_Bond_Add_cb - callback routine entered when 'Add' button pushed on Bond Edit Screen
34 //  New_Bond_Input_cb - callback routine entered when any of the entries on the bond add line are changed
35 //  New_Lone_Pair_Add_cb - callback routine entered when lone pair cone added
36 //  New_Polyhedra_Add_cb - callback routine entered when 'Add' button pushed on Polyhedra Edit Screen
37 //  New_Polyhedra_Input_cb - callback routine entered when any of the entries on the polyhedra add line are changed
38 //  New_Sphere_Input_cb - callback routine entered when new sphere added
39 //  next_focus - routine to select next widget for focus when <TAB> is pressed
40 //  Polyhedra_Combo_cb - callback routine entered when atom in combo box is changed
41 //  Polyhedra_Frame_Combo_cb - callback entered when frame combo is changed
42 //  Sphere_Combo_cb - callback when Sphere combo box clicked
43 //  Sphere_Frame_Combo_cb - callback entered when frame combo is changed
44 //  View_Console_cb - callback routine to view console listing
45 //  View_Cursor_cb - callback routine to view cursor feedback window
46 //  View_File_cb - callback routine to view any file
47 //  View_Listing_cb - callback to view listing file
48 //  View_List_Close_cb - callback to close str file editor window
49 //  View_Listing_Close_cb - callback to close Listing windows
50 //  View_POV_cb - callback to view the POV file
51 
52 #include "drawxtl.h"
53 #include "DRAWxtlViewUI.h"
54 #include "gl2ps.h"
55 #include "EditView.h"
56 #include "Ellipsoids.h"
57 #include "draw_ext.h"
58 #if WIN32
59 #include <direct.h>
60 #else
61 #include <unistd.h>
62 #define _chdir chdir
63 #endif
64 #include <ctype.h>
65 
66 #include "DRAWxtl_proto.h"
67 
68 static int zero2 = 0;
69 
70 static int three = 3;
71 
72 extern char Edit_title[128];
73 
74 #ifdef WIN32
75 const char *flu_file_chooser (const char *message, const char *pattern,
76 			      const char *filename);
77 #endif
78 
79 void
Edit_Polyhedra_Close_cb(void)80 Edit_Polyhedra_Close_cb (void)
81 {
82     Polyhedra->Polyhedra_Edit_Window->hide ();
83     Restore_Working_Copy ();	// undo any changes
84     Generate_Drawing (1);	// regenerate
85 }
86 
87 void
Edit_Polyhedra_Save_cb(Fl_Button *,int * save)88 Edit_Polyhedra_Save_cb (Fl_Button *, int *save)
89 {
90 // callback routine when 'save' or 'apply' button is pressed on the Edit Polyhhedra screen
91     char atom1[5], atom2[5], color[40], widget[16382], type[3];
92 
93     char tmp[20];
94 
95     int i = 0;
96 
97     int np = 0;
98 
99     unsigned int j, k;
100 
101     int l;
102 
103     float d1, d2, transp;
104 
105     int Frame_No = 1;
106 
107     char *selection;
108 
109     if (drvui->max_frame > 1) {
110 	Frame_No = atoi (Polyhedra->Frame_No->value ());
111 	for (i = 1, j = 1; i < drvui->npoly; i++) {	// copy parameters for other frames to
112 	    if (drvui->polyhedra[i].poly_fn != Frame_No) {	//   start of list
113 		if ((int) j != i) {
114 		    drvui->polyhedra[j].poly_fn = drvui->polyhedra[i].poly_fn;
115 		    strncpy (drvui->polyhedra[j].poly_col, drvui->polyhedra[i].poly_col,
116 			     40);
117 		    strncpy (drvui->polyhedra[j].poly_l, drvui->polyhedra[i].poly_l, 4);
118 		    strncpy (drvui->polyhedra[j].poly_t, drvui->polyhedra[i].poly_t, 4);
119 		    drvui->polyhedra[j].poly_min = drvui->polyhedra[i].poly_min;
120 		    drvui->polyhedra[j].poly_size = drvui->polyhedra[i].poly_size;
121 		}
122 		j++;
123 	    }
124 	}
125 	drvui->npoly = j;
126 	for (i = 1, j = 1; i < drvui->nplane; i++) {	// copy parameters for other frames to
127 	    if (drvui->planes[i].plane_fn != Frame_No) {	//   start of list
128 		if ((int) j != i) {
129 		    drvui->planes[j].plane_fn = drvui->planes[i].plane_fn;
130 		    strncpy (drvui->planes[j].plane_col, drvui->planes[i].plane_col, 40);
131 		    strncpy (drvui->planes[j].plane_l, drvui->planes[i].plane_l, 4);
132 		    drvui->planes[j].plane_size = drvui->planes[i].plane_size;
133 		}
134 		j++;
135 	    }
136 	}
137 	drvui->nplane = j;
138 	i = drvui->npoly - 1;
139     }
140     selection = Polyhedra->PolyhedraBuffer->text ();
141     strcpy (widget, selection);
142     free (selection);
143     drvui->npoly = 0;
144     drvui->nplane = 0;
145     if (strlen (widget) < 10) {
146 	strcpy (widget, "");
147 	Polyhedra->PolyhedraBuffer->text (widget);
148     } else {
149 	while (strlen (widget) > 10) {
150 	    i++;
151 	    sscanf (widget, " %s", type);
152 	    strcpy (atom2, "");
153 	    transp = 0.;
154 	    if (!strncmp (type, "PS", 2) || !strncmp (type, "SH", 2)
155 		|| !strncmp (type, "PL", 2)) {
156 		sscanf (widget, "%s %s %f %f %s %s %f", type, atom1, &d1, &d2, color, tmp,
157 			&transp);
158 		strcpy (atom2, "");
159 		strcpy (drvui->polyhedra[i].poly_t, atom2);
160 	    } else {
161 		sscanf (widget, "%s %s %s %f %f %s %s %f", type, atom1, atom2, &d1, &d2,
162 			color, tmp, &transp);
163 		strcpy (drvui->polyhedra[i].poly_t, atom2);
164 	    }
165 	    trim_string (color, 40);
166 	    if (!strlen (color))
167 		strcpy (color, "Gray20");
168 	    if (isdigit (color[0]) || color[0] == '.') {
169 		char color1[10], color2[10], color3[10];
170 
171 		if (!strncmp (type, "PS", 2) || !strncmp (type, "SH", 2)
172 		    || !strncmp (type, "PL", 2)) {
173 		    sscanf (widget, "%s %s %f %f %s %s %s %s %f", type, atom1, &d1, &d2,
174 			    color1, color2, color3, tmp, &transp);
175 		    strcpy (atom2, "");
176 		    strcpy (drvui->polyhedra[i].poly_t, atom2);
177 		} else {
178 		    sscanf (widget, "%s %s %s %f %f %s %s %s %s %f", type, atom1, atom2,
179 			    &d1, &d2, color1, color2, color3, tmp, &transp);
180 		    strcpy (drvui->polyhedra[i].poly_t, atom2);
181 		}
182 		strcpy (color, color1);
183 		strcat (color, " ");
184 		strcat (color, color2);
185 		strcat (color, " ");
186 		strcat (color, color3);
187 		trim_string (color, 40);
188 	    }
189 	    if (transp > 0.0f) {
190 		sprintf (tmp, " filter %.3f", transp);
191 		strcat (color, tmp);
192 	    }
193 	    if (!strncmp (type, "PL", 2)) {
194 		np++;
195 		drvui->planes[np].plane_size = d2;
196 		strncpy (drvui->planes[np].plane_col, color, 25);
197 		strcpy (drvui->planes[np].plane_l, atom1);
198 		drvui->planes[np].plane_fn = Frame_No;
199 		drvui->nplane = np + 1;
200 	    } else {
201 		strncpy (drvui->polyhedra[i - np].poly_l, atom1, 4);
202 		drvui->polyhedra[i - np].poly_min = d1;
203 		drvui->polyhedra[i - np].poly_size = d2;
204 		strcpy (drvui->polyhedra[i - np].poly_col, color);
205 		drvui->polyhedra[i - np].poly_fn = Frame_No;
206 		drvui->npoly = i + 1 - np;
207 		for (l = 0; l < drvui->nedges; l++) {
208 		    if (!strcmp (drvui->polyedges[l].name, atom1)) {
209 			strcpy (drvui->polyhedra[i-np].poly_col_edge, drvui->polyedges[l].color);
210 			drvui->polyhedra[i-np].poly_rad_edge = drvui->polyedges[l].radius;
211 			break;
212 		    }
213 		}
214 	    }
215 	    for (j = 0; j < strlen (widget); j++) {
216 		if (widget[j] == '\n')
217 		    break;
218 	    }
219 	    for (j++, k = 0; j < strlen (widget); j++)
220 		widget[k++] = widget[j];
221 	    widget[k] = 0;
222 	}
223     }
224     strcpy (drvui->col_edge, Polyhedra->Def_Edge_Color->value ());
225     drvui->rad_edge = (float) atof (Polyhedra->Def_Edge_Radius->value ());
226     if (drvui->rad_edge > 0.0)
227 	edges = 2;
228     drvui->Str_File_Changed = 1;
229     Update_Str (0);
230     Generate_Drawing (0);
231     if (*save != 3) {
232 	Save_Working_Copy ();
233 	Polyhedra->PolyInstr2->hide ();
234     }
235     if (*save == 1) {
236 	Polyhedra->Polyhedra_Edit_Window->hide ();
237     }
238     Fl::redraw ();
239 }
240 
241 void
Edit_Slab_cb(void)242 Edit_Slab_cb (void)
243 {
244 // routine to create the edit slab screen
245     char string[100];
246 
247     static int one = 1;
248 
249     int y = 50;
250 
251     static const Fl_Menu_Item slabmodes[] = {
252 	{"ignore", 0, NULL, (void *) 0, 0, 0, 0, 14, 56},
253 	{"apply", 0, NULL, (void *) 0, 0, 0, 0, 14, 56},
254 	{"show", 0, NULL, (void *) 0, 0, 0, 0, 14, 56},
255 	{0, 0, 0, 0, 0, 0, 0, 0, 0}
256     };
257 
258     if (!strlen (drvui->CurFile->value ())) {	// Make sure rendering enabled
259 	Error_Box ("A Structure File must be selected first.");
260 	return;
261     }
262     if (!Slabs) {
263 	Slabs = new SlabParam;	// new instance of the slab parameters
264 	Slabs->SlabWindow = new Fl_Window (50, 50, 400, 430, "Edit Slab Parameters");
265 	Slabs->SlabWindow->callback ((Fl_Callback *) Edit_Slab_Close_cb);
266 	{
267 	    Fl_Text_Display *o = new Fl_Text_Display (0, y, 400, 0, "Slab Dimensions");
268 
269 	    o->box (FL_NO_BOX);
270 	    o->labelfont (1);
271 	    o->textcolor (1);
272 	}
273 	y += 25;
274 	Slabs->Slab_A = new Fl_Input (20, y, 100, 25, "a");
275 	Slabs->Slab_A->align (FL_ALIGN_TOP);
276 	Slabs->Slab_A->labelfont (1);
277 
278 	Slabs->Slab_B = new Fl_Input (150, y, 100, 25, "b");
279 	Slabs->Slab_B->align (FL_ALIGN_TOP);
280 	Slabs->Slab_B->labelfont (1);
281 
282 	Slabs->Slab_C = new Fl_Input (280, y, 100, 25, "c");
283 	Slabs->Slab_C->align (FL_ALIGN_TOP);
284 	Slabs->Slab_C->labelfont (1);
285 
286 	y += 40;
287 	Slabs->Slab_Alpha = new Fl_Input (20, y, 100, 25, "alpha");
288 	Slabs->Slab_Alpha->align (FL_ALIGN_TOP);
289 	Slabs->Slab_Alpha->labelfont (1);
290 
291 	Slabs->Slab_Beta = new Fl_Input (150, y, 100, 25, "beta");
292 	Slabs->Slab_Beta->align (FL_ALIGN_TOP);
293 	Slabs->Slab_Beta->labelfont (1);
294 
295 	Slabs->Slab_Gamma = new Fl_Input (280, y, 100, 25, "gamma");
296 	Slabs->Slab_Gamma->align (FL_ALIGN_TOP);
297 	Slabs->Slab_Gamma->labelfont (1);
298 
299 	y += 60;
300 	{
301 	    Fl_Text_Display *o = new Fl_Text_Display (0, y, 400, 0, "Slab Orientation");
302 
303 	    o->box (FL_NO_BOX);
304 	    o->labelfont (1);
305 	    o->textcolor (1);
306 	}
307 
308 	y += 30;
309 	Slabs->Slab_Off_X = new Fl_Input (20, y, 100, 25, "X Offset");
310 	Slabs->Slab_Off_X->align (FL_ALIGN_TOP);
311 	Slabs->Slab_Off_X->labelfont (1);
312 
313 	Slabs->Slab_Off_Y = new Fl_Input (150, y, 100, 25, "Y Offset");
314 	Slabs->Slab_Off_Y->align (FL_ALIGN_TOP);
315 	Slabs->Slab_Off_Y->labelfont (1);
316 
317 	Slabs->Slab_Off_Z = new Fl_Input (280, y, 100, 25, "Z Offset");
318 	Slabs->Slab_Off_Z->align (FL_ALIGN_TOP);
319 	Slabs->Slab_Off_Z->labelfont (1);
320 
321 	y += 60;
322 	Slabs->Slab_Rot_X = new Fl_Input (20, y, 100, 25, "X Rotation");
323 	Slabs->Slab_Rot_X->align (FL_ALIGN_TOP);
324 	Slabs->Slab_Rot_X->labelfont (1);
325 
326 	Slabs->Slab_Rot_Y = new Fl_Input (150, y, 100, 25, "Y Rotation");
327 	Slabs->Slab_Rot_Y->align (FL_ALIGN_TOP);
328 	Slabs->Slab_Rot_Y->labelfont (1);
329 
330 	Slabs->Slab_Rot_Z = new Fl_Input (280, y, 100, 25, "Z Rotation");
331 	Slabs->Slab_Rot_Z->align (FL_ALIGN_TOP);
332 	Slabs->Slab_Rot_Z->labelfont (1);
333 
334 	y += 60;
335 	Slabs->Slab_Mode = new Fl_Choice (175, y, 70, 25, "Slab Mode");
336 	Slabs->Slab_Mode->align (FL_ALIGN_TOP);
337 	Slabs->Slab_Mode->labelfont (1);
338 	Slabs->Slab_Mode->menu (slabmodes);
339 
340 	Slabs->Slab_Mode->value (slabmode);
341 
342 #if !defined (WIN32) && !defined (__APPLE__)
343 	Slabs->SlabWindow->icon ((char *) drvui->icon);
344 #endif
345 	y += 60;
346 	Fl_Button *r = new Fl_Button (65, y, 70, 25, "Close");
347 
348 	r->tooltip ("Close this window and discard all changes.");
349 	r->callback ((Fl_Callback *) Edit_Slab_Close_cb);
350 	Fl_Button *s = new Fl_Button (265, y, 70, 25, "Save");
351 
352 	s->tooltip
353 	    ("Apply current contents of top box to drawing, then close this window.");
354 	s->callback ((Fl_Callback *) Edit_Slab_Save_cb, &one);
355 	Fl_Button *a = new Fl_Button (165, y, 70, 25, "Apply");
356 
357 	a->tooltip
358 	    ("Apply current contents of top box to drawing, but leave this window open.");
359 	a->callback ((Fl_Callback *) Edit_Slab_Save_cb, &zero2);
360 	Slabs->SlabWindow->end ();
361     }
362     sprintf (string, "%6.3f", drvui->slab_con[0]);
363     Slabs->Slab_A->value (string);
364     sprintf (string, "%6.3f", drvui->slab_con[1]);
365     Slabs->Slab_B->value (string);
366     sprintf (string, "%6.3f", drvui->slab_con[2]);
367     Slabs->Slab_C->value (string);
368     sprintf (string, "%6.3f", drvui->slab_con[3]);
369     Slabs->Slab_Alpha->value (string);
370     sprintf (string, "%6.3f", drvui->slab_con[4]);
371     Slabs->Slab_Beta->value (string);
372     sprintf (string, "%6.3f", drvui->slab_con[5]);
373     Slabs->Slab_Gamma->value (string);
374     sprintf (string, "%6.3f", drvui->slab_off[0]);
375     Slabs->Slab_Off_X->value (string);
376     sprintf (string, "%6.3f", drvui->slab_off[1]);
377     Slabs->Slab_Off_Y->value (string);
378     sprintf (string, "%6.3f", drvui->slab_off[2]);
379     Slabs->Slab_Off_Z->value (string);
380     sprintf (string, "%6.3f", drvui->slab_rot[0]);
381     Slabs->Slab_Rot_X->value (string);
382     sprintf (string, "%6.3f", drvui->slab_rot[1]);
383     Slabs->Slab_Rot_Y->value (string);
384     sprintf (string, "%6.3f", drvui->slab_rot[2]);
385     Slabs->Slab_Rot_Z->value (string);
386     Slabs->SlabWindow->show ();
387 }
388 
389 void
Edit_Slab_Close_cb(void)390 Edit_Slab_Close_cb (void)
391 {
392     Slabs->SlabWindow->hide ();
393 }
394 
395 void
Edit_Slab_Save_cb(Fl_Button *,int * save)396 Edit_Slab_Save_cb (Fl_Button *, int *save)
397 {
398 // callback routine when 'save' or 'apply' button is pressed on the Edit Slab screen
399 
400     Omit->nomits = 0;
401     drvui->slab_con[0] = (float) atof (Slabs->Slab_A->value ());
402     drvui->slab_con[1] = (float) atof (Slabs->Slab_B->value ());
403     drvui->slab_con[2] = (float) atof (Slabs->Slab_C->value ());
404     drvui->slab_con[3] = (float) atof (Slabs->Slab_Alpha->value ());
405     drvui->slab_con[4] = (float) atof (Slabs->Slab_Beta->value ());
406     drvui->slab_con[5] = (float) atof (Slabs->Slab_Gamma->value ());
407     drvui->slab_off[0] = (float) atof (Slabs->Slab_Off_X->value ());
408     drvui->slab_off[1] = (float) atof (Slabs->Slab_Off_Y->value ());
409     drvui->slab_off[2] = (float) atof (Slabs->Slab_Off_Z->value ());
410     drvui->slab_rot[0] = (float) atof (Slabs->Slab_Rot_X->value ());
411     drvui->slab_rot[1] = (float) atof (Slabs->Slab_Rot_Y->value ());
412     drvui->slab_rot[2] = (float) atof (Slabs->Slab_Rot_Z->value ());
413     slabmode = Slabs->Slab_Mode->value ();
414     drvui->Str_File_Changed = 1;
415     if (*save) {
416 	Slabs->SlabWindow->hide ();
417     }
418     Update_Str (0);
419     Generate_Drawing (0);
420     Fl::redraw ();
421 }
422 
423 void
Edit_Spheres_cb(void)424 Edit_Spheres_cb (void)
425 {
426 // callback routine to load sphere edit screen
427     char string[100];
428 
429     static int one = 1;
430 
431     static int two = 2;
432 
433     int i;
434 
435     int y_size = 120;
436 
437     int y = 25;
438 
439     if (!strlen (drvui->CurFile->value ())) {	// Make sure rendering enabled
440 	Error_Box ("A Structure File must be selected first.");
441 	return;
442     }
443 /*
444     if (!natom) {         // No atoms, no spheres...
445         Error_Box("This structure file does not contain any atoms.");
446         return;
447     }
448 */
449     Save_Working_Copy ();	// save the working str file
450     if (!Spheres) {
451 	Spheres = new SphereParam;	// new instance of the spheres parameters
452 	Spheres->Sphere_Edit_Window =
453 	    new Fl_Window (100, 100, 460, 350, "Edit Sphere Parameters");
454 	Spheres->Sphere_Edit_Window->callback ((Fl_Callback *) Edit_Spheres_Close_cb);
455 	Spheres->Sphere_Output_Buffer = NULL;
456 	Spheres->SphereBuffer = NULL;
457 	if (drvui->max_frame > 1) {
458 	    Flu_Combo_List *o = Spheres->Frame_No =
459 		new Flu_Combo_List (180, y, 75, 25, "Frame No.");
460 	    o->align (FL_ALIGN_TOP);
461 	    o->callback (Sphere_Frame_Combo_cb);
462 	    o->labelfont (1);
463 	    for (i = 1; i <= drvui->max_frame; i++) {
464 		sprintf (string, "%d", i);
465 		o->list.add (string);
466 	    }
467 	    o->pop_height (20 * drvui->max_frame);
468 	    o->value ("1");
469 	    y += 40;
470 	    y_size -= 40;
471 	}
472 	Spheres->Sphere_Edit = new Fl_Text_Editor (25, y, 410, y_size,
473 						   "Atom     Size     Color                         ");
474 	Spheres->SphereBuffer = new Fl_Text_Buffer;
475 	Spheres->SphereBuffer->add_modify_callback ((Fl_Text_Modify_Cb) Modify_Spheres_cb,
476 						    (void *) NULL);
477 	y += 5 + y_size;
478 	Spheres->SphereInstr = new Fl_Output (25, y, 410, 0, "Press 'Add' to replace "
479 					      "selected line - 'Remove' to delete it");
480 	Spheres->SphereInstr->hide ();
481 	Spheres->SphereInstr->align (FL_ALIGN_BOTTOM);
482 	Spheres->SphereInstr1 = new Fl_Output (25, y, 410, 0,
483 					       "Highlight or double-click text above to edit");
484 	Spheres->SphereInstr1->hide ();
485 	Spheres->SphereInstr1->align (FL_ALIGN_BOTTOM);
486 	Spheres->Sphere_Edit->textfont (FL_COURIER);
487 	Spheres->Sphere_Edit->textsize (12);
488 	Spheres->Sphere_Edit->buffer (Spheres->SphereBuffer);
489 	Spheres->Sphere_Edit->labelfont (FL_COURIER_BOLD);
490 	y += 40;
491 	Flu_Combo_List *o = Spheres->Sphere_Combo =
492 	    new Flu_Combo_List (55, y, 100, 25, "Atom");
493 	o->align (FL_ALIGN_TOP);
494 	o->callback (Sphere_Combo_cb);
495 	o->labelfont (1);
496 	Fl_Input *os = Spheres->New_Sphere_Size = new Fl_Input (165, y, 50, 25, "Size");
497 
498 	os->align (FL_ALIGN_TOP);
499 	os->callback ((Fl_Callback *) New_Sphere_Input_cb);
500 	os->labelfont (1);
501 	Flu_Combo_List *ot = Spheres->New_Sphere_Color =
502 	    new Flu_Combo_List (225, y, 160, 25, "Color");
503 	Load_Color_Combo (ot);
504 	ot->align (FL_ALIGN_TOP);
505 	ot->callback ((Fl_Callback *) New_Sphere_Input_cb);
506 	ot->labelfont (1);
507 	y += 30;
508 	Fl_Button *om = Spheres->New_Sphere_Add = new Fl_Button (105, y, 70, 25, "Add");
509 
510 	om->callback ((Fl_Callback *) New_Sphere_Add_cb, &one);
511 	om->tooltip ("When active, press to transfer data in boxes to window above");
512 	om->deactivate ();
513 	Fl_Button *mm = Spheres->New_Sphere_Remove =
514 	    new Fl_Button (195, y, 70, 25, "Remove");
515 	mm->callback ((Fl_Callback *) New_Sphere_Add_cb, &zero2);
516 	mm->tooltip ("When active, press to remove highlighted line.");
517 	mm->deactivate ();
518 	Fl_Button *pm = Spheres->New_Sphere_Convert =
519 	    new Fl_Button (285, y, 70, 25, "Convert");
520 	pm->callback ((Fl_Callback *) New_Sphere_Add_cb, &two);
521 	pm->tooltip
522 	    ("When active, press to convert atom in boxes from sphere to ellipsoid");
523 	pm->deactivate ();
524 	y += 40;
525 	Spheres->SphereInstr2 = new Fl_Output (25, y, 410, 0,
526 					       "Changes are temporary until \"Apply\" or \"Save\" is pressed.");
527 	Spheres->SphereInstr2->hide ();
528 	Spheres->SphereInstr2->align (FL_ALIGN_BOTTOM);
529 	y += 30;
530 	Fl_Button *r = new Fl_Button (105, y, 70, 25, "Close");
531 
532 	r->tooltip ("Close this window and discard all changes.");
533 	r->callback ((Fl_Callback *) Edit_Spheres_Close_cb);
534 	Fl_Button *s = new Fl_Button (285, y, 70, 25, "Save");
535 
536 	s->tooltip
537 	    ("Apply current contents of top box to drawing, then close this window.");
538 	s->callback ((Fl_Callback *) Edit_Spheres_Save_cb, &one);
539 	Fl_Button *a = new Fl_Button (195, y, 70, 25, "Apply");
540 
541 	a->tooltip
542 	    ("Apply current contents of top box to drawing, but leave this window open.");
543 	a->callback ((Fl_Callback *) Edit_Spheres_Save_cb, &zero2);
544 	Spheres->Sphere_Edit_Window->end ();
545 #if !defined (WIN32) && !defined (__APPLE__)
546 	Spheres->Sphere_Edit_Window->icon ((char *) drvui->icon);
547 #endif
548     }
549     Sphere_Frame_Combo_cb (NULL, NULL);
550     Spheres->Sphere_Edit_Window->show ();
551 }
552 
553 void
Edit_Spheres_Close_cb(void)554 Edit_Spheres_Close_cb (void)
555 {
556     drvui->destroy |= SPHERE;
557     Spheres->Sphere_Edit_Window->hide ();
558     Restore_Working_Copy ();	// undo any changes
559     Generate_Drawing (1);	// regenerate
560 }
561 
562 void
Edit_Spheres_Save_cb(Fl_Button *,int * save)563 Edit_Spheres_Save_cb (Fl_Button *, int *save)
564 {
565 // callback routine when 'save' or 'apply' button is pressed on the Edit Spheres screen
566 // save == 0 - apply the changes and update saved working copy
567 // save == 1 - save the changes and close the window
568 // save == 3 - apply the changes but do not update saved working copy
569     char atom1[5], color[40], widget[16382];
570 
571     int j, k;
572 
573     int i = 0, n;
574 
575     float d1;
576 
577     int Frame_No = 1;
578 
579     if (drvui->max_frame > 1) {
580 	Frame_No = atoi (Spheres->Frame_No->value ());
581 	for (i = 1, j = 1; i < drvui->nsphere; i++) {	// copy parameters for other frames to
582 	    if (drvui->spheres[i].sphere_fn != Frame_No) {	//   start of list
583 		if ((int) j != i) {
584 		    drvui->spheres[j].sphere_fn = drvui->spheres[i].sphere_fn;
585 		    strcpy (drvui->spheres[j].sphere_col, drvui->spheres[i].sphere_col);
586 		    strcpy (drvui->spheres[j].sphere_l, drvui->spheres[i].sphere_l);
587 		    drvui->spheres[j].sphere_size = drvui->spheres[i].sphere_size;
588 		    drvui->spheres[j].sphere_n = drvui->spheres[i].sphere_n;
589 		}
590 		j++;
591 	    }
592 	}
593 	i = j - 1;
594     }
595     char *selection = Spheres->SphereBuffer->text ();
596 
597     strcpy (widget, selection);
598     free (selection);
599     if (strlen (widget) < 10) {
600 	drvui->nsphere = i + 1;	// sum over all frames or zero
601 	strcpy (widget, "");
602 	Spheres->SphereBuffer->text (widget);
603     } else {
604 	while (strlen (widget) > 10) {
605 	    i++;
606 	    char filter1[10], filter2[10], numb[5];
607 
608 	    memset (filter1, 0, 10);
609 	    (void) sscanf (widget, "%s %s %f %s %s %s", atom1, numb, &d1, color, filter1,
610 			   filter2);
611 	    strcpy (drvui->spheres[i].sphere_l, atom1);
612 	    drvui->spheres[i].sphere_size = d1;
613 	    if (!strcmp (filter1, "filter")) {
614 		strcat (color, " ");
615 		strcat (color, filter1);
616 		strcat (color, " ");
617 		strcat (color, filter2);
618 	    }
619 	    strcpy (drvui->spheres[i].sphere_col, color);
620 	    drvui->spheres[i].sphere_fn = Frame_No;
621 	    if (strstr (numb, "*"))
622 		n = -1;
623 	    else
624 		(void) sscanf (numb, "%d", &n);
625 	    drvui->spheres[i].sphere_n = n;
626 	    drvui->nsphere = i + 1;
627 	    for (j = 0; j < (int) strlen (widget); j++) {
628 		if (widget[j] == '\n')
629 		    break;
630 	    }
631 	    for (j++, k = 0; j < (int) strlen (widget); j++)
632 		widget[k++] = widget[j];
633 	    widget[k] = 0;
634 	}
635     }
636     drvui->Str_File_Changed = 1;
637     if (*save != 3) {
638 	Save_Working_Copy ();
639 	Spheres->SphereInstr2->hide ();
640     }
641     if (*save == 1) {
642 	drvui->destroy |= SPHERE;
643 	Spheres->Sphere_Edit_Window->hide ();
644     }
645     Update_Str (0);
646     Generate_Drawing (0);
647     Fl::redraw ();
648 }
649 
650 void
Edit_STR_cb(Fl_Menu_ *,void * arg)651 Edit_STR_cb (Fl_Menu_ *, void *arg)	// routine to edit the str file
652 {
653     int r;
654     const char *tempname;
655 
656     static int one = 1;
657 
658     static int mone = -1;
659 
660     if (textwindow) {
661 	textwindow->hide ();
662 	textwindow->~Fl_Window ();
663 	delete (textbuf);
664 	delete (textwindow);
665     }
666     if (!strlen (drvui->Cur_File)) {
667 	r =fl_choice ("A Structure File must be selected first.","Ok","Create new",NULL);
668 	if (!r) return;
669 	tempname=(fl_input("Enter filename","unnamed.str"));
670 	if (!tempname) return;
671 	strcpy(drvui->Cur_File,tempname);
672     }
673 // callback routine to display Edit Str File screen
674     Edit_Str_Type = arg;
675     if (arg) {
676 	if (strlen (drvui->Cur_File) < 2)
677 	    return;
678 	strcpy (Edit_title, "Edit Original Version of STR File");
679     } else {
680 	if (strlen (drvui->Cur_Temp) < 2)
681 	    return;
682 	strcpy (Edit_title, "Edit Working Copy of STR File");
683 	Update_Str (0);		// make str file current
684     }
685     Edit_changed = 0;
686     Edit_loading = 1;
687     textwindow = new Fl_Window (20, 20, 480, 550, Edit_title);
688     textwindow->begin ();
689     textwindow->callback ((Fl_Callback *) Edit_STR_Close_cb);
690     Fl_Text_Editor *display = new Fl_Text_Editor (0, 0, 480, 510);
691 
692     display->textfont (FL_COURIER);
693     display->textsize (12);
694     textbuf = new Fl_Text_Buffer;
695     display->buffer (textbuf);
696     textbuf->add_modify_callback (Edit_Changed_cb, textwindow);
697     textbuf->call_modify_callbacks ();
698 
699     Fl_Button *o = new Fl_Button (50, 515, 80, 30, "Close");
700 
701     o->tooltip ("Close this window and discard all changes.");
702     o->callback ((Fl_Callback *) Edit_STR_Close_cb);
703     Fl_Button *oo = new Fl_Button (150, 515, 80, 30, "Apply");
704 
705     oo->tooltip ("Apply current contents to drawing, but leave this window open.");
706     oo->callback ((Fl_Callback *) Edit_STR_Save_cb, &mone);
707     Fl_Button *po = new Fl_Button (250, 515, 80, 30, "Save");
708 
709     po->tooltip ("Apply current contents to drawing, then close this window.");
710     po->callback ((Fl_Callback *) Edit_STR_Save_cb, &zero2);
711     Fl_Button *op = new Fl_Button (350, 515, 80, 30, "Save As");
712 
713     op->callback ((Fl_Callback *) Edit_STR_Save_cb, &one);
714     op->tooltip ("Rewrite current contents to new file, and close this window.");
715     if (arg) {
716 	textbuf->loadfile (drvui->Cur_File);
717     } else {
718 	textbuf->loadfile (drvui->Cur_Temp);
719     }
720     Edit_loading = 0;
721 #if !defined (WIN32) && !defined (__APPLE__)
722     textwindow->icon ((char *) drvui->icon);
723 #endif
724     textwindow->end ();
725     textwindow->resizable (textwindow);
726     textwindow->show ();
727 }
728 
729 void
Edit_STR_Close_cb(void)730 Edit_STR_Close_cb (void)	// callback to destruct editor window
731 {
732 // callback to close the STR edit screen
733     if (Edit_changed) {		// buffer changed - query user
734 	int r = fl_choice ("The current file has been modified, but not saved.\n"
735 			   "Would you like to save it now?",
736 			   "Cancel", "Yes", "No");
737 
738 	if (r == 1) {
739 	    drvui->Str_File_Changed = 1;
740 	    Edit_STR_Save_cb (NULL, &zero2);
741 	    return;
742 	}
743 	if (r == 0)
744 	    return;
745     }
746     drvui->destroy |= TEXT1;
747     textwindow->hide ();
748 }
749 
750 void
Edit_STR_Save_cb(Fl_Button *,int * action)751 Edit_STR_Save_cb (Fl_Button *, int *action)	// callback to save edited str file
752 {
753 // callback routine to save edit parameter data
754     FILE *file;
755 
756     char *selection;
757 
758     drvui->Str_File_Changed = 1;
759     if (*action > 0) {		// true for 'Save As'
760 #if defined(WIN32)
761 	char drive[_MAX_DRIVE];
762 
763 	char dir[_MAX_DIR];
764 
765 	char fname[_MAX_FNAME];
766 
767 	char ext[_MAX_EXT];
768 
769 	const char *newfile =
770 	    flu_file_chooser ("Select New Name for Data/Experiment File",
771 			      "*.str", drvui->Cur_File);
772 
773 	if (newfile) {
774 	    _splitpath (newfile, drive, dir, fname, ext);	//Windows code
775 	    strcpy (drvui->Cur_Dir, drive);	// Drive letter
776 	    strcat (drvui->Cur_Dir, dir);	//   and directory
777 	    strcpy (drvui->Cur_File, fname);	// copy file name
778 	    strcat (drvui->Cur_File, ext);	// and add extension
779 #else
780 	int i, k = 0;
781 
782 	char *newfile =
783 	    fl_file_chooser ("Select New Name for Data/Experiment File", "*.str",
784 			     drvui->Cur_File);
785 
786 	if (newfile) {
787 	    strcpy (drvui->Cur_File, newfile);
788 	    strcpy (drvui->Cur_Dir, newfile);
789 	    for (i = strlen (drvui->Cur_Dir); i > 0; --i) {	// Find final / in file name
790 		if (drvui->Cur_Dir[i - 1] == '/') {
791 		    drvui->Cur_Dir[i] = 0;
792 		    break;
793 		}
794 	    }
795 	    for (i = strlen (drvui->Cur_Dir); newfile[i] != 0; i++) {
796 		drvui->Cur_File[k++] = newfile[i];	// copy file name to Cur_File
797 	    }
798 	    drvui->Cur_File[k] = 0;
799 #endif
800 	    chdir (drvui->Cur_Dir);	// switch to new directory
801 	    if ((file = fopen (drvui->Cur_File, "r"))) {
802 		if (!fl_choice ("Selected file exists. Do you wish to overwrite it?",
803 				"No", "Yes", NULL)) {
804 		    return;
805 		}
806 	    }
807 	    WriteConfig ();
808 	}
809     }				// end of *action > 0
810     if (Edit_Str_Type || *action > 0) {
811 	file = fopen (drvui->Cur_File, "w");	// open new or existing file for writing
812 	if (!file) {
813 	    Error_Box ("Unable to open STR file for writing");
814 	    return;
815 	}
816     } else {
817 	file = fopen (drvui->Cur_Temp, "w");
818 	if (!file) {
819 	    Error_Box ("Unable to open TMP file for writing");
820 	    return;
821 	}
822     }
823 
824     selection = textbuf->text ();
825     fprintf (file, "%s", selection);	// copy text from window to file
826     free (selection);
827     fclose (file);		// close the file
828     Edit_changed = 0;
829     if (Edit_Str_Type) {
830 	Process_Inp (2);
831     } else {
832 	int l,m;
833 	drvui->fpin = fopen (drvui->Cur_Temp, "r");	// set up to process tmp file
834 	natom = 0;
835 	Omit->nomits = 0;
836 	drvui->frame_no = 1;
837 	drvui->modulated = 0;
838 	drvui->no_mod_vectors = 0;
839 	drvui->no_site_displace = 0;
840 	drvui->no_site_U_terms = 0;
841 	drvui->no_site_occ = 0;
842 	drvui->no_cell_vec = 0;
843 
844 	drvui->sys=0;               /* reset crystal system/symmetry and */
845 	drvui->no_subsys = 1;       /* initialize the subsystem variables */
846 	for (l = 0; l < 3; l++) {
847 	    for (m = 0; m < 3; m++)
848 		drvui->subsys_fact[0][l][m] = 0.0f;
849 	    drvui->subsys_fact[0][l][l] = 1.0f;     /* set to identity */
850 	}
851 	drvui->subsys_ref_volume = 1.0f;
852 	drvui->subsys_vol[0] = 1.0;
853 	ShowMapLegend = 0;
854 	read_inp (2);
855 	make_bmat (drvui->sys, drvui->lat_con, drvui->b_mat, drvui->ginv, drvui->rec_lat_con);
856 
857 	fclose (drvui->fpin);
858     }
859     Generate_Drawing (0);
860     if (*action >= 0) {
861 	drvui->destroy |= TEXT1;
862 	textwindow->hide ();
863     }
864     Fl::redraw ();
865 }
866 
867 void
868 Lone_Pair_Combo_cb (Fl_Widget *, void *)
869 {
870 // load other widgets when the atom in the combo box is changed
871     if (strlen (LonePairs->Height->value ()) == 0)
872 	return;
873     if (strlen (LonePairs->Radius1->value ()) == 0)
874 	return;
875     if (strlen (LonePairs->Radius2->value ()) == 0)
876 	return;
877     if (strlen (LonePairs->Number->value ()) == 0)
878 	return;
879     if (strlen (LonePairs->LonePair_Color->value ()) == 0)
880 	return;
881     LonePairs->LonePair_Add->activate ();
882 }
883 
884 void
885 LonePair_Frame_Combo_cb (Fl_Widget *, void *)
886 {
887 // routine called when the frame number is changed on the Bonds Edit Screen
888     int i, j;
889 
890     char atom1[5];
891 
892     char widget[16382];
893 
894     char atoms[100][5];
895 
896     char color[40];
897 
898     int no;
899 
900     float radius1, radius2;
901 
902     float d1;
903 
904     char string[100];
905 
906     int Frame_No = 1;
907 
908     if (drvui->max_frame > 1)
909 	Frame_No = atoi (LonePairs->Frame_No->value ());
910     int nlist = Get_Unique_Atoms (atoms, Frame_No);	// get unique atom names in sorted list
911 
912     LonePairs->LonePair_Combo->list.clear ();	// clear out the old names
913     for (j = 0; j < nlist; j++) {	// add atom names in alphabetic order
914 	LonePairs->LonePair_Combo->list.add (atoms[j]);
915     }
916     LonePairs->LonePair_Combo->value (atoms[0]);	// load first one in window
917     Lone_Pair_Combo_cb (NULL, NULL);
918     widget[0] = '\0';
919     for (i = 1; i < drvui->ncone; i++) {
920 	if (drvui->cones[i].cone_fn != Frame_No)
921 	    continue;		//skip if not for this frame
922 	strncpy (atom1, drvui->cones[i].cone_l1, 4);
923 	atom1[4] = 0;
924 	for (j = 3; j >= 0; --j) {
925 	    if (atom1[j] == ' ')
926 		atom1[j] = 0;
927 	}
928 	no = drvui->cones[i].numlonepairs;
929 	radius1 = drvui->cones[i].cone_min;
930 	radius2 = drvui->cones[i].cone_max;
931 	d1 = drvui->cones[i].cone_height;
932 	strncpy (color, drvui->cones[i].col_cone, 40);
933 	trim_string (color, 40);
934 	if (!strlen (color))
935 	    strcpy (color, "Gray20");
936 	if (color[strlen (color) - 1] < ' ')
937 	    color[strlen (color) - 1] = 0;
938 	sprintf (string, "  %4s     %2d%9.3f%9.3f%9.3f     %s\n", atom1, no, d1,
939 		 radius1, radius2, color);
940 	strcat (widget, string);
941     }
942     LonePairs->LonePairBuffer->text (widget);
943     LonePairs->LonePairInst1->show ();
944     LonePairs->LonePairInst->hide ();
945 }
946 
947 void
948 Main_Frame_Combo_cb (Fl_Widget *, void *)
949 {
950 // callback routine when Frame Number is changed on the main page
951     int frame = atoi (drvui->Frame_No->value ());
952 
953     drvui->X_Min->value (drvui->frames[frame].cryst_lim[0]);
954     drvui->X_Max->value (drvui->frames[frame].cryst_lim[3]);
955     drvui->Y_Min->value (drvui->frames[frame].cryst_lim[1]);
956     drvui->Y_Max->value (drvui->frames[frame].cryst_lim[4]);
957     drvui->Z_Min->value (drvui->frames[frame].cryst_lim[2]);
958     drvui->Z_Max->value (drvui->frames[frame].cryst_lim[5]);
959     if (clipflag) {
960 	drvui->X_Min_clip->value (drvui->frames[frame].clip_lim[0]);
961 	drvui->Y_Min_clip->value (drvui->frames[frame].clip_lim[1]);
962 	drvui->Z_Min_clip->value (drvui->frames[frame].clip_lim[2]);
963 	drvui->X_Max_clip->value (drvui->frames[frame].clip_lim[3]);
964 	drvui->Y_Max_clip->value (drvui->frames[frame].clip_lim[4]);
965 	drvui->Z_Max_clip->value (drvui->frames[frame].clip_lim[5]);
966     }
967 }
968 
969 void
970 MapType_cb (void)
971 {
972     if (!strcmp (Maps->MapType->value (), "CIF FoFc - fcf")
973 	|| !strcmp (Maps->MapType->value (), "JANA FoFc - m80")) {
974 	Maps->MapCalc->show ();
975 	Maps->MapCalcType->show ();
976 	Maps->Resolution->show ();
977     } else {
978 	Maps->MapCalc->hide ();
979 	Maps->MapCalcType->hide ();
980 	Maps->Resolution->hide ();
981     }
982 }
983 
984 void
985 Map_Info_cb (void)
986 {
987     char string[600];
988 
989     char buf_string[16384];
990 
991     static int six = 6, zero = 0;
992 
993 // callback to display map header information
994     if (helpwindow6) {
995 //        helpwindow6->show();
996 //        return;
997 	Fl::delete_widget (helpwindow6);
998     }
999 
1000     if (Map_Info.info_valid == 0)	// no map yet, so read it
1001 	Edit_Maps_Save_cb ((Fl_Button *) zero, &zero);
1002     if (Map_Info.info_valid == 0)	// if still no data, return
1003 	return;
1004     helpwindow6 = new Fl_Window (200, 180, 620, 360, "Map Info");
1005     helpwindow6->begin ();
1006     helpwindow6->callback ((Fl_Callback *) View_Help_Close_cb, &six);
1007     int y = 40;
1008 
1009     Fl_Text_Display *box1 =
1010 	new Fl_Text_Display (0, y, 600, 0, "DRAWxtl V5.5 Map File Information");
1011     box1->box (FL_NO_BOX);
1012     box1->labelsize (24);
1013     box1->labelcolor ((Fl_Color) 1);
1014     y += 20;
1015     strcpy (string, "Map Title: ");
1016     strcat (string, Map_Info.title);
1017     Fl_Multiline_Output *box2 = new Fl_Multiline_Output (20, y, 580, 280, "");
1018 
1019     box2->box (FL_NO_BOX);
1020     box2->labelsize (14);
1021     box2->labelcolor ((Fl_Color) 186);
1022     box2->cursor_color (FL_BACKGROUND_COLOR);
1023     box2->color (FL_BACKGROUND_COLOR);
1024     strcpy (buf_string, string);
1025     strcat (buf_string, "\n\n");
1026     sprintf (string, "Map Cell Parameters: %7.3f %7.3f %7.3f %7.2f %7.2f %7.2f\n\n",
1027 	     Map_Info.lat_con[0], Map_Info.lat_con[1], Map_Info.lat_con[2],
1028 	     Map_Info.lat_con[3], Map_Info.lat_con[4], Map_Info.lat_con[5]);
1029     strcat (buf_string, string);
1030     sprintf (string, "Minimum and Maximum density: %8.1f %8.1f\n\n", Map_Info.rhomn,
1031 	     Map_Info.rhomx);
1032     strcat (buf_string, string);
1033     sprintf (string, "Map Steps parallel to a, b, c: %5d %5d %5d\n\nSteps per A: %i\n\n",
1034 	     Map_Info.map_int[0], Map_Info.map_int[1], Map_Info.map_int[2], Map_Info.res);
1035     strcat (buf_string, string);
1036     if (!drvui->modulated) {
1037 	sprintf (string, "Map Calculated Region:            Axis     Min       Max\n"
1038 		 "                                                    x: %8.3f %8.3f\n"
1039 		 "                                                    y: %8.3f %8.3f\n"
1040 		 "                                                    z: %8.3f %8.3f\n",
1041 		 Map_Info.xlim[0], Map_Info.xlim[1],
1042 		 Map_Info.ylim[0], Map_Info.ylim[1], Map_Info.zlim[0], Map_Info.zlim[1]);
1043     } else {
1044 	sprintf (string,
1045 		 "Map Calculated Region:            Axis     Min       Max     Axis    Min       Max\n"
1046 		 "                                                    x: %8.3f %8.3f        x4: %8.3f %8.3f\n"
1047 		 "                                                    y: %8.3f %8.3f        x5: %8.3f %8.3f\n"
1048 		 "                                                    z: %8.3f %8.3f        x6: %8.3f %8.3f\n",
1049 		 Map_Info.xlim[0], Map_Info.xlim[1], Map_Info.x4lim[0], Map_Info.x4lim[1],
1050 		 Map_Info.ylim[0], Map_Info.ylim[1], Map_Info.x5lim[0], Map_Info.x5lim[1],
1051 		 Map_Info.zlim[0], Map_Info.zlim[1], Map_Info.x6lim[0],
1052 		 Map_Info.x6lim[1]);
1053     }
1054     strcat (buf_string, string);
1055     y += 250;
1056     Fl_Button *o = new Fl_Button (270, y, 80, 30, "Close");
1057 
1058     o->callback ((Fl_Callback *) View_Help_Close_cb, &six);
1059 #if !defined (WIN32) && !defined (__APPLE__)
1060     helpwindow6->icon ((char *) drvui->icon);
1061 #endif
1062     box2->value (buf_string);
1063     helpwindow6->end ();
1064     helpwindow6->show ();
1065 }
1066 
1067 void
1068 Modify_Arrow_cb (Fl_Widget *, void *)
1069 {
1070     char value[8], color[40];
1071 
1072     float length, diam;
1073 
1074     float pos[3], comp[3];
1075 
1076     int start, end;
1077 
1078     const char *selection;
1079 
1080     if (!arrows->ArrowBuffer->selected ()) {
1081 	arrows->AddButton->deactivate ();
1082 	arrows->RemoveButton->deactivate ();
1083 	return;
1084     }
1085     memset (color, 0, 40);
1086     arrows->ArrowBuffer->selection_position (&start, &end);
1087     selection = arrows->ArrowBuffer->line_text (start);
1088     arrows->ArrowInstr1->hide ();
1089     arrows->ArrowInstr->show ();
1090     sscanf (selection, "%f %f %f %f %f %f %f %f %s", &pos[0], &pos[1], &pos[2],
1091 	    &comp[0], &comp[1], &comp[2], &length, &diam, color);
1092     free ((char *) selection);
1093     if (strlen (color) && isalpha (color[0])) {
1094 	sprintf (value, "%4.3f", pos[0]);
1095 	arrows->Px->value (value);
1096 	sprintf (value, "%4.3f", pos[1]);
1097 	arrows->Py->value (value);
1098 	sprintf (value, "%4.3f", pos[2]);
1099 	arrows->Pz->value (value);
1100 	sprintf (value, "%4.3f", comp[0]);
1101 	arrows->Cx->value (value);
1102 	sprintf (value, "%4.3f", comp[1]);
1103 	arrows->Cy->value (value);
1104 	sprintf (value, "%4.3f", comp[2]);
1105 	arrows->Cz->value (value);
1106 	sprintf (value, "%4.3f", length);
1107 	arrows->Length->value (value);
1108 	sprintf (value, "%4.3f", diam);
1109 	arrows->Diameter->value (value);
1110 	arrows->Color->value (color);
1111 	arrows->AddButton->activate ();
1112 	arrows->RemoveButton->activate ();
1113 	New_Arrow_Input_cb (NULL, NULL);
1114     }
1115     return;
1116 }
1117 
1118 void
1119 Modify_Bonds_cb (Fl_Widget *, void *)
1120 {
1121     char from[10], color[40], type[10], to[10], value1[20];
1122 
1123     float mind, maxd, diam;
1124 
1125     int i, start, end;
1126 
1127     int itype;
1128 
1129     const char *selection;
1130 
1131     if (!Bonds->BondBuffer->selected ()) {
1132 	Bonds->New_Bond_Add->deactivate ();
1133 	Bonds->New_Bond_Remove->deactivate ();
1134 	return;
1135     }
1136     memset (color, 0, 40);
1137     Bonds->BondBuffer->selection_position (&start, &end);
1138     selection = Bonds->BondBuffer->line_text (start);
1139     Bonds->BondInstr1->hide ();
1140     Bonds->BondInstr->show ();
1141     (void) sscanf (selection, "%s %s %s %f %f %f %s", type, from, to, &diam, &mind, &maxd,
1142 		   color);
1143     itype = 0;
1144     if (!strncmp (type, "dash", 4)) {
1145 	i = sscanf (selection, "%s %d %s %s %f %f %f %s", type, &itype, from, to, &diam, &mind, &maxd,
1146 		   color);
1147 	if ( i < 4 ) {
1148 	    itype = 5;
1149 	    (void) sscanf (selection, "%s %s %s %f %f %f %s", type, from, to, &diam, &mind, &maxd,
1150 		   color);
1151 	}
1152     }
1153     free ((char *) selection);
1154     Bonds->New_Bond_From->value (from);
1155     Bonds->New_Bond_To->value (to);
1156     sprintf (value1, "%2.3f", mind);
1157     Bonds->New_Bond_Min->value (value1);
1158     sprintf (value1, "%2.3f", maxd);
1159     Bonds->New_Bond_Max->value (value1);
1160     sprintf (value1, "%2.3f", diam);
1161     Bonds->New_Bond_Dia->value (value1);
1162     Bonds->New_Bond_Color->value (color);
1163     if (itype > 0) {
1164 	Bonds->New_Bond_Style->set ();
1165 	if (itype != 5) {
1166 	    sprintf (value1, "%3d", itype);
1167 	    Bonds->New_Bond_Dashes->value(value1);
1168 	}
1169     }
1170     Bonds->New_Bond_Add->activate ();
1171     Bonds->New_Bond_Remove->activate ();
1172 }
1173 
1174 void
1175 Modify_Bonds_Distance_cb (Fl_Widget *, void *)
1176 {
1177     char atom[10], value[8];
1178 
1179     float dist;
1180 
1181     int start, end;
1182 
1183     const char *selection;
1184 
1185     if (!Bonds->Bond_Output_Buffer->selected ()) {
1186 	Bonds->New_Bond_To->value ("");
1187 	Bonds->New_Bond_Add->deactivate ();
1188 	Bonds->New_Bond_Remove->deactivate ();
1189 	return;
1190     }
1191     memset (atom, 0, 10);
1192     Bonds->Bond_Output_Buffer->selection_position (&start, &end);
1193     selection = Bonds->Bond_Output_Buffer->line_text (start);
1194     sscanf (selection, "%s %f", atom, &dist);
1195     free ((char *) selection);
1196     if (strlen (atom) && isalpha (atom[0])) {
1197 	Bonds->New_Bond_To->value (atom);
1198 	sprintf (value, "%2.3f", .1);
1199 	Bonds->New_Bond_Dia->value (value);
1200 	sprintf (value, "%2.3f", dist - .1);
1201 	Bonds->New_Bond_Min->value (value);
1202 	sprintf (value, "%2.3f", dist + .1);
1203 	Bonds->New_Bond_Max->value (value);
1204 	Bonds->New_Bond_Color->value ("Red");
1205 	Bonds->New_Bond_Add->activate ();
1206 	Bonds->New_Bond_Remove->activate ();
1207 	New_Bond_Input_cb (NULL, NULL);
1208     } else {
1209 	Bonds->New_Bond_To->value ("");
1210 	Bonds->New_Bond_Add->deactivate ();
1211 	Bonds->New_Bond_Remove->deactivate ();
1212     }
1213     return;
1214 }
1215 
1216 void
1217 Modify_Ellipsoids_cb (Fl_Widget *, void *)
1218 {
1219     char atom[10], color[40], string[10];
1220 
1221     int no, i;
1222 
1223     int start, end;
1224 
1225     const char *selection;
1226 
1227     if (!ellipsoids->ColorInputBuf->selected ()) {
1228 	ellipsoids->Atom_Combo->value ("");
1229 	ellipsoids->Color_Combo->value ("");
1230 	ellipsoids->New_Ellipsoid_Add->deactivate ();
1231 	ellipsoids->New_Ellipsoid_Convert->deactivate ();
1232 	return;
1233     }
1234     memset (atom, 0, 10);
1235     memset (color, 0, 40);
1236     ellipsoids->ColorInputBuf->selection_position (&start, &end);
1237     selection = ellipsoids->ColorInputBuf->line_text (start);
1238     sscanf (selection, "%s %s %s", atom, string, color);
1239     free ((char *) selection);
1240     while (strlen (atom) < 4) {
1241 	strcat (atom, " ");
1242     }
1243     if (strlen (atom) && isalpha (atom[0])) {
1244 	if (strstr (string, "*"))
1245 	    sprintf (string, "%4s *", atom);
1246 	else {
1247 	    sscanf (string, "%d", &no);
1248 	    sprintf (string, "%4s%2d", atom, no);
1249 	}
1250 	ellipsoids->Atom_Combo->value (string);
1251 	ellipsoids->Color_Combo->value (color);
1252 	ellipsoids->New_Ellipsoid_Add->activate ();
1253 	ellipsoids->New_Ellipsoid_Remove->activate ();
1254 	set_tf_status ();	//  set the appropriate flags
1255 	for (i = 0; i < natom; i++) {
1256 	    if (drvui->atoms[i].atom_fn != drvui->frame_no)
1257 		continue;
1258 	    if (check_atom_name (drvui->atoms[i].atom_l, atom)
1259 		&& drvui->atoms[i].TF_status == 1) {
1260 		ellipsoids->New_Ellipsoid_Convert->activate ();
1261 		break;
1262 	    }
1263 	}
1264 	New_Ellipsoid_Input_cb (NULL, NULL);
1265     }
1266     return;
1267 }
1268 
1269 void
1270 Modify_LonePair_cb (Fl_Widget *, void *)
1271 {
1272     char atom[10], value[8], color[40];
1273 
1274     float d1, d2, height;
1275 
1276     int start, end, no;
1277 
1278     const char *selection;
1279 
1280     if (!LonePairs->LonePairBuffer->selected ()) {
1281 	LonePairs->LonePair_Combo->value ("");
1282 	return;
1283     }
1284     memset (atom, 0, 10);
1285     memset (color, 0, 40);
1286 
1287     LonePairs->LonePairBuffer->selection_position (&start, &end);
1288     selection = LonePairs->LonePairBuffer->line_text (start);
1289     LonePairs->LonePairInst1->hide ();
1290     LonePairs->LonePairInst->show ();
1291     sscanf (selection, " %s %d %f %f %f %s", atom, &no, &height, &d1, &d2, color);
1292     free ((char *) selection);
1293     if (strlen (atom) && isalpha (atom[0])) {
1294 	LonePairs->LonePair_Combo->value (atom);
1295 	sprintf (value, "%2.3f", d1);
1296 	LonePairs->Radius1->value (value);
1297 	sprintf (value, "%2.3f", d2);
1298 	LonePairs->Radius2->value (value);
1299 	sprintf (value, "%2.3f", height);
1300 	LonePairs->Height->value (value);
1301 	LonePairs->LonePair_Color->value (color);
1302 	sprintf (value, "%d", no);
1303 	LonePairs->Number->value (value);
1304 	LonePairs->LonePair_Add->activate ();
1305 	LonePairs->LonePair_Remove->activate ();
1306     } else {
1307 	LonePairs->LonePair_Combo->value ("");
1308 	LonePairs->Radius1->value ("");
1309 	LonePairs->Radius2->value ("");
1310 	LonePairs->Height->value ("");
1311 	LonePairs->LonePair_Color->value ("");
1312 	LonePairs->Number->value ("");
1313 	LonePairs->LonePair_Add->deactivate ();
1314 	LonePairs->LonePair_Remove->deactivate ();
1315     }
1316 }
1317 
1318 void
1319 Modify_Maps_cb (Fl_Widget *, void *)
1320 {
1321     char type[8], color[40], value[10];
1322 
1323     float level;
1324 
1325     float step, top;
1326 
1327     int start, end;
1328 
1329     const char *selection;
1330 
1331     if (!Maps->MapsBuffer->selected ()) {
1332 	return;
1333     }
1334     memset (type, 0, 8);
1335     memset (color, 0, 40);
1336     Maps->MapsBuffer->selection_position (&start, &end);
1337     selection = Maps->MapsBuffer->line_text (start);
1338     Maps->MapsInstr1->hide ();
1339     Maps->MapsInstr->show ();
1340     if (!drvui->Fourier2d)
1341 	sscanf (selection, " %f %s %s", &level, type, color);
1342     else
1343 	sscanf (selection, " %f %f %f %s", &level, &step, &top, color);
1344     free ((char *) selection);
1345     if (strlen (color) && isalpha (color[0])) {
1346 	sprintf (value, "%2.3f", level);
1347 	Maps->Level->value (value);
1348 	if (drvui->Fourier2d) {
1349 	    sprintf (value, "%2.3f", step);
1350 	    Maps->Step->value (value);
1351 	    sprintf (value, "%2.3f", top);
1352 	    Maps->Top->value (value);
1353 	} else {
1354 	    Maps->Type->value (type);
1355 	}
1356 	Maps->Color->value (color);
1357 	Maps->Add_Button->activate ();
1358 	Maps->Remove_Button->activate ();
1359     } else {
1360 	Maps->Color->value ("");
1361 	if (drvui->Fourier2d) {
1362 	    Maps->Step->value ("");
1363 	    Maps->Top->value ("");
1364 	} else
1365 	    Maps->Type->value ("");
1366 	Maps->Level->value ("");
1367 	Maps->Add_Button->activate ();
1368 	Maps->Remove_Button->deactivate ();
1369     }
1370 }
1371 
1372 void
1373 Modify_Polyhedra_cb (Fl_Widget *, void *)
1374 {
1375     char atom[10], color[40], type[10], to[10], value1[20];
1376 
1377     float mind, maxd, transp;
1378 
1379     int start, end;
1380 
1381     int itype = 0;
1382 
1383     const char *selection;
1384 
1385     if (!Polyhedra->PolyhedraBuffer->selected ()) {
1386 	Polyhedra->PolyInstr->hide ();
1387 	Polyhedra->New_Polyhedra_Add->deactivate ();
1388 	Polyhedra->New_Polyhedra_Remove->deactivate ();
1389 	return;
1390     }
1391     memset (atom, 0, 10);
1392     memset (color, 0, 40);
1393     memset (to, 0, 10);
1394     transp = 0.0f;
1395     mind = 0.0f;
1396     maxd = 0.0f;
1397     Polyhedra->PolyhedraBuffer->selection_position (&start, &end);
1398     selection = Polyhedra->PolyhedraBuffer->line_text (start);
1399     Polyhedra->PolyInstr1->hide ();
1400     Polyhedra->PolyInstr->show ();
1401     sscanf (selection, "%s", type);
1402     if (!strncmp (type, "PS", 2)) {
1403 	(void) sscanf (selection, "%s %s %f %f %s %*s %f", type, atom, &mind, &maxd,
1404 		       color, &transp);
1405 	if (isdigit (color[0]) || color[0] == '.') {
1406 	    char color1[10], color2[10], color3[10];
1407 
1408 	    (void) sscanf (selection, "%s %s %f %f %s %s %s %*s %f", type, atom, &mind,
1409 			   &maxd, color1, color2, color3, &transp);
1410 	    strcpy (color, color1);
1411 	    strcat (color, " ");
1412 	    strcat (color, color2);
1413 	    strcat (color, " ");
1414 	    strcat (color, color3);
1415 	}
1416 	itype = 0;
1417     } else if (!strncmp (type, "PV", 2)) {
1418 	(void) sscanf (selection, "%s %s %s %f %f %s %*s %f", type, atom, to, &mind,
1419 		       &maxd, color, &transp);
1420 	if (isdigit (color[0]) || color[0] == '.') {
1421 	    char color1[10], color2[10], color3[10];
1422 
1423 	    (void) sscanf (selection, "%s %s %s %f %f %s %s %s %*s %f", type, atom, to,
1424 			   &mind, &maxd, color1, color2, color3, &transp);
1425 	    strcpy (color, color1);
1426 	    strcat (color, " ");
1427 	    strcat (color, color2);
1428 	    strcat (color, " ");
1429 	    strcat (color, color3);
1430 	}
1431 	itype = 1;
1432     } else if (!strncmp (type, "SH", 2)) {
1433 	(void) sscanf (selection, "%s %s %f %f %s %*s %f", type, atom, &mind, &maxd,
1434 		       color, &transp);
1435 	if (isdigit (color[0]) || color[0] == '.') {
1436 	    char color1[10], color2[10], color3[10];
1437 
1438 	    (void) sscanf (selection, "%s %s %f %f %s %s %s %*s %f", type, atom, &mind,
1439 			   &maxd, color1, color2, color3, &transp);
1440 	    strcpy (color, color1);
1441 	    strcat (color, " ");
1442 	    strcat (color, color2);
1443 	    strcat (color, " ");
1444 	    strcat (color, color3);
1445 	}
1446 	itype = 2;
1447     } else if (!strncmp (type, "PL", 2)) {
1448 	(void) sscanf (selection, "%s %s %f %f %s %*s %f", type, atom, &mind, &maxd,
1449 		       color, &transp);
1450 	if (isdigit (color[0]) || color[0] == '.') {
1451 	    char color1[10], color2[10], color3[10];
1452 
1453 	    (void) sscanf (selection, "%s %s %f %f %s %s %s %*s %f", type, atom, &mind,
1454 			   &maxd, color1, color2, color3, &transp);
1455 	    strcpy (color, color1);
1456 	    strcat (color, " ");
1457 	    strcat (color, color2);
1458 	    strcat (color, " ");
1459 	    strcat (color, color3);
1460 	}
1461 	itype = 3;
1462     }
1463     free ((char *) selection);
1464     Polyhedra->New_Polyhedra_From->value (atom);
1465     Polyhedra->Polyhedra_Combo->value (atom);
1466     Polyhedra_Combo_cb (NULL, NULL);
1467     Polyhedra->New_Polyhedra_To->value (to);
1468     sprintf (value1, "%2.3f", mind);
1469     Polyhedra->New_Polyhedra_Min->value (value1);
1470     sprintf (value1, "%2.3f", maxd);
1471     Polyhedra->New_Polyhedra_Max->value (value1);
1472     Polyhedra->New_Polyhedra_Color->value (color);
1473     if (transp > 0.) {
1474 	sprintf (value1, "%.3f", transp);
1475 	Polyhedra->New_Polyhedra_Transp->value (value1);
1476     }
1477     switch (itype) {
1478     case 0:
1479 	Polyhedra->Polysz->set ();
1480 	Polyhedra->Polyvert->clear ();
1481 	Polyhedra->Polyshell->clear ();
1482 	Polyhedra->Plane->clear ();
1483 	break;
1484     case 1:
1485 	Polyhedra->Polyvert->set ();
1486 	Polyhedra->Polysz->clear ();
1487 	Polyhedra->Polyshell->clear ();
1488 	Polyhedra->Plane->clear ();
1489 	break;
1490     case 2:
1491 	Polyhedra->Polyvert->clear ();
1492 	Polyhedra->Polyshell->set ();
1493 	Polyhedra->Polysz->clear ();
1494 	Polyhedra->Plane->clear ();
1495 	break;
1496     case 3:
1497 	Polyhedra->Plane->set ();
1498 	Polyhedra->Polyvert->clear ();
1499 	Polyhedra->Polysz->clear ();
1500 	Polyhedra->Polyshell->clear ();
1501     }
1502     Polyhedra->New_Polyhedra_Add->activate ();
1503     Polyhedra->New_Polyhedra_Remove->activate ();
1504     return;
1505 }
1506 
1507 void
1508 Modify_Polyhedra_Distance_cb (Fl_Widget *, void *)
1509 {
1510 // callback routine entered when a selection is made in the polyhedra bond-distance table
1511     char atom[10], value[8];
1512 
1513     float dist;
1514 
1515     int start, end;
1516 
1517     const char *selection;
1518 
1519     if (!Polyhedra->Polyhedra_Output_Buffer->selected ()) {
1520 	Polyhedra->New_Polyhedra_To->value ("");
1521 	Polyhedra->New_Polyhedra_Add->deactivate ();
1522 	return;
1523     }
1524     memset (atom, 0, 10);
1525     Polyhedra->Polyhedra_Output_Buffer->selection_position (&start, &end);
1526     selection = Polyhedra->Polyhedra_Output_Buffer->line_text (start);
1527     sscanf (selection, "%s %f", atom, &dist);
1528     if (strlen (atom) && isalpha (atom[0])) {
1529 	Polyhedra->New_Polyhedra_To->value (atom);
1530 	sprintf (value, "%2.3f", dist - .2);
1531 	Polyhedra->New_Polyhedra_Min->value (value);
1532 	sprintf (value, "%2.3f", dist + .2);
1533 	Polyhedra->New_Polyhedra_Max->value (value);
1534 	Polyhedra->New_Polyhedra_Color->value ("Red");
1535 	Polyhedra->New_Polyhedra_Add->activate ();
1536 	New_Polyhedra_Input_cb (NULL, NULL);
1537     } else {
1538 	Polyhedra->New_Polyhedra_To->value ("");
1539 	Polyhedra->New_Polyhedra_Add->deactivate ();
1540 	Polyhedra->New_Polyhedra_Remove->deactivate ();
1541     }
1542     free ((char *) selection);
1543     return;
1544 }
1545 
1546 void
1547 Modify_Spheres_cb (Fl_Widget *, void *)
1548 {
1549     char atom[10], value[8], color[40], string[40];
1550 
1551     float dist;
1552 
1553     int start, end, i, n;
1554 
1555     const char *selection;
1556 
1557     if (!Spheres->SphereBuffer->selected ()) {
1558 	Spheres->Sphere_Combo->value ("");
1559 	Spheres->New_Sphere_Size->value ("");
1560 	Spheres->New_Sphere_Add->deactivate ();
1561 	Spheres->New_Sphere_Convert->deactivate ();
1562 	return;
1563     }
1564     memset (atom, 0, 10);
1565     memset (color, 0, 40);
1566     Spheres->SphereBuffer->selection_position (&start, &end);
1567     selection = Spheres->SphereBuffer->line_text (start);
1568     Spheres->SphereInstr1->hide ();
1569     Spheres->SphereInstr->show ();
1570     if (strlen (selection) == 0)
1571 	return;			// user clicked on empty line by mistake
1572     sscanf (selection, "%s %s %f %s", atom, string, &dist, color);
1573     while (strlen (atom) < 4)
1574 	strcat (atom, " ");
1575     free ((char *) selection);
1576     if (strstr (string, "*"))
1577 	n = -1;
1578     else
1579 	(void) sscanf (string, "%d", &n);
1580     if (strlen (atom) && isalpha (atom[0])) {
1581 	strcpy (string, atom);
1582 	if (n < 0)
1583 	    strcpy (value, " *");
1584 	else
1585 	    sprintf (value, "%2d", n);
1586 	strcat (string, value);
1587 	Spheres->Sphere_Combo->value (string);
1588 	sprintf (value, "%2.3f", dist);
1589 	Spheres->New_Sphere_Size->value (value);
1590 	Spheres->New_Sphere_Color->value (color);
1591 	Spheres->New_Sphere_Add->activate ();
1592 	Spheres->New_Sphere_Remove->activate ();
1593 	for (i = 1; i < drvui->n_ellips; i++) {
1594 	    if (check_atom_name (drvui->ellips[i].ellips_l, atom)
1595 		&& (drvui->ellips[i].ellips_n == n || n == -1)
1596 		&& drvui->ellips[i].ell_type == 1)
1597 		Spheres->New_Sphere_Convert->activate ();
1598 	}
1599 	New_Sphere_Input_cb (NULL, NULL);
1600     }
1601     return;
1602 }
1603 
1604 void
1605 New_Arrow_Add_cb (class Fl_Widget *, int *action)
1606 {
1607 // Add new arrow to display list on Arrow Edit Screen
1608     char string[100], color[40];
1609 
1610     int start, end;
1611 
1612     char *selection = NULL;
1613 
1614     arrows->ArrowInstr2->show ();
1615     if (arrows->ArrowBuffer->selected ()) {
1616 	arrows->ArrowBuffer->selection_position (&start, &end);
1617 	selection = arrows->ArrowBuffer->line_text (start);
1618 	if (!*action)
1619 	    arrows->ArrowBuffer->remove (arrows->ArrowBuffer->line_start (start),
1620 					 arrows->ArrowBuffer->line_end (end) + 1);
1621     }
1622 
1623     if (*action) {
1624 	strcpy (color, arrows->Color->value ());
1625 	trim_string (color, 40);
1626 	if (!strlen (color))
1627 	    strcpy (color, "Gray20");
1628 	sprintf (string, "%6.3f %6.3f %6.3f %10.3f %6.3f %6.3f %10.3f %6.3f   %s\n",
1629 		 atof (arrows->Px->value ()), atof (arrows->Py->value ()),
1630 		 atof (arrows->Pz->value ()), atof (arrows->Cx->value ()),
1631 		 atof (arrows->Cy->value ()), atof (arrows->Cz->value ()),
1632 		 atof (arrows->Length->value ()), atof (arrows->Diameter->value ()),
1633 		 color);
1634 	if (selection)
1635 	    arrows->ArrowBuffer->replace (arrows->ArrowBuffer->line_start (start),
1636 					  arrows->ArrowBuffer->line_end (end) + 1,
1637 					  string);
1638 	else
1639 	    arrows->ArrowBuffer->append (string);
1640     }
1641     if (selection)
1642 	free ((char *) selection);
1643     arrows->Px->value ("");
1644     arrows->Py->value ("");
1645     arrows->Pz->value ("");
1646     arrows->Cx->value ("");
1647     arrows->Cy->value ("");
1648     arrows->Cz->value ("");
1649     arrows->Color->value ("");
1650     arrows->Diameter->value ("");
1651     arrows->Length->value ("");
1652     arrows->AddButton->deactivate ();
1653     arrows->RemoveButton->deactivate ();
1654     arrows->ArrowInstr->hide ();
1655     arrows->ArrowInstr1->show ();
1656     Edit_Arrow_Save_cb (NULL, &three);
1657 }
1658 
1659 void
1660 New_Arrow_Input_cb (class Fl_Widget *, void *)
1661 {
1662 // callback routine to make 'Add' new bond button active whenever all fields are non-blank
1663     if (!strlen (arrows->Px->value ()))
1664 	return;
1665     if (!strlen (arrows->Py->value ()))
1666 	return;
1667     if (!strlen (arrows->Pz->value ()))
1668 	return;
1669     if (!strlen (arrows->Cx->value ()))
1670 	return;
1671     if (!strlen (arrows->Cy->value ()))
1672 	return;
1673     if (!strlen (arrows->Cz->value ()))
1674 	return;
1675     if (!strlen (arrows->Length->value ()))
1676 	return;
1677     if (!strlen (arrows->Diameter->value ()))
1678 	return;
1679     if (!strlen (arrows->Color->value ()))
1680 	return;
1681     arrows->AddButton->activate ();
1682 }
1683 
1684 void
1685 New_Bond_Add_cb (class Fl_Widget *, int *action)
1686 {
1687 // Add new bond to display list on Bond Edit Screen
1688     char string[100], type[5];
1689 
1690     float dia, dmin, dmax;
1691 
1692     int start, end, numd;
1693 
1694     char *selection = NULL;
1695 
1696     Bonds->BondInstr2->show ();
1697     if (Bonds->BondBuffer->selected ()) {
1698 	Bonds->BondBuffer->selection_position (&start, &end);
1699 	selection = Bonds->BondBuffer->line_text (start);
1700 	if (*action)
1701 	    Bonds->BondBuffer->remove (Bonds->BondBuffer->line_start (start),
1702 				       Bonds->BondBuffer->line_end (end) + 1);
1703     }
1704     if (!*action) {
1705 	dia = (float) atof (Bonds->New_Bond_Dia->value ());
1706 	dmin = (float) atof (Bonds->New_Bond_Min->value ());
1707 	dmax = (float) atof (Bonds->New_Bond_Max->value ());
1708 	if (Bonds->New_Bond_Style->value ()) {
1709 	    strcpy (type, "dash");
1710 	    numd = atoi (Bonds->New_Bond_Dashes->value ());
1711 	    if (numd > 0)
1712 		sprintf (string, "%4s %3d %4s   %4s  %9.3f %9.3f %9.3f     %s\n",
1713 			type, numd, Bonds->New_Bond_From->value (), Bonds->New_Bond_To->value (), dia,
1714 			dmin, dmax, Bonds->New_Bond_Color->value ());
1715 	    else
1716 		sprintf (string, "%4s     %4s   %4s  %9.3f %9.3f %9.3f     %s\n",
1717 			type, Bonds->New_Bond_From->value (), Bonds->New_Bond_To->value (), dia,
1718 			dmin, dmax, Bonds->New_Bond_Color->value ());
1719 	} else {
1720 	    strcpy (type, "bond");
1721 	    sprintf (string, "%4s     %4s   %4s  %9.3f %9.3f %9.3f     %s\n",
1722 		 type, Bonds->New_Bond_From->value (), Bonds->New_Bond_To->value (), dia,
1723 		 dmin, dmax, Bonds->New_Bond_Color->value ());
1724 	}
1725 	if (selection)
1726 	    Bonds->BondBuffer->replace (Bonds->BondBuffer->line_start (start),
1727 					Bonds->BondBuffer->line_end (end) + 1, string);
1728 	else
1729 	    Bonds->BondBuffer->append (string);
1730     }
1731     if (selection)
1732 	free ((char *) selection);
1733     Bonds->New_Bond_To->value ("");
1734     Bonds->New_Bond_Dia->value ("");
1735     Bonds->New_Bond_Min->value ("");
1736     Bonds->New_Bond_Max->value ("");
1737     Bonds->New_Bond_Color->value ("");
1738     Bonds->New_Bond_Style->value (0);
1739     Bonds->New_Bond_Dashes->value ("");
1740     Bonds->New_Bond_Add->deactivate ();
1741     Bonds->New_Bond_Remove->deactivate ();
1742     Bonds->BondInstr1->show ();
1743     Bonds->BondInstr->hide ();
1744     Edit_Bond_Save_cb (NULL, &three);
1745 }
1746 
1747 void
1748 New_Ellipsoid_Add_cb (class Fl_Widget *, int *action)
1749 {
1750     int start, end;
1751 
1752     char string[40], string2[40], atom[5], color[40], num[4];
1753 
1754     int no, i = 0;
1755 
1756     char *selection = NULL;
1757 
1758     ellipsoids->Instr2->show ();
1759     strcpy (string, ellipsoids->Atom_Combo->value ());
1760     strcpy (color, ellipsoids->Color_Combo->value ());
1761     if (ellipsoids->ColorInputBuf->selected ()) {
1762 	ellipsoids->ColorInputBuf->selection_position (&start, &end);
1763 	selection = ellipsoids->ColorInputBuf->line_text (start);
1764 	if (*action != 1)
1765 	    ellipsoids->ColorInputBuf->remove (ellipsoids->ColorInputBuf->
1766 					       line_start (start),
1767 					       ellipsoids->ColorInputBuf->line_end (end) +
1768 					       1);
1769     }
1770     ellipsoids->New_Ellipsoid_Add->deactivate ();
1771     ellipsoids->New_Ellipsoid_Convert->deactivate ();
1772     ellipsoids->New_Ellipsoid_Remove->deactivate ();
1773     ellipsoids->Instr1->show ();
1774     ellipsoids->Instr->hide ();
1775     if (*action == 1) {		// add
1776 	sscanf (string, "%s %s", atom, num);
1777 	if (strstr (num, "*"))
1778 	    sprintf (string, "%4s   *   %s\n", atom, color);
1779 	else {
1780 	    sscanf (num, "%d", &no);
1781 	    sprintf (string, "%4s %3d   %s\n", atom, no, color);
1782 	}
1783 	if (selection)
1784 	    ellipsoids->ColorInputBuf->replace (ellipsoids->ColorInputBuf->
1785 						line_start (start),
1786 						ellipsoids->ColorInputBuf->
1787 						line_end (end) + 1, string);
1788 	else
1789 	    ellipsoids->ColorInputBuf->append (string);
1790     } else if (*action == 2) {	// convert selection to sphere
1791 	while (1) {		// delete selected item from combo list
1792 	    if (ellipsoids->Atom_Combo->list.text (++i) == NULL)
1793 		break;
1794 	    strcpy (string2, ellipsoids->Atom_Combo->list.text (i));
1795 	    if (!strcmp (string, string2)) {
1796 		ellipsoids->Atom_Combo->list.remove (i);
1797 		break;
1798 	    }
1799 	}
1800 	if (!selection)
1801 	    return;		// happens when the atom is not in the ellipsoid list,
1802 	// but the user tried to force its conversion anyway
1803 	sscanf (selection, "%s %s %s", atom, num, color);
1804 	if (strstr (num, "*"))
1805 	    no = -1;
1806 	else
1807 	    sscanf (num, "%d", &no);
1808 	while (strlen (atom) < 4)
1809 	    strcat (atom, " ");
1810 	for (i = 1; i < drvui->n_ellips; i++) {
1811 	    if (check_atom_name (atom, drvui->ellips[i].ellips_l) &&
1812 		(no == drvui->ellips[i].ellips_n || no == -1)) {
1813 		drvui->ellips[i].ell_type = 1;	// no longer an ellipse
1814 		drvui->spheres[drvui->nsphere].sphere_fn = 1;	// it goes into frame 1
1815 		strcpy (drvui->spheres[drvui->nsphere].sphere_l, atom);	// same name as ellipse
1816 		if (no == -1)
1817 		    drvui->spheres[drvui->nsphere].sphere_n = no;
1818 		else
1819 		    drvui->spheres[drvui->nsphere].sphere_n = drvui->ellips[i].ellips_n;
1820 		drvui->spheres[drvui->nsphere].sphere_size =
1821 		    (drvui->ellips[i].ellips_RMS[0]
1822 		     + drvui->ellips[i].ellips_RMS[1]
1823 		     + drvui->ellips[i].ellips_RMS[2]) * drvui->Ellipsoid_Scale / 3.0f;	//size
1824 		strcpy (drvui->spheres[drvui->nsphere].sphere_col, color);
1825 		i = drvui->n_ellips;
1826 	    }
1827 	}
1828 	if (!drvui->spheres) {
1829 	    drvui->spheres =
1830 		(struct sphere_struct *) zalloc (20 * sizeof (struct sphere_struct));
1831 	    if (!drvui->spheres) {
1832 		Error_Box ("Unable to allocate storage for spheres.");
1833 		return;
1834 	    }
1835 	}
1836 	if (++drvui->nsphere > drvui->nsphere_alloc) {
1837 	    drvui->spheres =
1838 		(struct sphere_struct *) realloc (drvui->spheres,
1839 						  20 * sizeof (struct sphere_struct));
1840 	    if (!drvui->spheres) {
1841 		Error_Box ("Unable to allocate storage for spheres.");
1842 		exit (0);
1843 	    }
1844 	    drvui->nsphere_alloc += 20;
1845 	}
1846 	drvui->Str_File_Changed = 1;
1847 	Update_Str (0);
1848 	Generate_Drawing (0);
1849     }
1850     if (selection)
1851 	free ((char *) selection);
1852     ellipsoids->Atom_Combo->value ("");
1853     ellipsoids->Color_Combo->value ("");
1854     Edit_Ellipsoid_Save_cb (NULL, &three);
1855 }
1856 
1857 void
1858 New_Ellipsoid_Input_cb (class Fl_Widget *, void *)
1859 {
1860 // callback routine to make 'Add' new ellipsoid button active whenever all required fields are non-blank
1861     if (!strlen (ellipsoids->Atom_Combo->value ()))
1862 	return;
1863     if (!strlen (ellipsoids->Color_Combo->value ()))
1864 	return;
1865     ellipsoids->New_Ellipsoid_Add->activate ();
1866     ellipsoids->New_Ellipsoid_Convert->activate ();
1867 }
1868 
1869 void
1870 New_Bond_Input_cb (class Fl_Widget *, void *)
1871 {
1872 // callback routine to make 'Add' new bond button active whenever all fields are non-blank
1873     if (!strlen (Bonds->New_Bond_To->value ()))
1874 	return;
1875     if (!atof (Bonds->New_Bond_Dia->value ()))
1876 	return;
1877     if (!atof (Bonds->New_Bond_Min->value ()))
1878 	return;
1879     if (!atof (Bonds->New_Bond_Max->value ()))
1880 	return;
1881     if (!strlen (Bonds->New_Bond_Color->value ()))
1882 	return;
1883     Bonds->New_Bond_Add->activate ();
1884 }
1885 
1886 void
1887 New_Map_Add_cb (class Fl_Widget *, int *action)
1888 {
1889 // Add new map contour to display list on Map Edit Screen
1890     char string[100];
1891 
1892     char value[20];
1893 
1894     float level;
1895 
1896     int start, end;
1897 
1898     char *selection = NULL;
1899 
1900     Maps->MapsInstr2->show ();
1901     if (Maps->MapsBuffer->selected ()) {
1902 	Maps->MapsBuffer->selection_position (&start, &end);
1903 	selection = Maps->MapsBuffer->line_text (start);
1904 	Maps->MapsBuffer->remove (Maps->MapsBuffer->line_start (start),
1905 				  Maps->MapsBuffer->line_end (end) + 1);
1906     }
1907     if (*action) {
1908 	strcpy (value, Maps->Level->value ());
1909 	level = (float) atof (value);
1910 	if (drvui->Fourier2d) {
1911 	    float step, top;
1912 
1913 	    strcpy (value, Maps->Step->value ());
1914 	    step = (float) atof (value);
1915 	    strcpy (value, Maps->Top->value ());
1916 	    top = (float) atof (value);
1917 	    sprintf (string, "%7.3f %7.3f %7.3f %s\n", level, step, top,
1918 		     Maps->Color->value ());
1919 	} else {
1920 	    sprintf (string, "%8.3f    %6s     %s\n", level, Maps->Type->value (),
1921 		     Maps->Color->value ());
1922 	}
1923 	Maps->MapsBuffer->append (string);
1924     }
1925     if (selection)
1926 	free ((char *) selection);
1927     Maps->Level->value ("");
1928     if (drvui->Fourier2d) {
1929 	Maps->Step->value ("");
1930 	Maps->Top->value ("");
1931     }
1932     Maps->Add_Button->deactivate ();
1933     Maps->Remove_Button->deactivate ();
1934     Maps->MapsInstr1->show ();
1935     Maps->MapsInstr->hide ();
1936     Edit_Maps_Save_cb (NULL, &three);
1937 }
1938 
1939 void
1940 New_Map_Input_cb (Fl_Widget *, void *)
1941 {
1942 // callback routine to make 'Add' new map level button active whenever all fields are non-blank
1943     if (!strlen (Maps->Color->value ()))
1944 	return;
1945     if (!strlen (Maps->Level->value ()))
1946 	return;
1947     if (drvui->Fourier2d) {
1948 	if (!strlen (Maps->Step->value ()))
1949 	    return;
1950 	if (!strlen (Maps->Top->value ()))
1951 	    return;
1952     } else if (!strlen (Maps->Type->value ()))
1953 	return;
1954     Maps->Add_Button->activate ();
1955 }
1956 
1957 void
1958 New_Polyhedra_Add_cb (class Fl_Widget *, int *action)
1959 {
1960 // Add new polyhedron to display list on Polyhedra Edit Screen
1961     char string[100];
1962 
1963     float dmin, dmax, transp;
1964 
1965     char temp[10];
1966 
1967     char atom1[5], atom2[5], type[3] = "PS";
1968 
1969     int start, end, i;
1970 
1971     char *selection = NULL;
1972 
1973     Polyhedra->PolyInstr2->show ();
1974     if (Polyhedra->PolyhedraBuffer->selected ()) {
1975 	Polyhedra->PolyhedraBuffer->selection_position (&start, &end);
1976 	selection = Polyhedra->PolyhedraBuffer->line_text (start);
1977 	if (!*action)
1978 	    Polyhedra->PolyhedraBuffer->remove (Polyhedra->PolyhedraBuffer->
1979 						line_start (start),
1980 						Polyhedra->PolyhedraBuffer->
1981 						line_end (end) + 1);
1982     }
1983     if (*action) {
1984 	strcpy (temp, Polyhedra->New_Polyhedra_Min->value ());
1985 	dmin = (float) atof (temp);
1986 	dmax = (float) atof (Polyhedra->New_Polyhedra_Max->value ());
1987 	transp = (float) atof (Polyhedra->New_Polyhedra_Transp->value ());
1988 
1989 	strcpy (atom1, Polyhedra->New_Polyhedra_From->value ());
1990 	strcpy (atom2, Polyhedra->New_Polyhedra_To->value ());
1991 	if (Polyhedra->Polysz->value ()) {
1992 	    strcpy (type, "PS");
1993 	    strcpy (atom2, "");
1994 	    dmin = 0.005f;
1995 	}
1996 	if (Polyhedra->Polyvert->value ()) {
1997 	    strcpy (type, "PV");
1998 	    dmin = 0.005f;
1999 	}
2000 	if (Polyhedra->Polyshell->value ()) {
2001 	    strcpy (type, "SH");
2002 	    strcpy (atom2, "");
2003 	}
2004 	if (Polyhedra->Plane->value ()) {
2005 	    strcpy (type, "PL");
2006 	    strcpy (atom2, "");
2007 	    dmin = 0.005f;
2008 	}
2009 	if (transp > 0.0f)
2010 	    sprintf (string, "  %2s      %4s    %4s %9.3f %9.3f     %s filter %.3f\n",
2011 		     type, atom1, atom2, dmin, dmax,
2012 		     Polyhedra->New_Polyhedra_Color->value (), transp);
2013 	else
2014 	    sprintf (string, "  %2s      %4s    %4s %9.3f %9.3f     %s\n", type, atom1,
2015 		     atom2, dmin, dmax, Polyhedra->New_Polyhedra_Color->value ());
2016 	if (selection)
2017 	    Polyhedra->PolyhedraBuffer->replace (Polyhedra->PolyhedraBuffer->
2018 						 line_start (start),
2019 						 Polyhedra->PolyhedraBuffer->
2020 						 line_end (end) + 1, string);
2021 	else
2022 	    Polyhedra->PolyhedraBuffer->append (string);
2023 	if (Polyhedra->Edge_Color->value()) {
2024 	    int found = 0;
2025 	    for ( i = 0; i<drvui->nedges; i++) {
2026 		if (!strcmp (drvui->polyedges[i].name, atom1)) {
2027 		    strcpy (drvui->polyedges[i].color, Polyhedra->Edge_Color->value());
2028 		    drvui->polyedges[i].radius = (float) atof (Polyhedra->Edge_Radius->value());
2029 		    found = 1;
2030 		    break;
2031 		}
2032 	    }
2033 	    if (found == 0) {
2034 		trim_string (atom1, 4);
2035 		strcpy (drvui->polyedges[drvui->nedges].name, atom1);
2036 		strcpy (drvui->polyedges[drvui->nedges].color, Polyhedra->Edge_Color->value());
2037 		drvui->polyedges[drvui->nedges++].radius = (float) atof (Polyhedra->Edge_Radius->value());
2038 		check_dynamic_storage ();
2039 	    }
2040 	}
2041     }
2042     if (selection)
2043 	free ((char *) selection);
2044     Polyhedra->New_Polyhedra_To->value ("");
2045     Polyhedra->New_Polyhedra_Min->value ("");
2046     Polyhedra->New_Polyhedra_Max->value ("");
2047     Polyhedra->New_Polyhedra_Color->value ("");
2048     Polyhedra->New_Polyhedra_Transp->value ("");
2049     Polyhedra->New_Polyhedra_Add->deactivate ();
2050     Polyhedra->New_Polyhedra_Remove->deactivate ();
2051     Polyhedra->PolyInstr1->show ();
2052     Edit_Polyhedra_Save_cb (NULL, &three);
2053 }
2054 
2055 void
2056 New_Lone_Pair_Add_cb (class Fl_Widget *, int *action)
2057 {
2058 // Add/remove lone pair in display list on Lone-Pair Edit Screen
2059     char string[100];
2060 
2061     float height, radius1, radius2;
2062 
2063     int start, end;
2064 
2065     int no;
2066 
2067     char *selection = NULL;
2068 
2069     LonePairs->LonePairInst2->show ();
2070     if (LonePairs->LonePairBuffer->selected ()) {
2071 	LonePairs->LonePairBuffer->selection_position (&start, &end);
2072 	selection = LonePairs->LonePairBuffer->line_text (start);
2073 	if (*action != 1)
2074 	    LonePairs->LonePairBuffer->remove (LonePairs->LonePairBuffer->
2075 					       line_start (start),
2076 					       LonePairs->LonePairBuffer->line_end (end) +
2077 					       1);
2078     }
2079     if (*action == 1) {
2080 	height = (float) atof (LonePairs->Height->value ());
2081 	radius1 = (float) atof (LonePairs->Radius1->value ());
2082 	radius2 = (float) atof (LonePairs->Radius2->value ());
2083 	no = atoi (LonePairs->Number->value ());
2084 
2085 	sprintf (string, "  %4s     %2d%9.3f%9.3f%9.3f     %s\n",
2086 		 LonePairs->LonePair_Combo->value (), no, height, radius1, radius2,
2087 		 LonePairs->LonePair_Color->value ());
2088 	if (selection)
2089 	    LonePairs->LonePairBuffer->replace (LonePairs->LonePairBuffer->
2090 						line_start (start),
2091 						LonePairs->LonePairBuffer->
2092 						line_end (end) + 1, string);
2093 	else
2094 	    LonePairs->LonePairBuffer->append (string);
2095     }
2096     if (selection)
2097 	free ((char *) selection);
2098     LonePairs->Number->value ("");
2099     LonePairs->Height->value ("");
2100     LonePairs->Radius1->value ("");
2101     LonePairs->Radius2->value ("");
2102     LonePairs->LonePair_Color->value ("");
2103     LonePairs->LonePair_Add->deactivate ();
2104     LonePairs->LonePair_Remove->deactivate ();
2105     LonePairs->LonePairInst1->show ();
2106     LonePairs->LonePairInst->hide ();
2107     Edit_Lone_Pair_Save_cb (NULL, &three);
2108 }
2109 
2110 void
2111 New_Polyhedra_Input_cb (class Fl_Widget *, void *)
2112 {
2113 // callback routine to make 'Add' new polyhedra button active whenever all required fields are non-blank
2114     if (Polyhedra->Polyvert->value () && !strlen (Polyhedra->New_Polyhedra_To->value ()))
2115 	return;
2116     if (Polyhedra->Polyshell->value ()
2117 	&& atof (Polyhedra->New_Polyhedra_Min->value ()) == 0.0)
2118 	return;
2119     if (atof (Polyhedra->New_Polyhedra_Max->value ()) == 0.0)
2120 	return;
2121     if (!strlen (Polyhedra->New_Polyhedra_Color->value ()))
2122 	return;
2123     Polyhedra->New_Polyhedra_Add->activate ();
2124 }
2125 
2126 void
2127 New_Sphere_Add_cb (class Fl_Widget *, int *action)
2128 {
2129 // * action == 0 - delete a sphere
2130 //          == 1 - add new sphere
2131 //          == 2 - convert existing sphere to ellipsoid (only if Uij's available)
2132 
2133     char string[100];
2134 
2135     int start, end, i, n;
2136 
2137     float size;
2138 
2139     char atom1[10], num[4], color[40];
2140 
2141     char *selection = NULL;
2142 
2143     size = (float) atof (Spheres->New_Sphere_Size->value ());
2144 
2145     Spheres->SphereInstr2->show ();
2146     strcpy (atom1, Spheres->Sphere_Combo->value ());
2147     if (Spheres->SphereBuffer->selected ()) {
2148 	Spheres->SphereBuffer->selection_position (&start, &end);
2149 	selection = Spheres->SphereBuffer->line_text (start);
2150 	if (*action != 1)
2151 	    Spheres->SphereBuffer->remove (Spheres->SphereBuffer->line_start (start),
2152 					   Spheres->SphereBuffer->line_end (end) + 1);
2153     }
2154     if (*action == 1) {
2155 	sprintf (string, "%6s %9.3f     %s\n", atom1, size,
2156 		 Spheres->New_Sphere_Color->value ());
2157 	if (selection)
2158 	    Spheres->SphereBuffer->replace (Spheres->SphereBuffer->line_start (start),
2159 					    Spheres->SphereBuffer->line_end (end) + 1,
2160 					    string);
2161 	else
2162 	    Spheres->SphereBuffer->append (string);
2163     } else if (*action == 2) {
2164 	if (selection && strlen (selection) > 0) {
2165 	    sscanf (selection, "%s %s %f %s", atom1, num, &size, color);
2166 	    if (strstr (num, "*"))
2167 		n = -1;
2168 	    else
2169 		(void) sscanf (num, "%d", &n);
2170 	} else {
2171 	    strcpy (string, atom1);
2172 	    sscanf (string, "%s %d", atom1, &n);
2173 	    if (strstr (string, "*"))
2174 		n = -1;
2175 	    strcpy (color, Spheres->New_Sphere_Color->value ());
2176 	}
2177 	while (strlen (atom1) < 4)
2178 	    strcat (atom1, " ");
2179 	for (i = 1; i < drvui->n_ellips; i++) {
2180 	    if (check_atom_name (atom1, drvui->ellips[i].ellips_l)
2181 		&& drvui->ellips[i].ell_type < 1000 && (drvui->ellips[i].ellips_n == n
2182 							|| n == -1)) {
2183 		drvui->ellips[i].ell_type = 1001;
2184 		strcpy (drvui->ellips[i].ellips_col, color);
2185 		drvui->do_ellipsoids = 1;
2186 	    }
2187 	}
2188     }
2189     free ((char *) selection);
2190     Spheres->New_Sphere_Size->value ("");
2191     Spheres->New_Sphere_Color->value ("");
2192     Spheres->Sphere_Combo->value ("");
2193     Spheres->New_Sphere_Add->deactivate ();
2194     Spheres->New_Sphere_Remove->deactivate ();
2195     Spheres->New_Sphere_Convert->deactivate ();
2196     Spheres->SphereInstr->hide ();
2197     Spheres->SphereInstr1->show ();
2198     Edit_Spheres_Save_cb (NULL, &three);
2199 }
2200 
2201 void
2202 New_Sphere_Input_cb (class Fl_Widget *, void *)
2203 {
2204     int i, n;
2205 
2206     char atom[5], number[5];
2207 
2208 // callback routine to make 'Add' new sphere button active whenever all required fields are non-blank
2209     if (atof (Spheres->New_Sphere_Size->value ()) == 0.0)
2210 	return;
2211     if (!strlen (Spheres->New_Sphere_Color->value ()))
2212 	return;
2213     Spheres->New_Sphere_Add->activate ();
2214     (void) sscanf (Spheres->Sphere_Combo->value (), "%s %s", atom, number);
2215     if (strstr (number, "*")) {
2216 	n = -1;
2217     } else {
2218 	(void) sscanf (number, "%d", &n);
2219     }
2220     while (strlen (atom) < 4)
2221 	strcat (atom, " ");
2222     for (i = 1; i < drvui->n_ellips; i++) {
2223 	if (check_atom_name (atom, drvui->ellips[i].ellips_l)
2224 	    && (drvui->ellips[i].ellips_n == n || n == -1)
2225 	    && drvui->ellips[i].ell_type == 1) {
2226 	    Spheres->New_Sphere_Convert->activate ();
2227 	}
2228     }
2229 }
2230 
2231 void
2232 next_focus (void)
2233 {
2234 // routine to change focus to next widget when <TAB> is pushed
2235     Fl_Widget *o = Fl::focus ();	// get pointer to widget with focus
2236 
2237     if (o == drvui->Origin_X) {	// from Origin_X go to Origin_Y
2238 	drvui->Origin_Y->take_focus ();
2239 	drvui->Origin_Y->position (0);	// highlight text
2240 	drvui->Origin_Y->mark (strlen (drvui->Origin_Y->value ()));
2241 	return;
2242     }
2243     if (o == drvui->Origin_Y) {
2244 	drvui->Origin_Z->take_focus ();
2245 	drvui->Origin_Z->position (0);
2246 	drvui->Origin_Z->mark (strlen (drvui->Origin_Z->value ()));
2247 	return;
2248     }
2249     if (o == drvui->Origin_Z) {
2250 	drvui->X_Rot->take_focus ();
2251 	drvui->X_Rot->position (0);
2252 	drvui->X_Rot->mark (strlen (drvui->X_Rot->value ()));
2253 	return;
2254     }
2255     if (o == drvui->X_Rot) {
2256 	drvui->Y_Rot->take_focus ();
2257 	drvui->Y_Rot->position (0);
2258 	drvui->Y_Rot->mark (strlen (drvui->Y_Rot->value ()));
2259 	return;
2260     }
2261     if (o == drvui->Y_Rot) {
2262 	drvui->Z_Rot->take_focus ();
2263 	drvui->Z_Rot->position (0);
2264 	drvui->Z_Rot->mark (strlen (drvui->Z_Rot->value ()));
2265 	return;
2266     }
2267     if (o == drvui->Z_Rot) {
2268 	drvui->X_Min->take_focus ();
2269 	return;
2270     }
2271 // set up the tab loop on the parameter edit screen
2272     if (edtprm) {
2273 	if (o == edtprm->Magnification) {
2274 	    edtprm->List->take_focus ();
2275 	    edtprm->List->position (0);
2276 	    edtprm->List->mark (strlen (edtprm->List->value ()));
2277 	}
2278 	if (o == edtprm->List) {
2279 	    edtprm->DepthCue->take_focus ();
2280 	    edtprm->DepthCue->position (0);
2281 	    edtprm->DepthCue->mark (strlen (edtprm->DepthCue->value ()));
2282 	}
2283 	if (o == edtprm->DepthCue) {
2284 	    edtprm->Mol_Comp_Dist->take_focus ();
2285 	    edtprm->Mol_Comp_Dist->position (0);
2286 	    edtprm->Mol_Comp_Dist->mark (strlen (edtprm->Mol_Comp_Dist->value ()));
2287 	}
2288 	if (o == edtprm->Mol_Comp_Dist) {
2289 	    edtprm->Cell_Edge_Width->take_focus ();
2290 	    edtprm->Cell_Edge_Width->position (0);
2291 	    edtprm->Cell_Edge_Width->mark (strlen (edtprm->Cell_Edge_Width->value ()));
2292 	}
2293 	if (o == edtprm->Cell_Edge_Width) {
2294 	    edtprm->Poly_Limit->take_focus ();
2295 	    edtprm->Poly_Limit->position (0);
2296 	    edtprm->Poly_Limit->mark (strlen (edtprm->Poly_Limit->value ()));
2297 	}
2298 	if (o == edtprm->Poly_Limit) {
2299 	    edtprm->Phong_Refl->take_focus ();
2300 	    edtprm->Phong_Refl->position (0);
2301 	    edtprm->Phong_Refl->mark (strlen (edtprm->Phong_Refl->value ()));
2302 	}
2303 	if (o == edtprm->Phong_Refl) {
2304 	    edtprm->Phong_Size->take_focus ();
2305 	    edtprm->Phong_Size->position (0);
2306 	    edtprm->Phong_Size->mark (strlen (edtprm->Phong_Size->value ()));
2307 	}
2308 	if (o == edtprm->Phong_Size) {
2309 	    edtprm->Ambient_Finish->take_focus ();
2310 	    edtprm->Ambient_Finish->position (0);
2311 	    edtprm->Ambient_Finish->mark (strlen (edtprm->Ambient_Finish->value ()));
2312 	}
2313 	if (o == edtprm->Ambient_Finish) {
2314 	    edtprm->Diffuse_Finish->take_focus ();
2315 	    edtprm->Diffuse_Finish->position (0);
2316 	    edtprm->Diffuse_Finish->mark (strlen (edtprm->Diffuse_Finish->value ()));
2317 	}
2318 	if (o == edtprm->Diffuse_Finish) {
2319 	    edtprm->Specular_Finish->take_focus ();
2320 	    edtprm->Specular_Finish->position (0);
2321 	    edtprm->Specular_Finish->mark (strlen (edtprm->Specular_Finish->value ()));
2322 	}
2323 	if (o == edtprm->Specular_Finish) {
2324 	    edtprm->Finish_Roughness->take_focus ();
2325 	    edtprm->Finish_Roughness->position (0);
2326 	    edtprm->Finish_Roughness->mark (strlen (edtprm->Finish_Roughness->value ()));
2327 	}
2328 	if (o == edtprm->Finish_Roughness) {
2329 	    edtprm->Magnification->take_focus ();
2330 	    edtprm->Magnification->position (0);
2331 	    edtprm->Magnification->mark (strlen (edtprm->Magnification->value ()));
2332 	}
2333     }
2334 // set up the tab loop on the ellipsoid edit screen
2335     if (ellipsoids) {
2336 	if (o == ellipsoids->Probability) {
2337 	    ellipsoids->Axis_Width->take_focus ();
2338 	    ellipsoids->Axis_Width->position (0);
2339 	    ellipsoids->Axis_Width->mark (strlen (ellipsoids->Axis_Width->value ()));
2340 	}
2341 	if (o == ellipsoids->Axis_Width) {
2342 	    ellipsoids->Axis_Color->take_focus ();
2343 //            ellipsoids->Axis_Color->position(0);
2344 //            ellipsoids->Axis_Color->mark(strlen(ellipsoids->Axis_Color->value()));
2345 	}
2346 	if (o == ellipsoids->Axis_Color) {
2347 	    ellipsoids->Cutout_Color->take_focus ();
2348 //            ellipsoids->Cutout_Color->position(0);
2349 //            ellipsoids->Cutout_Color->mark(strlen(ellipsoids->Cutout_Color->value()));
2350 	}
2351 	if (o == ellipsoids->Cutout_Color) {
2352 	    ellipsoids->Probability->take_focus ();
2353 	    ellipsoids->Probability->position (0);
2354 	    ellipsoids->Probability->mark (strlen (ellipsoids->Probability->value ()));
2355 	}
2356     }
2357 }
2358 
2359 void
2360 Polyhedra_Combo_cb (Fl_Widget *, void *)
2361 {
2362 // update bond distance table when the atom in the combo box is changed
2363     const char *atom;
2364     char value[10];
2365     int i;
2366 
2367     if (!drvui->table)
2368 	drvui->table = (char *) zalloc (20480 * sizeof (char));
2369     atom = Polyhedra->Polyhedra_Combo->value ();	// get name from combo box
2370     Polyhedra->New_Polyhedra_From->value (atom);	// put it in the 'From' location
2371     Load_Bond_Data (atom, drvui->table);
2372     Polyhedra->Polyhedra_Output_Buffer->text (drvui->table);
2373     for (i = 0; i<drvui->nedges; i++) {
2374 	if (!strcmp (atom, drvui->polyedges[i].name)) {
2375 		Polyhedra->Edge_Color->value( (const char*) drvui->polyedges[i].color);
2376 		sprintf (value, "%.3f", drvui->polyedges[i].radius);
2377 		Polyhedra->Edge_Radius->value(value);
2378 		return;
2379 	}
2380     }
2381     Polyhedra->Edge_Color->value("");
2382     Polyhedra->Edge_Radius->value("");
2383 }
2384 
2385 void
2386 Polyhedra_Frame_Combo_cb (Fl_Widget *, void *)
2387 {
2388 // routine called when the frame number is changed on the Polyhedra Edit Screen
2389     int i, j;
2390 
2391     char atom1[5];
2392 
2393     char atom2[5];
2394 
2395     char widget[16382];
2396 
2397     char atoms[100][5];
2398 
2399     char color[40];
2400 
2401     char string[100];
2402 
2403     int Frame_No = 1;
2404 
2405     if (drvui->max_frame > 1)
2406 	Frame_No = atoi (Polyhedra->Frame_No->value ());
2407     int nlist = Get_Unique_Atoms (atoms, Frame_No);	// get unique atom names in sorted list
2408 
2409     Polyhedra->Polyhedra_Combo->list.clear ();	// clear out the old names
2410     for (j = 0; j < nlist; j++) {	// add atom names in alphabetic order
2411 	Polyhedra->Polyhedra_Combo->list.add (atoms[j]);
2412     }
2413     Polyhedra->Polyhedra_Combo->value (atoms[0]);	// load first one in window
2414     Polyhedra_Combo_cb (NULL, NULL);
2415     widget[0] = '\0';
2416     for (i = 1; i < drvui->npoly; i++) {
2417 	if (drvui->polyhedra[i].poly_fn != Frame_No)
2418 	    continue;		//skip if not for this frame
2419 	float d1, d2;
2420 
2421 	char type[3] = "PS";
2422 
2423 	memset (atom1, 0, 5);
2424 	memset (atom2, 0, 5);
2425 	strncpy (atom1, drvui->polyhedra[i].poly_l, 4);
2426 	strncpy (atom2, drvui->polyhedra[i].poly_t, 4);
2427 	if (strlen (atom2))
2428 	    strcpy (type, "PV");
2429 	d1 = drvui->polyhedra[i].poly_min;
2430 	if (d1 > 0.005)
2431 	    strcpy (type, "SH");
2432 	d2 = drvui->polyhedra[i].poly_size;
2433 	strcpy (color, drvui->polyhedra[i].poly_col);
2434 	if (color[strlen (color) - 1] < ' ')
2435 	    color[strlen (color) - 1] = 0;
2436 	if (strlen (color) > 25)
2437 	    color[25] = 0;
2438 	trim_string (atom1, 5);
2439 	if (strlen (atom2))
2440 	    trim_string (atom2, 5);
2441 	sprintf (string, "  %2s      %4s    %4s %9.3f %9.3f     %s\n", type, atom1, atom2,
2442 		 d1, d2, color);
2443 	strcat (widget, string);
2444     }
2445     for (i = 1; i < drvui->nplane; i++) {
2446 	float d1, d2;
2447 
2448 	char type[3] = "PL";
2449 
2450 	strncpy (atom1, drvui->planes[i].plane_l, 4);
2451 	strcpy (atom2, "");
2452 	atom1[4] = 0;
2453 	for (j = 3; j >= 0; --j) {
2454 	    if (atom1[j] == ' ')
2455 		atom1[j] = 0;
2456 	}
2457 	d1 = 0.;
2458 	d2 = drvui->planes[i].plane_size;
2459 	strcpy (color, drvui->planes[i].plane_col);
2460 	if (color[strlen (color) - 1] < ' ')
2461 	    color[strlen (color) - 1] = 0;
2462 	if (strlen (color) > 25)
2463 	    color[25] = 0;
2464 	sprintf (string, "  %s      %4s    %4s %9.3f %9.3f     %s\n", type, atom1, atom2,
2465 		 d1, d2, color);
2466 	strcat (widget, string);
2467     }
2468     Polyhedra->PolyhedraBuffer->text (widget);
2469     Polyhedra->PolyInstr1->show ();
2470     Polyhedra->PolyInstr->hide ();
2471 }
2472 
2473 void
2474 Sphere_Combo_cb (Fl_Widget *, void *)
2475 {
2476 // load size and color when the Sphere Combo is changed
2477 
2478     Spheres->New_Sphere_Size->value ("0.4");
2479     Spheres->New_Sphere_Color->value ("Red");
2480     Spheres->New_Sphere_Add->activate ();
2481 /*
2482     for (i=1; i<drvui->n_ellips; i++) {
2483         if (check_atom_name(atom1,drvui->ellips_l[i]) && drvui->ell_type[i] < 1000 && drvui->ell_type[i] >= 0) {
2484             Spheres->New_Sphere_Convert->activate();
2485             i = drvui->n_ellips;
2486         }
2487     }
2488 */
2489 }
2490 
2491 struct combo_atoms_struct
2492 {
2493     char combo_atoms[7];
2494 };
2495 
2496 void
2497 Sphere_Frame_Combo_cb (Fl_Widget *, void *)
2498 {
2499 // routine called when the frame number is changed on the Spheres Edit Screen
2500     int i, j, no_ad, n, n_combo = 0;
2501 
2502     char atom[5];
2503 
2504     char tstring[5];
2505 
2506     struct combo_atoms_struct *combo;
2507 
2508     char widget[16382];
2509 
2510     char color[40];
2511 
2512     char string[100];
2513 
2514     int Frame_No = 1;
2515 
2516     combo =
2517 	(combo_atoms_struct *) zalloc (drvui->atom_alloc *
2518 				       sizeof (struct combo_atoms_struct));
2519     if (!combo) {
2520 	Error_Box ("Unable to allocate space for combo atoms.\n");
2521 	exit (0);
2522     }
2523     if (drvui->max_frame > 1)
2524 	Frame_No = atoi (Spheres->Frame_No->value ());
2525     Spheres->Sphere_Combo->list.add ("");	// add a dummy at start
2526     for (j = 0; j < natom; j++) {
2527 	memset (atom, 0, 5);
2528 	if (drvui->atoms[j].atom_fn != Frame_No)
2529 	    continue;
2530 	strcpy (atom, drvui->atoms[j].atom_l);
2531 	strcpy (string, drvui->atoms[j].atom_l);
2532 	n = drvui->atoms[j].sv_atom_n;;
2533 	no_ad = 0;
2534 	for (i = 1; i < drvui->n_ellips; i++) {
2535 	    if (check_atom_name (atom, drvui->ellips[i].ellips_l)
2536 		&& drvui->ellips[i].ell_type > 1000 && drvui->ellips[i].ellips_n == n) {
2537 		no_ad = 1;
2538 		i = drvui->n_ellips;
2539 	    }
2540 	}
2541 	if (!no_ad) {
2542 	    sprintf (tstring, "%2d", n);
2543 	    strcat (string, tstring);
2544 	    Spheres->Sphere_Combo->list.add (string);
2545 	    n = 1;
2546 	    for (i = 0; i < n_combo; i++) {
2547 		if (check_atom_name (atom, combo[i].combo_atoms))
2548 		    n = 0;
2549 	    }
2550 	    if (n) {
2551 		strcpy (string, atom);
2552 		strcat (string, " *");
2553 		strcpy (combo[n_combo++].combo_atoms, string);
2554 	    }
2555 	}
2556     }
2557     for (i = 0; i < n_combo; i++)
2558 	Spheres->Sphere_Combo->list.insert (i + 2, combo[i].combo_atoms);
2559     Spheres->Sphere_Combo->value ("");	// load blank in window
2560     Sphere_Combo_cb (NULL, NULL);
2561     widget[0] = '\0';
2562     for (i = 1; i < drvui->nsphere; i++) {	// process sphere info
2563 	if (drvui->spheres[i].sphere_fn != Frame_No)
2564 	    continue;		//skip if not for this frame
2565 	float d1;
2566 
2567 	d1 = drvui->spheres[i].sphere_size;
2568 	strcpy (atom, drvui->spheres[i].sphere_l);
2569 	while (strlen (atom) < 4)
2570 	    strcat (atom, " ");
2571 	strcpy (color, drvui->spheres[i].sphere_col);
2572 	if (drvui->spheres[i].sphere_n > 0) {
2573 	    sprintf (string, "%4s%2d %9.3f     %s\n", atom, drvui->spheres[i].sphere_n,
2574 		     d1, color);
2575 	} else {
2576 	    sprintf (string, "%4s * %9.3f     %s\n", atom, d1, color);
2577 	}
2578 	strcat (widget, string);
2579     }
2580     Spheres->SphereBuffer->text (widget);
2581     if (strlen (widget) > 5)
2582 	Spheres->SphereInstr1->show ();
2583     free (combo);
2584 }
2585 
2586 void
2587 View_Console_cb (void)		// callback to list the 'cns' file
2588 {				// see View_Listing_cb for detailed comments
2589     static int one = 1;
2590 
2591 // callback routine to view the console listing
2592     if (!strlen (drvui->Cur_File)) {	// Make sure rendering enabled
2593 	Error_Box ("A Structure File must be selected first.");
2594 	return;
2595     }
2596     if (!listwindow1) {
2597 	listwindow1 = new Fl_Window (50, 50, 680, 450, "Console Output");
2598 	listwindow1->begin ();
2599 	listwindow1->callback ((Fl_Callback *) View_Listing_Close_cb, &one);
2600 	Fl_Text_Editor *display = new Fl_Text_Editor (0, 0, 680, 410);
2601 
2602 	textbuf1 = new Fl_Text_Buffer;
2603 	display->buffer (textbuf1);
2604 	display->textfont (FL_COURIER);
2605 	Fl_Button *o = new Fl_Button (300, 415, 80, 30, "Close");
2606 
2607 	o->tooltip ("Close this window and discard all changes.");
2608 	o->callback ((Fl_Callback *) View_Listing_Close_cb, &one);
2609 	listwindow1->end ();
2610 #if !defined (WIN32) && !defined (__APPLE__)
2611 	listwindow1->icon ((char *) drvui->icon);
2612 #endif
2613     }
2614     textbuf1->loadfile (drvui->Cur_Console);
2615     listwindow1->show ();
2616 }
2617 
2618 void
2619 View_Cursor_cb (void)		// callback to show a dedicated window for
2620 {				// Graphics Cursor feedback
2621     static int five = 5;
2622 
2623     if (!strlen (drvui->Cur_File)) {	// Make sure rendering enabled
2624 	Error_Box ("A Structure File must be selected first.");
2625 	return;
2626     }
2627 
2628     if (!listwindow5) {
2629 	listwindow5 = new Fl_Window (50, 50, 550, 550, "Geometry Information");
2630 	listwindow5->begin ();
2631 	listwindow5->callback ((Fl_Callback *) View_Listing_Close_cb, &five);
2632 
2633 	drvui->Cursor_posW = new Fl_Browser (15, 15, 520, 450);
2634 	static int bwidths[] = { 160,100,80,80,80,0 };
2635         static const Fl_Menu_Item resetmodes[] = {
2636 	    {"never", 0, NULL, (void *) 0, 0, 0, 0, 14, 56},
2637 	    {"after 2 atoms", 0, NULL, (void *) 0, 0, 0, 0, 14, 56},
2638 	    {"after 3 atoms", 0, NULL, (void *) 0, 0, 0, 0, 14, 56},
2639 	    {"after 4 atoms", 0, NULL, (void *) 0, 0, 0, 0, 14, 56},
2640 	    {0, 0, 0, 0, 0, 0, 0, 0, 0}
2641 	};
2642 	drvui->Cursor_posW->column_widths (bwidths);
2643 	drvui->Cursor_posW->column_char ('\t');
2644 	drvui->Cursor_posW->type (FL_MULTI_BROWSER);
2645 	drvui->Cursor_posW->box (FL_FRAME_BOX);
2646 	drvui->Cursor_posW->color (FL_BACKGROUND_COLOR);
2647 
2648 	update_cursor_window();
2649 
2650 	listwindow5->resizable(drvui->Cursor_posW);
2651 
2652 	Fl_Choice *p = drvui->Cursor_reset =
2653 	    new Fl_Choice (220, 480, 125, 25, "Reset list ");
2654 	p->align (FL_ALIGN_LEFT);
2655 	p->callback (Cursor_Reset_Combo_cb);
2656 	p->labelfont (1);
2657 	p->menu (resetmodes);
2658 	p->value (0);
2659 
2660 	Fl_Button *o = new Fl_Button (240, 515, 80, 30, "Close");
2661 
2662 	o->tooltip ("Close this window");
2663 	o->callback ((Fl_Callback *) View_Listing_Close_cb, &five);
2664 	listwindow5->end ();
2665 #if !defined (WIN32) && !defined (__APPLE__)
2666 	listwindow5->icon ((char *) drvui->icon);
2667 #endif
2668     }
2669     listwindow5->show ();
2670 }
2671 
2672 void
2673 View_File_cb (void)		// callback to view any file
2674 {				// see View_Listing_cb for detailed comments
2675     static int three = 3;
2676 
2677     char *newfile;
2678 
2679     static char label[100];
2680 
2681 // callback routine to view the any file
2682     if (!listwindow3) {
2683 	listwindow3 = new Fl_Window (50, 50, 680, 450, "");
2684 	listwindow3->begin ();
2685 	listwindow3->callback ((Fl_Callback *) View_Listing_Close_cb, &three);
2686 	Fl_Text_Editor *display = new Fl_Text_Editor (0, 0, 680, 410);
2687 
2688 	textbuf3 = new Fl_Text_Buffer;
2689 	display->buffer (textbuf3);
2690 	display->textfont (FL_COURIER);
2691 	Fl_Button *o = new Fl_Button (300, 415, 80, 30, "Close");
2692 
2693 	o->tooltip ("Close this window.");
2694 	o->callback ((Fl_Callback *) View_Listing_Close_cb, &three);
2695 	listwindow3->end ();
2696 #if !defined (WIN32) && !defined (__APPLE__)
2697 	listwindow3->icon ((char *) drvui->icon);
2698 #endif
2699     }
2700     newfile = fl_file_chooser ("Select File to View", "*.*", NULL, 1);
2701     if (newfile) {
2702 	textbuf3->loadfile (newfile);
2703 	sprintf (label, "File View: %s", newfile);
2704 	listwindow3->label (label);
2705 	listwindow3->show ();
2706     }
2707 }
2708 
2709 void
2710 View_Listing_cb (void)		// callback to list the '.out' file
2711 {
2712     static int two = 2;
2713 
2714     if (!strlen (drvui->Cur_File)) {	// Make sure rendering enabled
2715 	Error_Box ("A Structure File must be selected first.");
2716 	return;
2717     }
2718 // callback to view listing file
2719     if (!listwindow2) {
2720 	listwindow2 = new Fl_Window (50, 50, 760, 450, "Listing View");
2721 	listwindow2->begin ();
2722 	listwindow2->callback ((Fl_Callback *) View_Listing_Close_cb, &two);
2723 	Fl_Text_Display *display = new Fl_Text_Display (0, 0, 760, 410);
2724 
2725 	display->textfont (FL_COURIER);
2726 	textbuf2 = new Fl_Text_Buffer;
2727 	display->buffer (textbuf2);
2728 	Fl_Button *o = new Fl_Button (340, 415, 80, 30, "Close");
2729 
2730 	o->tooltip ("Close this window and discard all changes.");
2731 	o->callback ((Fl_Callback *) View_Listing_Close_cb, &two);
2732 	listwindow2->end ();
2733 #if !defined (WIN32) && !defined (__APPLE__)
2734 	listwindow2->icon ((char *) drvui->icon);
2735 #endif
2736     }
2737     textbuf2->loadfile (drvui->Cur_Listing);
2738     listwindow2->show ();
2739 }
2740 
2741 void
2742 View_Listing_Close_cb (Fl_Window *, int *arg)	// callback to hide listing windows
2743 {
2744     switch (*arg) {
2745     case 1:
2746 	listwindow1->hide ();
2747 	break;
2748     case 2:
2749 	listwindow2->hide ();
2750 	break;
2751     case 3:
2752 	listwindow3->hide ();
2753 	break;
2754     case 4:
2755 	listwindow4->hide ();
2756 	break;
2757     case 5:
2758 	listwindow5->hide ();
2759 	break;
2760     }
2761 }
2762 
2763 void
2764 View_POV_cb (void)
2765 {
2766 // Callback routine to view the POV file
2767     char cmd[512], incpath[256], errfile[1024];
2768 
2769     int i;
2770 
2771     if (!strlen (drvui->CurFile->value ())) {	// Make sure rendering enabled
2772 	Error_Box ("A Structure File must be selected first.");
2773 	return;
2774     }
2775     Update_Str (0);		// Update str file
2776     Generate_Drawing (0);	// Update picture
2777     Fl::flush ();		// Clear the menu bleed through
2778 
2779     incpath[0] = '\0';
2780     if (strlen (drvui->POV_Include) > 10)
2781 	strcpy (incpath, drvui->POV_Include);	// make copy of colors.inc full path name
2782 
2783 #ifdef WIN32
2784     strcpy (cmd, "\"\"");	// build the command string
2785     strcat (cmd, drvui->POV_Path);	//   for Windows
2786     strcat (cmd, "\"");
2787     strcat (cmd, " ");
2788     strcat (cmd, drvui->POV_Options);
2789     strcat (cmd, " ");
2790     strcat (cmd, " +I\"");
2791 #else
2792     strcpy (cmd, drvui->POV_Path);	// build command string
2793     strcat (cmd, " ");		//    for Linux
2794     strcat (cmd, drvui->POV_Options);
2795     strcat (cmd, " ");
2796     if (strlen (incpath) > 0) {
2797 	strcat (cmd, " +HI");
2798 	strcat (cmd, incpath);
2799 	strcat (cmd, " ");
2800     }
2801 #endif
2802     strcat (cmd, drvui->Cur_Root);
2803     strcat (cmd, ".pov");
2804 
2805     strcpy (errfile, drvui->Cur_Root);
2806     strcat (errfile, ".err");
2807 #ifdef WIN32
2808     strcat (cmd, "\"\"");
2809 #else
2810     strcat (cmd, " +GF");
2811     strcat (cmd, errfile);
2812 #endif
2813     FILE *ef = fopen (errfile, "w");
2814 
2815     fprintf (ef, "An error occurred running the POVRAY program.\n");
2816     fprintf (ef, "The most probable cause is that the path is not correct.\n");
2817     fprintf (ef, "Check settings in File/Configure/POV menu\n");
2818     fclose (ef);
2819 
2820     Fl::flush ();
2821 #ifdef WIN32
2822     drvui->mainWindow->hide ();
2823 #endif
2824     i = system (cmd);		// call the POV program
2825 #ifdef WIN32
2826     drvui->mainWindow->show ();
2827 #endif
2828     if (i != 0) {
2829 	if (!listwindow4) {
2830 	    static int four = 4;
2831 
2832 	    listwindow4 = new Fl_Window (50, 50, 760, 450, "POV error messages");
2833 	    listwindow4->begin ();
2834 	    listwindow4->callback ((Fl_Callback *) View_Listing_Close_cb, &four);
2835 	    Fl_Text_Display *display = new Fl_Text_Display (0, 0, 760, 410);
2836 
2837 	    display->textfont (FL_COURIER);
2838 	    textbuf4 = new Fl_Text_Buffer;
2839 	    display->buffer (textbuf4);
2840 	    Fl_Button *o = new Fl_Button (340, 415, 80, 30, "Close");
2841 
2842 	    o->tooltip ("Close this window.");
2843 	    o->callback ((Fl_Callback *) View_Listing_Close_cb, &four);
2844 	    listwindow4->end ();
2845 #if !defined (WIN32) && !defined (__APPLE__)
2846 	    listwindow4->icon ((char *) drvui->icon);
2847 #endif
2848 	}
2849 	textbuf4->loadfile (errfile);
2850 	listwindow4->show ();
2851 //        Error_Box("An error occurred running the POVRAY program.\nCheck settings in File/Configure/POV menu\nand contents of POV output file PROJECT.err.");
2852     } else
2853 	unlink (errfile);
2854 }
2855 
2856 void
2857 Write_Map_cb (void)
2858 {
2859     int i, j, k, ijk;
2860 
2861     FILE *mapout;
2862 
2863     char *newfile =
2864 	fl_file_chooser ("Select Output 'grd'", "*.*", Maps->Filename->value (), 1);
2865     if (newfile) {
2866 	if (!(mapout = fopen (newfile, "w"))) {
2867 	    Error_Box ("Unable to open selected output file.");
2868 	    return;
2869 	}
2870 	if (!FourierPt) {
2871 	    Error_Box ("Fourier Map Not Available.");
2872 	    fclose (mapout);
2873 	    return;
2874 	}
2875 	fprintf (mapout, "%s\n", Map_Info.title);
2876 	fprintf (mapout, "%f %f %f %f %f %f\n", Map_Info.lat_con[0],
2877 		 Map_Info.lat_con[1], Map_Info.lat_con[2], Map_Info.lat_con[3],
2878 		 Map_Info.lat_con[4], Map_Info.lat_con[5]);
2879 	fprintf (mapout, "%d %d %d\n", Map_Info.map_int[0], Map_Info.map_int[1],
2880 		 Map_Info.map_int[2]);
2881 
2882 	ijk = 0;
2883 /* Write the Rho values */
2884 	for (i = 0; i < Map_Info.map_int[0]; i++) {
2885 	    for (j = 0; j < Map_Info.map_int[1]; j++) {
2886 		for (k = 0; k < Map_Info.map_int[2]; k++) {
2887 		    fprintf (mapout, " %f\n", FourierPt[ijk++]);
2888 		}
2889 	    }
2890 	}
2891 	fclose (mapout);
2892 	Maps->Filename->value (newfile);
2893 	FourierMapType = 1;	// new type
2894 	Maps->MapType->value ("GSAS - grd");
2895     }
2896 }
2897 
2898 void
2899 Dump_View_cb (void)
2900 {
2901     FILE *fp;
2902 
2903     char file[256];
2904 
2905     int state = GL2PS_OVERFLOW, buffsize = 0;
2906 
2907     int format = GL2PS_EPS;
2908 
2909     int sort;
2910 
2911     int options =
2912 	GL2PS_DRAW_BACKGROUND | GL2PS_NO_BLENDING | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT
2913 	| GL2PS_SILENT | GL2PS_TIGHT_BOUNDING_BOX;
2914     int nbcol = 16;
2915 
2916     GLint viewport[4];
2917 
2918     float cpx, cpy, cpz;
2919 
2920     float m[16];
2921     GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
2922     GLfloat light_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
2923     GLfloat light_specular[] = { 0.1f, 0.1f, 0.1f, 1.0f };
2924     GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
2925     GLfloat mat_shininess[] = { 0.8f };
2926     GLfloat light_position[] = { 0.0f, 1.0f, 1.0f, 0.0f };
2927     GLfloat light_direction[] = { 0.0f, -1.0f, 0.0f };
2928 
2929     if (!strlen (drvui->CurFile->value ())) {	// Make sure rendering enabled
2930 	Error_Box ("A Structure File must be selected first.");
2931 	return;
2932     }
2933 //   if (ReadFourMap)
2934 //     sort = GL2PS_SIMPLE_SORT;
2935 //   else
2936     sort = GL2PS_BSP_SORT;
2937 
2938 
2939     Update_Str (0);		// Update str file
2940     Generate_Drawing (0);	// Update picture
2941 
2942     glGetIntegerv (GL_VIEWPORT, viewport);
2943     strcpy (file, drvui->Cur_Root);
2944     strcat (file, ".ps");
2945 
2946     fp = fopen (file, "wb");
2947 
2948     while (state == GL2PS_OVERFLOW) {
2949 	buffsize += 1024 * 1024;
2950 	gl2psBeginPage (file, "DRAWxtl 5.5", viewport, format, sort, options,
2951 			GL_RGBA, 0, NULL, nbcol, nbcol, nbcol, buffsize, fp, file);
2952 
2953 	glMatrixMode (GL_PROJECTION);
2954 	glLoadIdentity ();
2955 	if (M_cameras == 0) {
2956 	    glOrtho (-gl_size, gl_size, -gl_size, gl_size, -10000., 10000.);
2957 	} else {
2958 	    gluPerspective (17., 1., 0.01, 1000.);
2959 	}
2960 	glMatrixMode (GL_MODELVIEW);
2961 	glLoadIdentity ();
2962 	cpx = (POV_Max[0] + POV_Min[0]) / 2.0f;
2963 	cpy = (POV_Max[1] + POV_Min[1]) / 2.0f;
2964 	cpz = (POV_Max[2] + POV_Min[2]) / 2.0f;
2965 //    glShadeModel (GL_SMOOTH);
2966 	glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular);
2967 	glMaterialfv (GL_FRONT, GL_SHININESS, mat_shininess);
2968 	glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular);
2969 	glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse);
2970 	glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient);
2971 	glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
2972 	glEnable (GL_LIGHTING);
2973 	glEnable (GL_LIGHT0);
2974 	glEnable (GL_COLOR_MATERIAL);
2975 	glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
2976 	glEnable (GL_DEPTH_TEST);
2977 	glDepthFunc (GL_LESS);
2978 	glClearColor (drvui->glback[0], drvui->glback[1], drvui->glback[2], 0.0f);
2979 	glClear ((GLbitfield) (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
2980 //    glLoadIdentity();
2981 //    glEnable(GL_BLEND);
2982 //    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2983 	gluLookAt (cpx, cpy, Scale * .50,	// camera position
2984 		   cpx, cpy, -1.0,	// camera lookat point
2985 		   0.0f, 1.0f, 0.0f);	// camera "up" vector
2986 	glLightfv (GL_LIGHT0, GL_POSITION, light_position);
2987 	glLightfv (GL_LIGHT0, GL_SPOT_DIRECTION, light_direction);
2988 	glColor3f (0.0f, 0.0f, 0.0f);
2989 	glPushMatrix ();
2990 //    glTranslatef (gl_pos_x, gl_pos_y, gl_pos_z);
2991 	glTranslatef (drvui->Trans[0], drvui->Trans[1], drvui->Trans[2]);
2992 	quaternion_to_rotmatrix (&Rotq, m);
2993 
2994 	glMultMatrixf (m);
2995 	glTranslatef (-cpx, -cpy, -cpz);
2996 	draw_cursor ();
2997 	glCallList (drvui->crystalDL);
2998 	for (drvui->frame_no = 1; drvui->frame_no <= drvui->max_frame; drvui->frame_no++)
2999 	    generate_gl_texts ();
3000 	glPopMatrix ();
3001 	drvui->frame_no = drvui->max_frame;
3002 
3003 
3004 	state = gl2psEndPage ();
3005     }
3006 
3007     if (state > 2)
3008 	Error_Box ("Generation of Postscript file failed.");
3009 
3010     fclose (fp);
3011 
3012 }
3013 
3014 void
3015 Cursor_Reset_Combo_cb (Fl_Widget *, void *)
3016 {
3017     drvui->cur_reset = drvui->Cursor_reset->value ();
3018     if (drvui->cur_reset == 0) drvui->cur_reset --;
3019 }
3020 
3021 void
3022 Edit_Surfaces_cb (void)
3023 {
3024 // Callback routine to show the Surface Parameter screen and load the widgets on that page
3025     char string[128];
3026 
3027     static int zero = 0;
3028 
3029     static int one = 1;
3030 
3031     int y;
3032 
3033     int i;
3034 
3035     int wh;
3036 
3037     char widget[2048];
3038 
3039     char type[6];
3040 
3041     if (!strlen (drvui->CurFile->value ())) {	// Make sure rendering enabled
3042 	Error_Box ("A Structure File must be selected first.");
3043 	return;
3044     }
3045     Save_Working_Copy ();
3046     if (!Surf) {
3047 	char title[30];
3048 
3049 	    strcpy (title, "Edit Surface parameters");
3050 	Surf = new SurfParam;	// new instance of the surface parameters
3051 
3052 	wh = 535;
3053 	if (drvui->max_frame > 1)
3054 	    wh += 60;
3055 	Surf->Surfaces_Edit_Window = new Fl_Window (50, 50, 500, wh, title);
3056 
3057 	Surf->Surfaces_Edit_Window->callback ((Fl_Callback *) Edit_Surfaces_Close_cb);
3058 	y = 20;
3059 	if (drvui->max_frame > 1) {
3060 	    Surf->Frame_No =
3061 		new Flu_Combo_List (220, y, 75, 25, "Frame No.");
3062 	    Surf->Frame_No->align (FL_ALIGN_TOP);
3063 	    Surf->Frame_No->callback (Surface_Frame_Combo_cb);
3064 	    Surf->Frame_No->labelfont (1);
3065 	    for (i = 1; i <= drvui->max_frame; i++) {
3066 		sprintf (string, "%d", i);
3067 		Surf->Frame_No->list.add (string);
3068 	    }
3069 	    Surf->Frame_No->pop_height (20 * drvui->max_frame);
3070 	    Surf->Frame_No->value ("1");
3071             y += 50;
3072 	}
3073 	Fl_Box *ob = new Fl_Box (10,y-20,480,y+200,"Bader AIM theory surfaces");
3074 	ob->box(FL_ENGRAVED_BOX);
3075 	ob->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE);
3076 	y += 15;
3077 
3078 	strcpy (widget, "");
3079 	Surf->AimSurfBuffer = new Fl_Text_Buffer;
3080 	Surf->AimSurfBuffer->add_modify_callback ((Fl_Text_Modify_Cb) Modify_AimSurfaces_cb,
3081 					       (void *) NULL);
3082 	Fl_Text_Editor *o =
3083 		new Fl_Text_Editor (50, y, 420, 80, "Atom       surfFile         Type       Color     ");
3084 	o->labelfont (FL_COURIER_BOLD);
3085 	o->textfont (FL_COURIER);
3086 	o->buffer (Surf->AimSurfBuffer);
3087 
3088 	Surf->AimSurfInstr = new Fl_Output (20, y + 100, 450, 0, "Press 'Add' to replace "
3089 					 "selected line - 'Remove' to delete it");
3090 	Surf->AimSurfInstr->hide ();
3091 	Surf->AimSurfInstr->align (FL_ALIGN_BOTTOM);
3092 	Surf->AimSurfInstr1 = new Fl_Output (20, y + 85, 450, 0, "Highlight text above "
3093 					  "or double click to edit line");
3094 	Surf->AimSurfInstr1->align (FL_ALIGN_BOTTOM);
3095 	y += 110;
3096 	Flu_Combo_List *oc = Surf->AimSurf_Combo =
3097 	    new Flu_Combo_List (45, y, 75, 25, "Atom");
3098 	oc->align (FL_ALIGN_BOTTOM);
3099 //	oc->callback (AimSurf_Combo_cb);
3100 
3101 	Surf->AimFile = new Fl_Input (120, y, 90, 25, "Filename");
3102 	Surf->AimFile->align (FL_ALIGN_BOTTOM);
3103 	Surf->AimFile->callback ((Fl_Callback *) New_AimSurf_Input_cb);
3104 	Surf->AimSurfType = new Flu_Combo_List (220, y, 70, 25, "Type");
3105 	Surf->AimSurfType->align (FL_ALIGN_BOTTOM);
3106 	Surf->AimSurfType->callback ((Fl_Callback *) New_AimSurf_Input_cb);
3107 	Surf->AimSurfType->list.add ("mesh");
3108 	Surf->AimSurfType->list.add ("solid");
3109 	Surf->AimSurfType->list.add ("dots");
3110 	Surf->AimSurfType->pop_height (40);
3111 
3112 	Surf->AimSurfColor = new Flu_Combo_List (300, y, 160, 25, "Color");
3113 	Load_Color_Combo (Surf->AimSurfColor);
3114 	Surf->AimSurfColor->align (FL_ALIGN_TOP);
3115 	Surf->AimSurfColor->callback ((Fl_Callback *) New_AimSurf_Input_cb);
3116 	Surf->AimSurfColor->align (FL_ALIGN_BOTTOM);
3117 	y += 45;
3118 
3119 	Fl_Button *om;
3120 	Fl_Button *mm;
3121 
3122 	om = Surf->Add_Button = new Fl_Button (180, y, 70, 25, "Add");
3123 	om->callback ((Fl_Callback *) New_AimSurf_Add_cb, &one);
3124 	om->tooltip ("When active, press to transfer data in boxes to window above");
3125 	om->deactivate ();
3126 	mm = Surf->Remove_Button = new Fl_Button (270, y, 70, 25, "Remove");
3127 	mm->callback ((Fl_Callback *) New_AimSurf_Add_cb, &zero);
3128 	mm->tooltip ("When active, press to remove highlighted line.");
3129 	mm->deactivate ();
3130 
3131 	Fl_Box *obb = new Fl_Box (10, y + 35, 480, 300, "Contact Surfaces and Void Volumes");
3132 	obb->box(FL_ENGRAVED_BOX);
3133 	obb->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE);
3134 
3135 	Surf->SurfType = new Flu_Combo_List (40, y + 60, 180, 25, "Method");
3136 	Surf->SurfType->align (FL_ALIGN_BOTTOM);
3137 //	Surf->SurfType->callback ((Fl_Callback *) New_Surf_Input_cb);
3138 	Surf->SurfType->list.add ("No surface");
3139 	Surf->SurfType->list.add ("Grid search");
3140 	Surf->SurfType->list.add ("MSMS (run now)");
3141 	Surf->SurfType->list.add ("MSMS (precalculated)");
3142 	Surf->SurfType->list.add ("Surface area test");
3143 	Surf->SurfType->pop_height (40);
3144 	Surf->SurfColor = new Flu_Combo_List (300, y + 60, 160, 25, "Color");
3145 	Load_Color_Combo (Surf->SurfColor);
3146 	Surf->SurfColor->list.add("byatom");
3147 	Surf->SurfColor->align (FL_ALIGN_TOP);
3148 	Surf->SurfColor->align (FL_ALIGN_BOTTOM);
3149 	Surf->Probe = new Fl_Input (120, y + 100, 30, 25, "Probe radius:");
3150 	Surf->Probe->align (FL_ALIGN_LEFT);
3151 	Surf->GridX = new Fl_Input (220, y + 100, 40, 25, "Gridsize:");
3152 	Surf->GridX->align (FL_ALIGN_LEFT);
3153 	Surf->GridY = new Fl_Input (270, y + 100, 40, 25, "x");
3154 	Surf->GridY->align (FL_ALIGN_LEFT);
3155 	Surf->GridZ = new Fl_Input (320, y + 100, 40, 25, "x");
3156 	Surf->GridZ->align (FL_ALIGN_LEFT);
3157 
3158 	y += 150;
3159 
3160 	Surf->SurfBuffer = new Fl_Text_Buffer;
3161 	Surf->SurfBuffer->add_modify_callback ((Fl_Text_Modify_Cb) Modify_Surfaces_cb,
3162 					       (void *) NULL);
3163 	Fl_Text_Editor *os =
3164 		new Fl_Text_Editor (140, y, 200, 60, "Atom       Radius");
3165 	os->labelfont (FL_COURIER_BOLD);
3166 	os->textfont (FL_COURIER);
3167 	os->buffer (Surf->SurfBuffer);
3168 
3169 	Surf->SurfInstr = new Fl_Output (20, y + 80, 450, 0, "Press 'Add' to replace "
3170 					 "selected line - 'Remove' to delete it");
3171 	Surf->SurfInstr->hide ();
3172 	Surf->SurfInstr->align (FL_ALIGN_BOTTOM);
3173 	Surf->SurfInstr1 = new Fl_Output (20, y + 60, 450, 0, "Highlight text above "
3174 					  "or double click to edit line");
3175 	Surf->SurfInstr1->align (FL_ALIGN_BOTTOM);
3176 	y += 80;
3177 	Flu_Combo_List *osc = Surf->Surf_Combo =
3178 	    new Flu_Combo_List (145, y, 75, 25, "Atom");
3179 	osc->align (FL_ALIGN_BOTTOM);
3180 //	osc->callback (Surf_Combo_cb);
3181 
3182 	Surf->Radius = new Fl_Input (220, y, 90, 25, "Radius");
3183 	Surf->Radius->align (FL_ALIGN_BOTTOM);
3184 	Surf->Radius->callback ((Fl_Callback *) New_Surf_Input_cb);
3185 
3186 	y += 40;
3187 	Fl_Button *osm;
3188 
3189 	Fl_Button *msm;
3190 
3191 	osm = Surf->Add_Button2 = new Fl_Button (180, y, 70, 20, "Add");
3192 	osm->callback ((Fl_Callback *) New_Radius_Add_cb, &one);
3193 	osm->tooltip ("When active, press to transfer data in boxes to window above");
3194 	osm->deactivate ();
3195 	msm = Surf->Remove_Button2 = new Fl_Button (270, y, 70, 20, "Remove");
3196 	msm->callback ((Fl_Callback *) New_Radius_Add_cb, &zero);
3197 	msm->tooltip ("When active, press to remove highlighted line.");
3198 	msm->deactivate ();
3199 
3200 	y += 10;
3201 
3202 	Surf->AimSurfInstr2 = new Fl_Output (25, y, 450, 0,
3203 					  "Changes are temporary until \"Apply\" or \"Save\" is pressed.");
3204 	Surf->AimSurfInstr2->hide ();
3205 	Surf->AimSurfInstr2->align (FL_ALIGN_BOTTOM);
3206 	y += 20;
3207 
3208 	Fl_Button *r = new Fl_Button (125, y, 70, 25, "Close");
3209 
3210 	r->tooltip ("Close this window and discard all changes.");
3211 	r->callback ((Fl_Callback *) Edit_Surfaces_Close_cb);
3212 	Fl_Button *s = new Fl_Button (325, y, 70, 25, "Save");
3213 
3214 	s->tooltip
3215 	    ("Apply current contents of top box to drawing, then close this window.");
3216 	s->callback ((Fl_Callback *) Edit_Surfaces_Save_cb, &one);
3217 	Fl_Button *a = new Fl_Button (225, y, 70, 25, "Apply");
3218 
3219 	a->tooltip
3220 	    ("Apply current contents of top box to drawing, but leave this window open.");
3221 	a->callback ((Fl_Callback *) Edit_Surfaces_Save_cb, &zero);
3222 #if !defined (WIN32) && !defined (__APPLE__)
3223 	Surf->Surfaces_Edit_Window->icon ((char *) drvui->icon);
3224 #endif
3225     }
3226     strcpy (widget, "");
3227     if (drvui->nsurf > 1)
3228         for (i = 1; i < drvui->nsurf; i++) {	// fill in the widgets
3229 
3230 	    switch (drvui->surftype[i]) {
3231 		case 0:
3232 		default:
3233 		strcpy (type, "mesh ");
3234 	        break;
3235 		case 1:
3236 		strcpy (type, "solid");
3237 		break;
3238 		case 2:
3239 		strcpy (type, "dots ");
3240 		break;
3241 	    }
3242 	    sprintf (string, "%4s%2d    %s      %s     %s\n",
3243 		     drvui->surfatom[i],drvui->surfnum[i], drvui->surffile[i], type,
3244 		     drvui->surfcolor[i]);
3245 	strcat (widget, string);
3246     }
3247     Surf->AimSurfBuffer->text (widget);
3248 
3249     Surf->AimSurfInstr1->show ();
3250     Surface_Frame_Combo_cb(NULL,NULL);
3251 
3252     if (drvui->voidflag==0) {
3253 	Surf->SurfType->value("No surface");
3254     } else {
3255 	char tmpstr[20];
3256 	if (drvui->voidflag ==1) Surf->SurfType->value("Grid search");
3257 	if (drvui->voidflag ==2) Surf->SurfType->value("MSMS (run now)");
3258 	if (drvui->voidflag ==-2) Surf->SurfType->value("MSMS (precalculated)");
3259 	if (drvui->voidflag ==3) Surf->SurfType->value("Surface area test");
3260 	Surf->SurfColor->value(drvui->voidcolor);
3261 	if (drvui->probesize > 0.) {
3262 		sprintf(tmpstr,"%.2f",drvui->probesize);
3263 		Surf->Probe->value(tmpstr);
3264 	}
3265 	sprintf (tmpstr,"%d",drvui->voidgrid[0]);
3266 	Surf->GridX->value(tmpstr);
3267 	sprintf (tmpstr,"%d",drvui->voidgrid[1]);
3268 	Surf->GridY->value(tmpstr);
3269 	sprintf (tmpstr,"%d",drvui->voidgrid[2]);
3270 	Surf->GridZ->value(tmpstr);
3271 
3272     strcpy (widget, "");
3273     if (drvui->natprop > 1)
3274         for (i = 1; i < drvui->natprop; i++) {	// fill in the widgets
3275 	    if (drvui->atprops[i].atprop_n != -1)
3276 		sprintf (string, "%4s%2d    %f\n",
3277 			 drvui->atprops[i].atprop_l,drvui->atprops[i].atprop_n,drvui->atprops[i].radius);
3278 	    else
3279 		sprintf (string, "%4s *    %f\n",
3280 			 drvui->atprops[i].atprop_l,drvui->atprops[i].radius);
3281 	    strcat (widget, string);
3282     }
3283     Surf->SurfBuffer->text (widget);
3284 
3285     }
3286     Surf->Surfaces_Edit_Window->end ();
3287     Surf->Surfaces_Edit_Window->show ();
3288 }
3289 
3290 void
3291 Edit_Surfaces_Close_cb (void)
3292 {
3293     Surf->Surfaces_Edit_Window->~Fl_Window ();	// this window needs to be deleted
3294     delete (Surf->Surfaces_Edit_Window);	// not just killed (2d/3d nature might change)
3295     delete (Surf->AimSurfBuffer);
3296     delete (Surf);
3297     Surf = NULL;
3298     Restore_Working_Copy ();	// undo any changes
3299     Generate_Drawing (1);	// regenerate
3300 }
3301 
3302 void
3303 Edit_Surfaces_Save_cb (Fl_Button *, int *save)
3304 {
3305 // callback routine when 'save' or 'apply' button is pressed on the Edit Maps screen
3306     char type[5], number[5], color[40], widget[16382];
3307     char filename[128];
3308     char atom[5];
3309     char t_name[5];
3310     int num;
3311     float radius;
3312 
3313     unsigned int j, k;
3314 
3315     int kk;
3316 
3317     int i = 0;
3318 
3319     int Frame_No = 1;
3320 
3321     char *selection = Surf->AimSurfBuffer->text ();
3322 
3323     if (drvui->max_frame > 1)
3324 	Frame_No = atoi (Surf->Frame_No->value ());
3325 
3326     strcpy (widget, selection);
3327     free (selection);
3328 
3329     drvui->nsurf = 1;
3330 
3331     if (strlen (widget) < 10) {
3332 	strcpy (widget, "");
3333 	Surf->AimSurfBuffer->text (widget);
3334     } else {
3335 	while (strlen (widget) > 10) {
3336 	    i++;
3337 		sscanf (widget, "%s %d %s %s %s", atom, &num, filename, type, color);
3338 	    trim_string (color, 40);
3339 	    if (!strlen (color))
3340 		strcpy (color, "Gray20");
3341 		if (strncmp (type, "mesh", 4) == 0)
3342 		    drvui->surftype[i] = 0;
3343 		else if (strncmp (type, "solid", 5) == 0)
3344 		    drvui->surftype[i] = 1;
3345 		else
3346 		    drvui->surftype[i] = 2;
3347 
3348 	    strcpy (drvui->surffile[i], filename);
3349 	    strcpy (drvui->surfcolor[i], color);
3350             strcpy (drvui->surfatom[i], atom);
3351             drvui->surfnum[i] = num;
3352 
3353 	    drvui->nsurf++;
3354 	    for (j = 0; j < strlen (widget); j++) {
3355 		if (widget[j] == '\n')
3356 		    break;
3357 	    }
3358 	    for (j++, k = 0; j < strlen (widget); j++)
3359 		widget[k++] = widget[j];
3360 	    widget[k] = 0;
3361 	}
3362     }
3363 
3364     if (!strncmp( Surf->SurfType->value(), "No",2) ) {
3365 	drvui->voidflag = 0;
3366     } else if (!strncmp ( Surf->SurfType->value(), "Grid", 4) ) {
3367 	drvui->voidflag = 1;
3368     } else if (!strncmp ( Surf->SurfType->value(), "MSMS", 4) ) {
3369 	drvui->voidflag = 2;
3370         if (!strstr(Surf->SurfType->value(), "now") )
3371 	    drvui->voidflag = -2;
3372     } else {
3373 	drvui->voidflag = 3;
3374     }
3375 
3376     if ( drvui->voidflag != 0 ) {
3377         drvui->probesize = (float)atof(Surf->Probe->value());
3378         drvui->voidgrid[0] = atoi(Surf->GridX->value());
3379         drvui->voidgrid[1] = atoi(Surf->GridY->value());
3380         drvui->voidgrid[2] = atoi(Surf->GridZ->value());
3381         strcpy(drvui->voidcolor,Surf->SurfColor->value());
3382 
3383 	selection = Surf->SurfBuffer->text ();
3384 
3385 	strcpy (widget, selection);
3386 	free (selection);
3387 
3388 	if (strlen (widget) < 10) {
3389 //	    drvui->voidflag = 0;
3390 	    strcpy (widget, "");
3391 	    Surf->SurfBuffer->text (widget);
3392 	} else {
3393 	    drvui->natprop=1;
3394 	    while (strlen (widget) > 10) {
3395 		i++;
3396 		sscanf (widget, "%s %s %f", atom, number, &radius);
3397 		if (number[0]== '*') {
3398 		    num = -1;
3399 		} else {
3400 		    (void) sscanf (number, "%d", &num);
3401 		}
3402 		drvui->atprops[drvui->natprop].atprop_n=num;
3403 		strcpy(drvui->atprops[drvui->natprop].atprop_l,atom);
3404 		drvui->atprops[drvui->natprop].radius=radius;
3405 		drvui->natprop++;
3406 		for (kk = 0; kk < natom; kk++) {       /* find this atom in list */
3407 		    if (check_atom_name (t_name, drvui->atoms[kk].atom_l)) {
3408 			if ((num == -1) || (num == drvui->atoms[kk].atom_n)) {
3409 			    drvui->atoms[kk].radius = radius;
3410 			}
3411 		    }
3412 		}
3413 		for (j = 0; j < strlen (widget); j++) {
3414 		    if (widget[j] == '\n')
3415 			break;
3416 		}
3417 		for (j++, k = 0; j < strlen (widget); j++)
3418 		    widget[k++] = widget[j];
3419 		widget[k] = 0;
3420 	    }
3421 	}
3422     }
3423     drvui->Str_File_Changed = 1;
3424     if (*save != 3) {
3425 	Save_Working_Copy ();
3426 	Surf->AimSurfInstr2->hide ();
3427     }
3428     if (*save == 1) {
3429 	Fl::delete_widget (Surf->Surfaces_Edit_Window);
3430 	delete (Surf);
3431 	Surf = NULL;
3432     }
3433     Update_Str (0);
3434     Generate_Drawing (0);
3435     Fl::redraw ();
3436 }
3437 
3438 void
3439 Modify_AimSurfaces_cb (Fl_Widget *, void *)
3440 {
3441     char type[8], color[40], value[10],tstring[10];
3442     char atom[5],filename[128];
3443     int num;
3444 
3445     int start, end;
3446 
3447     const char *selection;
3448 
3449     if (!Surf->AimSurfBuffer->selected ()) {
3450 	return;
3451     }
3452     memset (type, 0, 8);
3453     memset (color, 0, 40);
3454     Surf->AimSurfBuffer->selection_position (&start, &end);
3455     selection = Surf->AimSurfBuffer->line_text (start);
3456     Surf->AimSurfInstr1->hide ();
3457     Surf->AimSurfInstr->show ();
3458 	sscanf (selection, " %s %2d %s %s %s", atom, &num, filename, type, color);
3459     free ((char *) selection);
3460     if (strlen (color) && isalpha (color[0])) {
3461 	strcpy(tstring,atom);
3462 	if (strlen(tstring)<4) strcat(tstring," ");
3463 	if (strlen(tstring)<4) strcat(tstring," ");
3464 	if (strlen(tstring)<4) strcat(tstring," ");
3465 	sprintf(value,"%2d",num);
3466 	strcat(tstring,value);
3467 	Surf->AimSurf_Combo->value (tstring);
3468 	Surf->AimFile->value (filename);
3469 	Surf->AimSurfType->value (type);
3470 	Surf->AimSurfColor->value (color);
3471 	Surf->Add_Button->activate ();
3472 	Surf->Remove_Button->activate ();
3473     } else {
3474 	Surf->AimSurf_Combo->value ("");
3475 	Surf->AimFile->value ("");
3476 	Surf->AimSurfColor->value ("");
3477 	Surf->AimSurfType->value ("");
3478 	Surf->Add_Button->activate ();
3479 	Surf->Remove_Button->deactivate ();
3480     }
3481 }
3482 
3483 void
3484 Modify_Surfaces_cb (Fl_Widget *, void *)
3485 {
3486     char type[8], value[10],tstring[10];
3487     char atom[5];
3488     double rad;
3489 
3490     int start, end;
3491 
3492     const char *selection;
3493 
3494     if (!Surf->SurfBuffer->selected ()) {
3495 	return;
3496     }
3497     memset (atom, 0, 5);
3498     memset (type, 0, 8);
3499     Surf->SurfBuffer->selection_position (&start, &end);
3500     selection = Surf->SurfBuffer->line_text (start);
3501     Surf->SurfInstr1->hide ();
3502     Surf->SurfInstr->show ();
3503 	sscanf (selection, "%s %s %lf", atom, type, &rad);
3504     free ((char *) selection);
3505 
3506 	strcpy(tstring,atom);
3507     if (strlen(tstring) && rad >0.) {
3508 	if (strlen(tstring)<4) strcat(tstring," ");
3509 	if (strlen(tstring)<4) strcat(tstring," ");
3510 	if (strlen(tstring)<4) strcat(tstring," ");
3511 	strcat(tstring,type);
3512 	Surf->Surf_Combo->value (tstring);
3513 	sprintf(value,"%.2f",rad);
3514 	Surf->Radius->value(value);
3515 	Surf->Add_Button2->activate ();
3516 	Surf->Remove_Button2->activate ();
3517     } else {
3518 	Surf->Surf_Combo->value ("");
3519 	Surf->Radius->value ("");
3520 	Surf->Add_Button2->activate ();
3521 	Surf->Remove_Button2->deactivate ();
3522     }
3523 }
3524 
3525 void
3526 New_AimSurf_Input_cb (Fl_Widget *, void *)
3527 {
3528 // callback routine to make 'Add' new map level button active whenever all fields are non-blank
3529     if (!strlen (Surf->AimSurfColor->value ()))
3530 	return;
3531     if (!strlen (Surf->AimSurfType->value ()))
3532 	return;
3533     Surf->Add_Button->activate ();
3534 }
3535 
3536 void
3537 New_Surf_Input_cb (Fl_Widget *, void *)
3538 {
3539 // callback routine to make 'Add' new map level button active whenever all fields are non-blank
3540     if (!strlen (Surf->Surf_Combo->value ()))
3541 	return;
3542     if (!strlen (Surf->Radius->value ()))
3543 	return;
3544     Surf->Add_Button2->activate ();
3545 }
3546 
3547 void
3548 New_AimSurf_Add_cb (class Fl_Widget *, int *action)
3549 {
3550     char string[100];
3551 
3552     int start, end;
3553 
3554     char *selection = NULL;
3555 
3556     Surf->AimSurfInstr2->show ();
3557     if (Surf->AimSurfBuffer->selected ()) {
3558 	Surf->AimSurfBuffer->selection_position (&start, &end);
3559 	selection = Surf->AimSurfBuffer->line_text (start);
3560 	Surf->AimSurfBuffer->remove (Surf->AimSurfBuffer->line_start (start),
3561 				  Surf->AimSurfBuffer->line_end (end) + 1);
3562     }
3563     if (*action) {
3564 	    sprintf (string, "%s    %s      %s      %s\n", Surf->AimSurf_Combo->value(),Surf->AimFile->value(),
3565 		     Surf->AimSurfType->value (), Surf->AimSurfColor->value ());
3566 	Surf->AimSurfBuffer->append (string);
3567     }
3568     if (selection)
3569 	free ((char *) selection);
3570     Surf->Add_Button->deactivate ();
3571     Surf->Remove_Button->deactivate ();
3572     Surf->AimSurfInstr1->show ();
3573     Surf->AimSurfInstr->hide ();
3574     Edit_Surfaces_Save_cb (NULL, &three);
3575 }
3576 
3577 void
3578 New_Radius_Add_cb (class Fl_Widget *, int *action)
3579 {
3580     char string[100];
3581 
3582     int start, end;
3583 
3584     char *selection = NULL;
3585 
3586     Surf->AimSurfInstr2->show ();
3587     if (Surf->SurfBuffer->selected ()) {
3588 	Surf->SurfBuffer->selection_position (&start, &end);
3589 	selection = Surf->SurfBuffer->line_text (start);
3590 	Surf->SurfBuffer->remove (Surf->SurfBuffer->line_start (start),
3591 				  Surf->SurfBuffer->line_end (end) + 1);
3592     }
3593     if (*action) {
3594 	    sprintf (string, "%s    %s\n", Surf->Surf_Combo->value(),Surf->Radius->value());
3595 	Surf->SurfBuffer->append (string);
3596     }
3597     if (selection)
3598 	free ((char *) selection);
3599     Surf->Add_Button2->deactivate ();
3600     Surf->Remove_Button2->deactivate ();
3601     Surf->SurfInstr1->show ();
3602     Surf->SurfInstr->hide ();
3603     Edit_Surfaces_Save_cb (NULL, &three);
3604 }
3605 
3606 //void AimSurf_Combo_cb(Fl_Widget*, void*)
3607 //{}
3608 //void Surf_Combo_cb(Fl_Widget*, void*)
3609 //{}
3610 
3611 void
3612 Surface_Frame_Combo_cb (Fl_Widget *, void *)
3613 {
3614     int i, j, n;
3615 
3616     char atom[5];
3617 
3618     char tstring[5];
3619 
3620     char string[100];
3621 
3622     int Frame_No = 1;
3623 
3624     if (drvui->max_frame > 1)
3625 	Frame_No = atoi (Surf->Frame_No->value ());
3626 
3627     Surf->AimSurf_Combo->list.clear ();	// clear out the old names
3628     Surf->AimSurf_Combo->list.add ("");	// add a dummy at start
3629 
3630     Surf->Surf_Combo->list.clear ();	// clear out the old names
3631     Surf->Surf_Combo->list.add ("");	// add a dummy at start
3632 
3633     for (j = 0; j < natom; j++) {
3634 	memset (atom, 0, 5);
3635 	if (drvui->atoms[j].atom_fn != Frame_No)
3636 	    continue;
3637 	strcpy (string, drvui->atoms[j].atom_l);
3638 	n = drvui->atoms[j].sv_atom_n;;
3639 	    sprintf (tstring, "%2d", n);
3640 	    strcat (string, tstring);
3641 	    Surf->AimSurf_Combo->list.add (string);
3642 	    Surf->Surf_Combo->list.add (string);
3643     }
3644     for (j = 0; j < natom; j++) {
3645 	memset (atom, 0, 5);
3646 	if (drvui->atoms[j].atom_fn != Frame_No)
3647 	    continue;
3648         i=0;
3649 	strcpy (string, drvui->atoms[j].atom_l);
3650         for (n=0;n<j;n++) {
3651 		if (!strcmp(string,drvui->atoms[n].atom_l)) {
3652 		i=1;
3653             	continue;
3654 		}
3655 	}
3656 	if (i==1) continue;
3657 	    sprintf (tstring, "*");
3658 	    if (strlen(string)<4) strcat(string," ");
3659 	    if (strlen(string)<4) strcat(string," ");
3660 	    if (strlen(string)<4) strcat(string," ");
3661 	    strcat (string, tstring);
3662 	    Surf->Surf_Combo->list.add (string);
3663     }
3664     Surf->AimSurf_Combo->value ("");	// load blank in window
3665     Surf->Surf_Combo->value ("");	// load blank in window
3666 }
3667 
3668