1 /*  pdnmesh - a 2D finite element solver
2     Copyright (C) 2001-2005 Sarod Yatawatta <sarod@users.sf.net>
3   This program is free software; you can redistribute it and/or modify
4   it under the terms of the GNU General Public License as published by
5   the Free Software Foundation; either version 2 of the License, or
6   (at your option) any later version.
7 
8   This program is distributed in the hope that it will be useful,
9   but WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   GNU General Public License for more details.
12 
13   You should have received a copy of the GNU General Public License
14   along with this program; if not, write to the Free Software
15   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16   $Id: graphics.c,v 1.76 2005/04/26 05:16:47 sarod Exp $
17 */
18 
19 
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <math.h>
28 #ifndef WIN32
29 #include <gtk/gtk.h>
30 #include <gdk/gdkkeysyms.h>
31 #include <gtk/gtkgl.h>
32 #endif/*WIN32*/
33 #ifdef WIN32
34 #include <windows.h>
35 #endif/*!WIN32*/
36 #include <GL/gl.h>
37 #include <GL/glu.h>
38 
39 #include "types.h"
40 
41 static float gl_bg_color[3]={0.0,0.0,0.0}; /* 3 x 1 array for background color */
42 
43 /* function to interpolate potential within
44    a triangle */
45 static MY_DOUBLE
interpolate_potential(MY_DOUBLE x0,MY_DOUBLE y0,MY_DOUBLE z0,MY_DOUBLE x1,MY_DOUBLE y1,MY_DOUBLE z1,MY_DOUBLE x2,MY_DOUBLE y2,MY_DOUBLE z2,MY_DOUBLE x,MY_DOUBLE y)46 interpolate_potential(MY_DOUBLE x0, MY_DOUBLE y0, MY_DOUBLE z0,
47       MY_DOUBLE x1, MY_DOUBLE y1, MY_DOUBLE z1,
48       MY_DOUBLE x2, MY_DOUBLE y2, MY_DOUBLE z2, MY_DOUBLE x, MY_DOUBLE y) {
49       MY_DOUBLE del,a,b,c,yy12,yy23,yy31,xx12,xx23,xx31;
50       yy23 = y1-y2;
51       yy31 = y2-y0;
52       yy12 = y0-y1;
53       xx23 = x1-x2;
54       xx31 = x2-x0;
55       xx12 = x0-x1;
56 
57       del = x0*yy23 + x1*yy31 + x2*yy12;
58       if (!(IS_ZERO(del))) {
59       del = 1.0/del;
60       a = del*(z0*yy23 + z1*yy31 + z2*yy12);
61       b = -del*(z0*xx23+z1*xx31+z2*xx12);
62       c = z0 - a*x0 - b*x0;
63       return(a*x+b*y+c);
64       }
65      return(0);
66 }
67 
68 extern boundary bound;
69 /* triangle used in info mode */
70 triangle *chosen_triangle;
71 /* option flags for plotting */
72 int plot_mesh, plot_cont, plot_fill, plot_grad, plot_legend;
73 int drawing_mode_flag;
74 /* flag to detect existing mesh: 1 is mesh exists, 0 otherwise */
75 int mesh_already_present;
76 
77 #ifndef WIN32
78 GtkWidget *global_status_bar=0,*global_status_label=0,*global_mode_label=0;
79 /* stuct to pass two widgets to a callback as data */
80 typedef struct dual_widget_ {
81   GtkWidget *w1;
82   GtkWidget *w2;
83 } dual_widget;
84 #endif/*WIN32*/
85 
86 /* global to update status bar */
87 void
update_status_bar(char * msg)88 update_status_bar(char *msg) {
89 #ifndef WIN32
90  gchar buf[256];
91  if ( global_status_bar ) {
92  g_snprintf(buf, 256, "%s", msg);
93  gtk_label_set_markup(GTK_LABEL(global_status_bar),buf);
94  }
95 #endif/*WIN32*/
96 #ifdef WIN32
97  /* windows  code goes here */
98 #endif /*!WIN32*/
99 }
100 
101 #ifndef WIN32
102 /* global to update mode label */
103 void
update_mode_label(char * msg)104 update_mode_label(char *msg) {
105   gchar buf[512];
106   int eigen_number;
107   char xyz_component='x';
108   /* for helmholtz cases we can have 3 times deg of freedom contours */
109    eigen_number=current_plotting_contour/3; /* floor by 3 */
110    switch(current_plotting_contour%3) {
111       /* mod by 3: x==0, y==1, z==2 */
112      case 0:
113       xyz_component='x';
114       break;
115      case 1:
116       xyz_component='y';
117       break;
118      case 2:
119       xyz_component='z';
120       break;
121      default:
122       break;
123    }
124 
125  /* if we are plotting an eigenvector, we display
126    eigenvalue */
127  if ( solve_equation == POISSON || solve_equation== POISSON_SPARSE ) {
128  g_snprintf(buf, 512, "|<span foreground=\"red\"><small>Poisson    </small></span>");
129  gtk_label_set_markup(GTK_LABEL(global_mode_label),buf);
130  } else  { /* we have an eigenvalue */
131   if (solve_equation == HELMHOLTZ ) {
132    g_snprintf(buf, 512, "|<span foreground=\"red\"><small>Helmholtz(homo)</small></span>%d:<span foreground=\"blue\">%5.3lf</span>",current_plotting_contour,eig_array[current_plotting_contour]);
133   } else if (solve_equation == HELMHOLTZ_INHOMO ) {
134 
135    g_snprintf(buf, 512, "|<span foreground=\"red\"><small>Helmholtz(inhomo)</small></span>%d:%c <span foreground=\"blue\">%5.3lf</span>",eigen_number,xyz_component,eig_array[eigen_number]);
136   } else if (solve_equation == HELMHOLTZ_FREQ) {
137 
138    g_snprintf(buf, 512, "|<span foreground=\"red\"><small>Helmholtz(freq) </small></span>%d:%c <span foreground=\"blue\">%5.3lf</span>",eigen_number,xyz_component,eig_array[eigen_number]);
139   } else if (solve_equation == HELMHOLTZ_BETA) {
140 
141    g_snprintf(buf, 512, "|<span foreground=\"red\"><small>Helmholtz(beta) </small></span>%d:%c <span foreground=\"blue\">%5.3lf</span>",eigen_number,xyz_component,eig_array[eigen_number]);
142   }
143 
144   gtk_label_set_markup(GTK_LABEL(global_mode_label),buf);
145  }
146 
147 }
148 #endif/*WIN32*/
149 
150 /* draw a polygon */
151 static void
draw_polygon(polygon * poly)152 draw_polygon(polygon *poly)
153 {
154 
155 	  glLineWidth(2.0);
156 		 if (poly && poly->head ) {
157 		 int i=poly->nedges;
158 		 poly_elist *tempe=poly->head;
159       for (;i;i--) {
160   if (!plot_fill) {
161   if ( tempe->data.type==DR) {
162 			glColor3f(0.9f, 1.0f, 0.4f);
163 		} else {
164 			glColor3f(0.1f, 1.0f, 0.9f);
165 		}
166   } else {
167 			glColor3f(0.0f, 0.0f, 0.0f);
168   }
169       glBegin(GL_LINE_LOOP);
170 			 glVertex2f( (GLfloat)Mx(tempe->data.p1,M), (GLfloat)My(tempe->data.p1,M));
171 			 glVertex2f( (GLfloat)Mx(tempe->data.p2,M), (GLfloat)My(tempe->data.p2,M));
172 			glEnd();
173        tempe=tempe->next;
174 			}
175 		 }
176 
177 	  glLineWidth(1.0);
178 }
179 
180 /* rendering routine */
181 void
global_render(void)182 global_render(void)
183 {
184  int i;
185  triangle *rec;
186  /* for boundary colors */
187  float bc,r,g,b;
188 
189 /**********************/
190  /* drawing routine */
191 	glClear(GL_COLOR_BUFFER_BIT);
192 
193  /* change background colour */
194   glClearColor(gl_bg_color[0],gl_bg_color[1],gl_bg_color[2],0);
195 
196 
197 	glLineWidth(1.0);
198 
199  if(drawing_mode_flag==DRAW_OUTPUT) {
200 	/* plot mesh */
201 	if ( plot_mesh  ) {
202 	glColor3f(0.3f, 0.3f, 0.1f);
203   DAG_traverse_list_reset(&dt);
204   rec=DAG_traverse_prune_list(&dt);
205 	while (rec) {
206      if (rec &&rec->status==LIVE) {
207 		/*		bc=rec->boundary/(double)bound.npoly*0.5+0.2f;
208 	     glColor3f((GLfloat)bc,(GLfloat)bc,(GLfloat)bc);  */
209           glBegin(GL_LINE_LOOP);
210 					glVertex2f( (GLfloat)Mx(rec->p0,M), (GLfloat) My(rec->p0,M));
211 					glVertex2f( (GLfloat)Mx(rec->p1,M), (GLfloat) My(rec->p1,M));
212 					glVertex2f( (GLfloat)Mx(rec->p2,M), (GLfloat) My(rec->p2,M));
213           glEnd();
214 			}
215 		/*rt.print_record(rec); */
216    rec=DAG_traverse_prune_list(&dt);
217 	}
218 	}
219   if (plot_fill) { /* diffused mode */
220   glShadeModel(GL_SMOOTH);
221   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
222   glEnable(GL_POLYGON_SMOOTH);
223   glEnable(GL_BLEND);
224   glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);
225   glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
226   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
227   glEnable(GL_DITHER);
228   DAG_traverse_list_reset(&dt);
229   rec=DAG_traverse_prune_list(&dt);
230 	while (rec) {
231      if (rec &&rec->status==LIVE) {
232           glBegin(GL_TRIANGLES);
233           get_colour(&r,&g,&b,(int)((Mzz(rec->p0,current_plotting_contour,M)-g_minpot)/(g_maxpot-g_minpot)*(float)contour_levels),contour_levels);
234  	        glColor3f(r, g, b);
235 					glVertex2f( (GLfloat)Mx(rec->p0,M), (GLfloat) My(rec->p0,M));
236           get_colour(&r,&g,&b,(int)((Mzz(rec->p1,current_plotting_contour,M)-g_minpot)/(g_maxpot-g_minpot)*(float)contour_levels),contour_levels);
237  	        glColor3f(r, g, b);
238 					glVertex2f( (GLfloat)Mx(rec->p1,M), (GLfloat) My(rec->p1,M));
239           get_colour(&r,&g,&b,(int)((Mzz(rec->p2,current_plotting_contour,M)-g_minpot)/(g_maxpot-g_minpot)*(float)contour_levels),contour_levels);
240  	        glColor3f(r, g, b);
241 					glVertex2f( (GLfloat)Mx(rec->p2,M), (GLfloat) My(rec->p2,M));
242           glEnd();
243 			}
244    rec=DAG_traverse_prune_list(&dt);
245 	}
246   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
247   glDisable(GL_BLEND);
248   glDisable(GL_DITHER);
249   }
250 	for (i=0;i<bound.npoly;i++){
251 		draw_polygon(&bound.poly_array[i]);
252 	}
253  /* info  mode */
254  /* plot selected triangle */
255  if ( chosen_triangle && chosen_triangle->status==LIVE ) {
256 
257 #ifdef DEBUG
258  fprintf(stderr,"point inside %d->(%d,%d,%d)\n",chosen_triangle->n,chosen_triangle->p0,chosen_triangle->p1,chosen_triangle->p2);
259 #endif
260 	/* draw */
261   /* plot this triangle */
262   glColor3f(1.0f, 0.3f, 1.0f);
263 	glLineWidth(1.0);
264 
265   glBegin(GL_LINE_LOOP);
266 					glVertex2f( (GLfloat)Mx(chosen_triangle->p0,M), (GLfloat)My(chosen_triangle->p0,M));
267 					glVertex2f( (GLfloat)Mx(chosen_triangle->p1,M), (GLfloat)My(chosen_triangle->p1,M));
268 					glVertex2f( (GLfloat)Mx(chosen_triangle->p2,M), (GLfloat)My(chosen_triangle->p2,M));
269 	glEnd();
270  }
271  /* draw zoom window */
272  if (	mouse_responce_flag == MENU_ZOOM_END ) { /* first point has been selected */
273 		   glBegin(GL_LINE_STRIP);
274 			 glColor3f(0.0f, 1.0f, 1.0f);
275 			 glVertex2f( (GLfloat)zoom_x1, (GLfloat)zoom_y1 );
276 			 glVertex2f( (GLfloat)zoom_x1, (GLfloat)zoom_y2 );
277 			 glVertex2f( (GLfloat)zoom_x2, (GLfloat)zoom_y2 );
278 			 glVertex2f( (GLfloat)zoom_x2, (GLfloat)zoom_y1 );
279 			 glVertex2f( (GLfloat)zoom_x1, (GLfloat)zoom_y1 );
280 			 glEnd();
281   }
282 
283  if ( plot_cont )  {
284 				plot_contour_all(M);
285 	}
286  if ( plot_grad ) {
287   plot_gradient(M);
288  }
289  } /* output mode */
290 /***********************************************/
291  if ( drawing_mode_flag== DRAW_INPUT ) {
292  	/* plot mesh with materials */
293  	glColor3f(0.3f, 0.3f, 0.1f);
294   DAG_traverse_list_reset(&dt);
295   rec=DAG_traverse_prune_list(&dt);
296 	 while (rec) {
297      if (rec &&rec->status==LIVE) {
298 				bc=(float)(rec->boundary/(double)bound.npoly*0.5)+0.2f;
299 	     glColor3f((GLfloat)bc,(GLfloat)bc,(GLfloat)bc);
300           glBegin(GL_TRIANGLES);
301 					glVertex2f( (GLfloat)Mx(rec->p0,M), (GLfloat) My(rec->p0,M));
302 					glVertex2f( (GLfloat)Mx(rec->p1,M), (GLfloat) My(rec->p1,M));
303 					glVertex2f( (GLfloat)Mx(rec->p2,M), (GLfloat) My(rec->p2,M));
304           glEnd();
305 			}
306 		/*rt.print_record(rec); */
307    rec=DAG_traverse_prune_list(&dt);
308 	 }
309 	 for (i=0;i<bound.npoly;i++){
310 	 	draw_polygon(&bound.poly_array[i]);
311 	 }
312  /* draw zoom window */
313   if (	mouse_responce_flag == MENU_ZOOM_END ) { /* first point has been selected */
314 		   glBegin(GL_LINE_STRIP);
315 			 glColor3f(0.0f, 1.0f, 1.0f);
316 			 glVertex2f( (GLfloat)zoom_x1, (GLfloat)zoom_y1 );
317 			 glVertex2f( (GLfloat)zoom_x1, (GLfloat)zoom_y2 );
318 			 glVertex2f( (GLfloat)zoom_x2, (GLfloat)zoom_y2 );
319 			 glVertex2f( (GLfloat)zoom_x2, (GLfloat)zoom_y1 );
320 			 glVertex2f( (GLfloat)zoom_x1, (GLfloat)zoom_y1 );
321 			 glEnd();
322   }
323  }
324 /***********************************************/
325 }
326 /* the  rest of the file is GTK+gtkglext stuff */
327 #ifndef WIN32
328 /* realize signal handler,
329   opengl intialization done here */
330 static void
realize(GtkWidget * widget,gpointer data)331 realize (GtkWidget *widget,
332    gpointer data)
333 {
334   GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
335 	GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
336 
337 #ifdef DEBUG
338 	g_print("%s: \"realize\"\n",gtk_widget_get_name(widget));
339 #endif
340 
341 	if(!gdk_gl_drawable_gl_begin(gldrawable,glcontext))
342 	    return;
343 
344 		gdk_gl_drawable_gl_end(gldrawable);
345 }
346 
347 /* reconfigure event handler */
348 static gboolean
configure_event(GtkWidget * widget,GdkEventConfigure * event,gpointer data)349 configure_event(GtkWidget *widget,
350      GdkEventConfigure *event,
351 		 gpointer  data)
352 {
353 
354  GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
355  GdkGLDrawable *gldrawable=gtk_widget_get_gl_drawable(widget);
356 
357  GLfloat w=widget->allocation.width;
358  GLfloat h=widget->allocation.height;
359 
360 #ifdef DEBUG
361  g_print("%s: \"configure_event\"\n",gtk_widget_get_name(widget));
362 #endif
363 
364  if(!gdk_gl_drawable_gl_begin(gldrawable,glcontext))
365      return(FALSE);
366 
367   glViewport(0,0,w,h);
368 	/* FIXME */
369 	glMatrixMode(GL_PROJECTION);
370 	  glLoadIdentity();
371 		gluOrtho2D(-1,1,-1,1);
372 		glMatrixMode(GL_MODELVIEW);
373 	gdk_gl_drawable_gl_end(gldrawable);
374 
375 	return(TRUE);
376 
377 }
378 
379 /* drawing routine, expose event */
380 static gboolean
expose_event(GtkWidget * widget,GdkEventExpose * event,gpointer data)381 expose_event(GtkWidget *widget,
382   GdkEventExpose *event,
383 	gpointer data)
384 {
385   GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
386   GdkGLDrawable *gldrawable=gtk_widget_get_gl_drawable(widget);
387 
388 #ifdef DEBUG
389  g_print("%s: \"expose_event\"\n", gtk_widget_get_name(widget));
390 #endif
391 
392  if (!gdk_gl_drawable_gl_begin(gldrawable,glcontext))
393      return(FALSE);
394 
395 /**********************************/
396    global_render();
397 /**********************************/
398   /* this should not be in expose event routine */
399   update_mode_label(0);
400  /* swap buffers */
401  if (gdk_gl_drawable_is_double_buffered(gldrawable))
402     gdk_gl_drawable_swap_buffers(gldrawable);
403 	else
404 	 glFlush();
405 
406  gdk_gl_drawable_gl_end(gldrawable);
407 
408  return(TRUE);
409 }
410 
411 
412 static int temp_scratch_arpack_max_iter;
413 static int temp_scratch_arpack_subspace;
414 static void
configure_arpack_save_iter(GtkEntry * textbox)415 configure_arpack_save_iter(GtkEntry *textbox)
416 {
417   temp_scratch_arpack_max_iter=(int)g_strtod(gtk_entry_get_text(textbox),0);
418 }
419 static void
configure_arpack_save_subspace_dimension(GtkEntry * textbox)420 configure_arpack_save_subspace_dimension(GtkEntry *textbox)
421 {
422   temp_scratch_arpack_subspace=(int)g_strtod(gtk_entry_get_text(textbox),0);
423 }
424 
425 static void
configure_arpack_update_values(GtkWidget * widget,gpointer data)426 configure_arpack_update_values(GtkWidget *widget,gpointer data)
427 {
428   if(temp_scratch_arpack_max_iter>0)
429    arpack_max_iterations=temp_scratch_arpack_max_iter;
430   if(temp_scratch_arpack_subspace>0)
431    arpack_subspace_dimension=temp_scratch_arpack_subspace;
432 
433   /* close window */
434   gtk_widget_destroy(GTK_WIDGET(data));
435 }
436 static void
configure_arpack_close_window(GtkWidget * widget,gpointer data)437 configure_arpack_close_window(GtkWidget *widget, gpointer data)
438 {
439   /* close window */
440   gtk_widget_destroy(GTK_WIDGET(data));
441 }
442 
443 static void
configure_arpack_solver(void)444 configure_arpack_solver(void)
445 {
446   char buf[20];
447   GtkWidget *window,*box1,*box2,*label,*textbox,*separator,*button;
448  /* initialize values */
449  temp_scratch_arpack_max_iter=arpack_max_iterations;
450  temp_scratch_arpack_subspace=arpack_subspace_dimension;
451 
452   window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
453   g_signal_connect_swapped(GTK_OBJECT(window),"delete_event",
454     G_CALLBACK(gtk_widget_destroy),(gpointer)window);
455   gtk_window_set_title(GTK_WINDOW(window),"ARPACK options");
456   box1=gtk_vbox_new(FALSE,0);
457   gtk_container_add(GTK_CONTAINER(window),box1);
458   gtk_widget_show(box1);
459 
460  /* text entry for max. iterations */
461   box2=gtk_hbox_new(FALSE,10);
462   gtk_container_set_border_width(GTK_CONTAINER(box2),10);
463   label=gtk_label_new("Iteration Limit:");
464   gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
465   gtk_widget_show(label);
466   textbox=gtk_entry_new();
467   g_snprintf(buf,20,"%d",arpack_max_iterations);
468   gtk_entry_set_text(GTK_ENTRY(textbox),buf);
469   gtk_box_pack_start(GTK_BOX(box2),textbox,FALSE,FALSE,0);
470   gtk_widget_show(textbox);
471   g_signal_connect(G_OBJECT(textbox),"changed",
472       G_CALLBACK(configure_arpack_save_iter),NULL);
473   gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
474   gtk_widget_show(box2);
475 
476  /* text entry for Subspace dimension*/
477   box2=gtk_hbox_new(FALSE,10);
478   gtk_container_set_border_width(GTK_CONTAINER(box2),10);
479   label=gtk_label_new("Subspace Dimension:");
480   gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
481   gtk_widget_show(label);
482   textbox=gtk_entry_new();
483   g_snprintf(buf,20,"%d",arpack_subspace_dimension);
484   gtk_entry_set_text(GTK_ENTRY(textbox),buf);
485   gtk_box_pack_start(GTK_BOX(box2),textbox,FALSE,FALSE,0);
486   gtk_widget_show(textbox);
487   g_signal_connect(G_OBJECT(textbox),"changed",
488       G_CALLBACK(configure_arpack_save_subspace_dimension),NULL);
489   gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
490   gtk_widget_show(box2);
491 
492 
493   /* seperator and buttons */
494   separator=gtk_hseparator_new();
495   gtk_box_pack_start(GTK_BOX(box1),separator,FALSE,TRUE,0);
496   gtk_widget_show(separator);
497 
498   box2=gtk_hbox_new(FALSE,10);
499   gtk_container_set_border_width(GTK_CONTAINER(box2),10);
500   gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,TRUE,0);
501   gtk_widget_show(box2);
502 
503   button=gtk_button_new_with_label("OK");
504   g_signal_connect(G_OBJECT(button),"clicked",
505     G_CALLBACK(configure_arpack_update_values),
506     window);
507 
508    gtk_box_pack_start(GTK_BOX(box2),button,TRUE,TRUE,0);
509    GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT);
510    gtk_widget_grab_default(button);
511    gtk_widget_show(button);
512 
513    button=gtk_button_new_with_label("Cancel");
514    g_signal_connect (G_OBJECT (button), "clicked",
515      G_CALLBACK(configure_arpack_close_window),
516      window);
517 
518    gtk_box_pack_start(GTK_BOX(box2),button,TRUE,TRUE,0);
519    gtk_widget_show(button);
520    gtk_widget_show(window);
521 }
522 
523 
524 
525 
526 /* global for changing triangle boundary */
527 static int temp_scratch_boundary;
528 
529 static void
change_triangle_boundary(GtkWidget * widget,gpointer data)530 change_triangle_boundary(GtkWidget *widget, gpointer data)
531 {
532   temp_scratch_boundary=GPOINTER_TO_INT(data);
533 }
534 
535 static void
update_triangle_info(GtkWidget * widget,gpointer data)536 update_triangle_info(GtkWidget *widget, gpointer data)
537 {
538 	if ( chosen_triangle )
539     chosen_triangle->boundary=temp_scratch_boundary;
540 
541 	chosen_triangle=0;
542 	gtk_widget_destroy(GTK_WIDGET(data));
543 }
544 
545 static void
cancel_triangle_info(GtkWidget * widget,gpointer * data)546 cancel_triangle_info(GtkWidget *widget, gpointer *data)
547 {
548 		chosen_triangle=0;
549 	  gtk_widget_destroy(GTK_WIDGET(data));
550 }
551 
552 /* utility functions */
553 static GtkWidget *
make_menu_item(gchar * name,GCallback callback,gpointer data)554 make_menu_item(gchar *name, GCallback callback,
555 								                          gpointer data)
556 {
557 	GtkWidget *item;
558 	item=gtk_menu_item_new_with_label(name);
559 	g_signal_connect(G_OBJECT(item),"activate",
560 	callback,(gpointer)data);
561 	gtk_widget_show(item);
562 	return(item);
563 }
564 
565 /* popup window for information of a triangle */
566 static void
dialog_display_triangle_info(void)567 dialog_display_triangle_info(void)
568 {
569 	GtkWidget *window,*label, *box1, *box2, *opt, *item, *menu;
570 	GtkWidget *button;
571 	static gchar buf[128];
572   int i;
573 
574 	window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
575   g_signal_connect_swapped(GTK_OBJECT(window),"delete_event",
576 	G_CALLBACK(gtk_widget_destroy),(gpointer)window);
577 
578 
579 	gtk_window_set_title(GTK_WINDOW(window),"Triangle properties");
580 
581 	box1=gtk_vbox_new(FALSE,0);
582 	gtk_container_add(GTK_CONTAINER(window),box1);
583 	gtk_widget_show(box1);
584 
585 	box2=gtk_hbox_new(FALSE,10);
586 	gtk_container_set_border_width(GTK_CONTAINER(box2),10);
587 	gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
588 	gtk_widget_show(box2);
589 	label=gtk_label_new(NULL);
590 	g_snprintf(buf,128,"Triangle <span foreground=\"blue\">%d</span>, <span foreground=\"red\">(%d,%d,%d)</span>",chosen_triangle->n,chosen_triangle->p0,chosen_triangle->p1,chosen_triangle->p2);
591   gtk_label_set_markup(GTK_LABEL(label),buf);
592 	gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
593 	gtk_widget_show(label);
594 
595 
596 	box2=gtk_hbox_new(FALSE,10);
597 	gtk_container_set_border_width(GTK_CONTAINER(box2),10);
598 	gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
599 	gtk_widget_show(box2);
600 	label=gtk_label_new("Boundary=");
601 	gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
602 	gtk_widget_show(label);
603 
604 
605 	/* boundary */
606   opt=gtk_option_menu_new();
607 	menu=gtk_menu_new();
608 	for (i=0;i<bound.npoly;i++) {
609 	 sprintf(buf,"%d",i);
610 	 item=make_menu_item(buf,
611 							G_CALLBACK(change_triangle_boundary),
612 							GINT_TO_POINTER(i));
613 	 gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
614 	}
615 	gtk_option_menu_set_menu(GTK_OPTION_MENU(opt),menu);
616 	gtk_option_menu_set_history(GTK_OPTION_MENU(opt), chosen_triangle->boundary);
617 
618 	gtk_box_pack_start(GTK_BOX(box2),opt,TRUE,TRUE,0);
619 	gtk_widget_show(opt);
620 
621 	/* buttons */
622 	box2=gtk_hbox_new(FALSE,10);
623 	gtk_container_set_border_width(GTK_CONTAINER(box2),10);
624 	gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
625 	gtk_widget_show(box2);
626 	button=gtk_button_new_with_label("OK");
627 	g_signal_connect(G_OBJECT(button),"clicked",
628 									G_CALLBACK(update_triangle_info),
629 									window);
630 	gtk_box_pack_start(GTK_BOX(box2),button,TRUE,TRUE,0);
631 	GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT);
632 	gtk_widget_grab_default(button);
633 	gtk_widget_show(button);
634 
635 	button=gtk_button_new_with_label("Cancel");
636 	g_signal_connect(G_OBJECT(button),"clicked",
637 									G_CALLBACK(cancel_triangle_info),
638 									window);
639 	gtk_box_pack_start(GTK_BOX(box2),button,TRUE,TRUE,0);
640 	gtk_widget_show(button);
641 
642 	gtk_widget_show(window);
643 }
644 
645 static char *temp_scratch_epsilon=0;
646 static char *temp_scratch_mu=0;
647 static char *temp_scratch_rho=0;
648 static void
dialog_material_info_change_eps(GtkEntry * textbox)649 dialog_material_info_change_eps(GtkEntry *textbox)
650 {
651 #ifdef DEBUG
652 		printf("dialog_material_info_change_eps value=%s\n",gtk_entry_get_text(textbox));
653 #endif
654     if((temp_scratch_epsilon=(char*)realloc((void*)temp_scratch_epsilon,
655     sizeof(char)*(size_t)(strlen(gtk_entry_get_text(textbox))+1)))==0) {
656     fprintf(stderr,"%s: %d: No free memory\n",__FILE__,__LINE__);
657     exit(1);
658     }
659     strcpy(temp_scratch_epsilon,gtk_entry_get_text(textbox));
660 }
661 static void
dialog_material_info_change_mu(GtkEntry * textbox)662 dialog_material_info_change_mu(GtkEntry *textbox)
663 {
664 #ifdef DEBUG
665 		printf("dialog_material_info_change_eps value=%s\n",gtk_entry_get_text(textbox));
666 #endif
667     if((temp_scratch_mu=(char*)realloc((void*)temp_scratch_mu,
668     sizeof(char)*(size_t)(strlen(gtk_entry_get_text(textbox))+1)))==0) {
669     fprintf(stderr,"%s: %d: No free memory\n",__FILE__,__LINE__);
670     exit(1);
671     }
672     strcpy(temp_scratch_mu,gtk_entry_get_text(textbox));
673 }
674 static void
dialog_material_info_change_rho(GtkEntry * textbox)675 dialog_material_info_change_rho(GtkEntry *textbox)
676 {
677 #ifdef DEBUG
678 		printf("dialog_material_info_change_eps value=%s\n",gtk_entry_get_text(textbox));
679 #endif
680     if((temp_scratch_rho=(char*)realloc((void*)temp_scratch_rho,
681     sizeof(char)*(size_t)(strlen(gtk_entry_get_text(textbox))+1)))==0) {
682     fprintf(stderr,"%s: %d: No free memory\n",__FILE__,__LINE__);
683     exit(1);
684     }
685     strcpy(temp_scratch_rho,gtk_entry_get_text(textbox));
686 }
687 static void
update_material_info(GtkWidget * widget,gpointer data)688 update_material_info(GtkWidget *widget, gpointer data)
689 {
690   exp_nodetype *pp=0;
691 	if ( chosen_triangle )  {
692    free(bound.poly_array[chosen_triangle->boundary].mustr);
693    bound.poly_array[chosen_triangle->boundary].mustr=temp_scratch_mu;
694    free(bound.poly_array[chosen_triangle->boundary].epsstr);
695    bound.poly_array[chosen_triangle->boundary].epsstr=temp_scratch_epsilon;
696    free(bound.poly_array[chosen_triangle->boundary].rhostr);
697    bound.poly_array[chosen_triangle->boundary].rhostr=temp_scratch_rho;
698    /* parse the strings */
699    pp=0;
700    equation_parse(bound.poly_array[chosen_triangle->boundary].mustr,&pp);
701    bound.poly_array[chosen_triangle->boundary].muexp=pp;
702    pp=0;
703    equation_parse(bound.poly_array[chosen_triangle->boundary].epsstr,&pp);
704    bound.poly_array[chosen_triangle->boundary].epsexp=pp;
705    pp=0;
706    equation_parse(bound.poly_array[chosen_triangle->boundary].rhostr,&pp);
707    bound.poly_array[chosen_triangle->boundary].rhoexp=pp;
708   } else {
709    free(temp_scratch_mu);
710    free(temp_scratch_epsilon);
711    free(temp_scratch_rho);
712   }
713 	chosen_triangle=0;
714 	gtk_widget_destroy(GTK_WIDGET(data));
715 }
716 static void
close_material_info(GtkWidget * widget,gpointer data)717 close_material_info(GtkWidget *widget, gpointer data)
718 {
719   free(temp_scratch_mu);
720   free(temp_scratch_epsilon);
721   free(temp_scratch_rho);
722 	chosen_triangle=0;
723 	gtk_widget_destroy(GTK_WIDGET(data));
724 }
725 /* popup window to modify material properties of an area */
726 static void
dialog_display_material_info(int boundary_no)727 dialog_display_material_info(int boundary_no){
728   GtkWidget *window,*box1,*box2,*label,*textbox,*button;
729 	static gchar buf[128];
730 
731   if ( boundary_no < bound.npoly ) {
732 /* intialize temp variables */
733 temp_scratch_epsilon=0;
734 temp_scratch_mu=0;
735 temp_scratch_rho=0;
736 /* copy original value to temp variables */
737     if((temp_scratch_epsilon=(char*)malloc(sizeof(char)*(size_t)(strlen(bound.poly_array[chosen_triangle->boundary].epsstr)+1)))==0) {
738     fprintf(stderr,"%s: %d: No free memory\n",__FILE__,__LINE__);
739     exit(1);
740     }
741     if((temp_scratch_mu=(char*)malloc(sizeof(char)*(size_t)(strlen(bound.poly_array[chosen_triangle->boundary].mustr)+1)))==0) {
742     fprintf(stderr,"%s: %d: No free memory\n",__FILE__,__LINE__);
743     exit(1);
744     }
745     if((temp_scratch_rho=(char*)malloc(sizeof(char)*(size_t)(strlen(bound.poly_array[chosen_triangle->boundary].rhostr)+1)))==0) {
746     fprintf(stderr,"%s: %d: No free memory\n",__FILE__,__LINE__);
747     exit(1);
748     }
749 
750     strcpy(temp_scratch_rho,bound.poly_array[chosen_triangle->boundary].rhostr);
751     strcpy(temp_scratch_mu,bound.poly_array[chosen_triangle->boundary].mustr);
752     strcpy(temp_scratch_epsilon,bound.poly_array[chosen_triangle->boundary].epsstr);
753 
754 	window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
755 	g_signal_connect_swapped(GTK_OBJECT(window),"delete_event",
756 	G_CALLBACK(gtk_widget_destroy),(gpointer)window);
757 	gtk_window_set_title(GTK_WINDOW(window),"Modify Material Properties");
758 
759  	box1=gtk_vbox_new(FALSE,0);
760 	gtk_container_add(GTK_CONTAINER(window),box1);
761 	gtk_widget_show(box1);
762 
763 
764 	box2=gtk_hbox_new(FALSE,10);
765 	gtk_container_set_border_width(GTK_CONTAINER(box2),10);
766 	gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
767 	gtk_widget_show(box2);
768 	g_snprintf(buf,128,"Boundary <span foreground=\"blue\">%d</span>",boundary_no);
769 	label=gtk_label_new(NULL);
770   gtk_label_set_markup(GTK_LABEL(label),buf);
771 	gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
772 	gtk_widget_show(label);
773 
774   box2=gtk_hbox_new(FALSE,10);
775   gtk_container_set_border_width(GTK_CONTAINER(box2),10);
776   label=gtk_label_new("epsilon (Permittivity)");
777   gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
778   gtk_widget_show(label);
779 
780   textbox=gtk_entry_new();
781   g_snprintf(buf,20,"%s",bound.poly_array[boundary_no].epsstr);
782   gtk_entry_set_text(GTK_ENTRY(textbox),buf);
783   gtk_box_pack_start(GTK_BOX(box2),textbox,TRUE,TRUE,0);
784   gtk_widget_show(textbox);
785 	g_signal_connect(G_OBJECT(textbox), "changed",
786 	 G_CALLBACK(dialog_material_info_change_eps),NULL);
787 	gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
788   gtk_widget_show(box2);
789 
790   box2=gtk_hbox_new(FALSE,10);
791   gtk_container_set_border_width(GTK_CONTAINER(box2),10);
792   label=gtk_label_new("mu (Permeability)");
793   gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
794   gtk_widget_show(label);
795 
796   textbox=gtk_entry_new();
797   g_snprintf(buf,20,"%s",bound.poly_array[boundary_no].mustr);
798   gtk_entry_set_text(GTK_ENTRY(textbox),buf);
799   gtk_box_pack_start(GTK_BOX(box2),textbox,TRUE,TRUE,0);
800   gtk_widget_show(textbox);
801 	g_signal_connect(G_OBJECT(textbox), "changed",
802 	 G_CALLBACK(dialog_material_info_change_mu),NULL);
803 	gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
804   gtk_widget_show(box2);
805 
806   box2=gtk_hbox_new(FALSE,10);
807   gtk_container_set_border_width(GTK_CONTAINER(box2),10);
808   label=gtk_label_new("rho (charge)");
809   gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
810   gtk_widget_show(label);
811 
812   textbox=gtk_entry_new();
813   g_snprintf(buf,20,"%s",bound.poly_array[boundary_no].rhostr);
814   gtk_entry_set_text(GTK_ENTRY(textbox),buf);
815   gtk_box_pack_start(GTK_BOX(box2),textbox,TRUE,TRUE,0);
816   gtk_widget_show(textbox);
817 	g_signal_connect(G_OBJECT(textbox), "changed",
818 	 G_CALLBACK(dialog_material_info_change_rho),NULL);
819 	gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
820   gtk_widget_show(box2);
821 
822 	/* buttons */
823 	box2=gtk_hbox_new(FALSE,10);
824 	gtk_container_set_border_width(GTK_CONTAINER(box2),10);
825 	gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
826 	gtk_widget_show(box2);
827 	button=gtk_button_new_with_label("OK");
828 	g_signal_connect(G_OBJECT(button),"clicked",
829 									G_CALLBACK(update_material_info),
830 									(gpointer)window);
831 	gtk_box_pack_start(GTK_BOX(box2),button,TRUE,TRUE,0);
832 	GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT);
833 	gtk_widget_grab_default(button);
834 	gtk_widget_show(button);
835 
836 	button=gtk_button_new_with_label("Cancel");
837 	g_signal_connect(G_OBJECT(button),"clicked",
838 									G_CALLBACK(close_material_info),
839 									(gpointer)window);
840 	gtk_box_pack_start(GTK_BOX(box2),button,TRUE,TRUE,0);
841 	gtk_widget_show(button);
842 
843 
844 	gtk_widget_show(window);
845  }
846 }
847 
848 
849 /* mouse button press */
850 static gboolean
button_press_event(GtkWidget * widget,GdkEventButton * event,gpointer data)851 button_press_event(GtkWidget *widget,
852    GdkEventButton *event,
853 	 gpointer data)
854 {
855  GLfloat mx,my;
856  point p;
857  DAG_node *current_dag_node;
858  double temp;
859 
860 #ifdef DEBUG
861  g_print("%s: \"button_press_event\"\n",gtk_widget_get_name(widget));
862 #endif
863 
864 
865  if ( event->button == 1 && mouse_responce_flag==MENU_INFO ) {
866 #ifdef DEBUG
867  g_print("info coords: (%lf, %lf)\n",event->x,event->y);
868 #endif
869 	/* we are in info mode, query a point */
870   /* get point  coordinates */
871  mx=widget->allocation.width;
872  my=widget->allocation.height;
873 
874 #ifdef DEBUG
875  g_print("window size (%f %f)\n",mx,my);
876 #endif
877 
878  p.x = (2*( double )event->x/( double ) mx-1.0);
879  p.y = -2*( double )event->y/( double ) my+1.0;
880 
881  /* transform back to global coords */
882  glGetDoublev(GL_MODELVIEW_MATRIX,current_mat);
883 
884 #ifdef DEBUG
885  g_print("finding "MDF","MDF"\n",p.x,p.y);
886 #endif
887  p.x=(p.x-current_mat[12])/current_mat[0];
888  p.y=(p.y-current_mat[13])/current_mat[5];
889  current_dag_node=DAG_find(&dt, (void *)&p,(void*)&M);
890  if ( current_dag_node ) {
891 	chosen_triangle=(triangle *)current_dag_node->rec;
892  if (chosen_triangle->status==LIVE ) {
893   if ( drawing_mode_flag== DRAW_OUTPUT ) {
894    dialog_display_triangle_info();
895   } else { /* DRAW_INPUT */
896   /* modify material properties */
897    dialog_display_material_info(chosen_triangle->boundary);
898   }
899 
900 	/* refine_this_triangle(chosen_triangle,0,1); */
901 #ifdef DEBUG
902 	printf("menu_info: point inside %d->(%d,%d,%d), status %d boundary %d\n",chosen_triangle->n,chosen_triangle->p0,chosen_triangle->p1,chosen_triangle->p2,chosen_triangle->status,chosen_triangle->boundary);
903 	printf("menu_info: points %d(%s), %d(%s), %d(%s)\n",chosen_triangle->p0,(Mval(chosen_triangle->p0,M)==FX? "fixed":"variable"), chosen_triangle->p1,(Mval(chosen_triangle->p1,M)==FX? "fixed":"variable"), chosen_triangle->p2,(Mval(chosen_triangle->p2,M)==FX? "fixed":"variable"));
904 	printf("menu_info: potentials %d("MDF"), %d("MDF"), %d("MDF")\n",chosen_triangle->p0,Mz(chosen_triangle->p0,M),chosen_triangle->p1,Mz(chosen_triangle->p1,M),chosen_triangle->p2,Mz(chosen_triangle->p2,M));
905 #endif
906   /* redraw */
907 		gdk_window_invalidate_rect(widget->window, &widget->allocation ,FALSE);
908 	return(TRUE);
909 	}
910   }
911   } else if ( event->button == 1 && mouse_responce_flag==MENU_SPLIT_TRIANGLE ) {
912 
913 #ifdef DEBUG
914  g_print("info coords: (%lf, %lf)\n",event->x,event->y);
915 #endif
916 	/* we are in info mode, query a point */
917   /* get point  coordinates */
918  mx=widget->allocation.width;
919  my=widget->allocation.height;
920 
921 #ifdef DEBUG
922  g_print("window size (%f %f)\n",mx,my);
923 #endif
924 
925  p.x = (2*( double )event->x/( double ) mx-1.0);
926  p.y = -2*( double )event->y/( double ) my+1.0;
927 
928  /* transform back to global coords */
929  glGetDoublev(GL_MODELVIEW_MATRIX,current_mat);
930 
931 #ifdef DEBUG
932  g_print("finding "MDF","MDF"\n",p.x,p.y);
933 #endif
934  p.x=(p.x-current_mat[12])/current_mat[0];
935  p.y=(p.y-current_mat[13])/current_mat[5];
936  current_dag_node=DAG_find(&dt, (void *)&p,(void*)&M);
937  if ( current_dag_node ) {
938 	chosen_triangle=(triangle *)current_dag_node->rec;
939  if (chosen_triangle->status==LIVE ) {
940 	 refine_this_triangle(chosen_triangle,1,1);
941   /* redraw */
942 		gdk_window_invalidate_rect(widget->window, &widget->allocation ,FALSE);
943 	return(TRUE);
944 	}
945   }
946  } else if ( (event->button == 1) && (mouse_responce_flag==MENU_ZOOM_START)) {
947 
948 #ifdef DEBUG
949   g_print("zoom start coords: (%lf, %lf)\n",event->x,event->y);
950 #endif
951 
952 	/* get click point coordinates  */
953   mx=widget->allocation.width;
954   my=widget->allocation.height;
955 
956    zoom_x1 = (2*( double )event->x/( double ) mx-1.0);
957    zoom_y1 = -2*( double )event->y/( double ) my+1.0;
958 
959    /* convert back to world coords */
960    glGetDoublev(GL_MODELVIEW_MATRIX,current_mat);
961    zoom_x1=(zoom_x1-current_mat[12])/current_mat[0];
962    zoom_y1=(zoom_y1-current_mat[13])/current_mat[5];
963    /* eliminate previous zoom window */
964 	 zoom_x2=zoom_x1; zoom_y2=zoom_y1;
965 
966     mouse_responce_flag=MENU_ZOOM_END;
967 	  return(TRUE);
968  } else if ( (event->button == 1) && (mouse_responce_flag==MENU_ZOOM_END)) {
969 
970 #ifdef DEBUG
971   g_print("zoom stop coords: (%lf, %lf)\n",event->x,event->y);
972 #endif
973   /* get click point coordinates  */
974   mx=widget->allocation.width;
975   my=widget->allocation.height;
976 
977    zoom_x2 = (2*( double )event->x/( double ) mx-1.0);
978    zoom_y2 = -2*( double )event->y/( double ) my+1.0;
979 
980 
981    /* convert back to world coords */
982     glGetDoublev(GL_MODELVIEW_MATRIX,current_mat);
983    zoom_x2=(zoom_x2-current_mat[12])/current_mat[0];
984    zoom_y2=(zoom_y2-current_mat[13])/current_mat[5];
985 
986 	/*printf("zoom window (%lf %lf) (%lf %lf)\n",zoom_x1,zoom_y1,zoom_x2,zoom_y2); */
987 	/* now zoom */
988 	if ( zoom_x1 != zoom_x2 ) {
989 		/* first arrange points in zoom window */
990 		if ( zoom_x1 > zoom_x2 ) {
991 						temp=zoom_x1;
992 						zoom_x1=zoom_x2;
993             zoom_x2=temp;
994 		}
995 		if ( zoom_y1 < zoom_y2 ) {
996 						temp=zoom_y1;
997 						zoom_y1=zoom_y2;
998 						zoom_y2=temp;
999 		}
1000 
1001   		/* now keep same aspect ratio as the figure */
1002 		zoom_y2=-(double)my/(double)mx*(zoom_x2-zoom_x1)+zoom_y1;
1003 	/*printf("zoom window (%lf %lf) (%lf %lf)\n",zoom_x1,zoom_y1,zoom_x2,zoom_y2); */
1004       /* preserve the current matrix on the stack */
1005 			 glPushMatrix();
1006        /* first zoom all */
1007 	     glLoadIdentity();
1008 		/* then do the real zoom */
1009 		glScalef(-2.0/(zoom_x1-zoom_x2),2.0/(zoom_y1-zoom_y2),1.0);
1010 		glTranslatef(-0.5*(zoom_x1+zoom_x2),-0.5*(zoom_y1+zoom_y2),0);
1011    /* redisplay */
1012 		gdk_window_invalidate_rect(widget->window, &widget->allocation ,FALSE);
1013  }
1014     mouse_responce_flag=MENU_ZOOM_START;
1015 	  return(TRUE);
1016  }
1017  return(FALSE);
1018 }
1019 
1020 
1021 /* mouse right button press menu */
1022 static gboolean
button_press_event_popup_menu(GtkWidget * widget,GdkEventButton * event,gpointer data)1023 button_press_event_popup_menu(GtkWidget *widget,
1024     GdkEventButton *event,
1025 		gpointer data)
1026 {
1027 
1028 #ifdef DEBUG
1029   g_print("%s: \"button_press_event_popup\":  ",gtk_widget_get_name(widget));
1030 #endif
1031 
1032 	if ( event->button==3) {
1033 
1034 #ifdef DEBUG
1035      g_print("button 3\n");
1036 #endif
1037 		 gtk_menu_popup(GTK_MENU(widget),NULL,NULL,NULL,NULL,
1038 		  event->button, event->time);
1039 		return(TRUE);
1040 	}
1041 
1042   return(FALSE);
1043 }
1044 
1045 /* mouse  motion */
1046 static gboolean
motion_notify_event(GtkWidget * widget,GdkEventMotion * event,gpointer data)1047 motion_notify_event(GtkWidget *widget,
1048    GdkEventMotion *event,
1049 	 gpointer data)
1050 {
1051 
1052  GLfloat mx,my;
1053  double cx,cy,cz;
1054  gchar buf[128];
1055  triangle *t;
1056  point p;
1057  DAG_node *current_dag_node;
1058  /* track coordinates */
1059    mx=widget->allocation.width;
1060    my=widget->allocation.height;
1061   p.x=cx=2*(double)event->x/(double)mx -1.0;
1062   p.y=cy=-2*(double)event->y/(double)my +1.0;
1063   glGetDoublev(GL_MODELVIEW_MATRIX,current_mat);
1064   cx=((cx-current_mat[12])/current_mat[0])*g_xscale-g_xoff;
1065   cy=((cy-current_mat[13])/current_mat[5])*g_yscale-g_yoff;
1066  /* switch back to global coords */
1067 
1068 /* find triangle */
1069  cz=0.0;
1070  p.x=(p.x-current_mat[12])/current_mat[0];
1071  p.y=(p.y-current_mat[13])/current_mat[5];
1072  current_dag_node=DAG_find(&dt, (void *)&p,(void*)&M);
1073  if ( current_dag_node ) {
1074 	 t=(triangle *)current_dag_node->rec;
1075    if (t->status==LIVE ) {
1076 /*   cz=interpolate_potential(Mx(t->p0),My(t->p0),Mzz(t->p0,current_plotting_contour),
1077     Mx(t->p1),My(t->p1),Mzz(t->p1,current_plotting_contour),
1078     Mx(t->p2),My(t->p2),Mzz(t->p2,current_plotting_contour),
1079     p.x,p.y);*/
1080  cz=interpolate_potential(Mx(t->p0,M)*g_xscale-g_xoff,My(t->p0,M)*g_yscale-g_yoff,Mzz(t->p0,current_plotting_contour,M),
1081     Mx(t->p1,M)*g_xscale-g_xoff,My(t->p1,M)*g_yscale-g_yoff,Mzz(t->p1,current_plotting_contour,M),
1082     Mx(t->p2,M)*g_xscale-g_xoff,My(t->p2,M)*g_yscale-g_yoff,Mzz(t->p2,current_plotting_contour,M),
1083     cx,cy);
1084    }
1085  }
1086  g_snprintf(buf, 128, "x: <span foreground=\"blue\">%5.3lf</span> y: <span foreground=\"blue\">%5.3lf</span> z: <span foreground=\"blue\">%5.3lf</span>", cx,cy,cz);
1087  gtk_label_set_markup(GTK_LABEL(global_status_label),buf);
1088  if ( mouse_responce_flag==MENU_ZOOM_END ) {
1089    /* g_print("%s: \"motion_notify_event\": button",gtk_widget_get_name(widget));
1090 	  g_print(" 1 (%lf, %lf)\n",event->x,event->y);
1091 		*/
1092    /* get click point coordinates  */
1093    zoom_x2 = (2*( double )event->x/( double ) mx-1.0);
1094    zoom_y2 = -2*( double )event->y/( double ) my+1.0;
1095 
1096 
1097    /* convert back to world coords */
1098     glGetDoublev(GL_MODELVIEW_MATRIX,current_mat);
1099    zoom_x2=(zoom_x2-current_mat[12])/current_mat[0];
1100    zoom_y2=(zoom_y2-current_mat[13])/current_mat[5];
1101 
1102  gdk_window_invalidate_rect(widget->window, &widget->allocation ,FALSE);
1103  return(TRUE);
1104  }
1105 
1106  return(FALSE);
1107 }
1108 
1109 /* menu handlers */
1110 static void
switch_to_0_mode(GtkWidget * widget)1111 switch_to_0_mode(GtkWidget *widget)
1112 {
1113   mouse_responce_flag=MENU_0;
1114 
1115 #ifdef DEBUG
1116   g_print("%s: \"menu 0\"\n",gtk_widget_get_name(widget));
1117 #endif
1118 
1119   update_status_bar("0 Mode");
1120 }
1121 
1122 static void
switch_to_info_mode(GtkWidget * widget)1123 switch_to_info_mode(GtkWidget *widget)
1124 {
1125   mouse_responce_flag=MENU_INFO;
1126 
1127 #ifdef DEBUG
1128   g_print("%s: \"menu info\"\n",gtk_widget_get_name(widget));
1129 #endif
1130 
1131   update_status_bar("Info Mode");
1132 }
1133 
1134 static void
switch_to_split_mode(GtkWidget * widget)1135 switch_to_split_mode(GtkWidget *widget)
1136 {
1137   mouse_responce_flag=MENU_SPLIT_TRIANGLE;
1138 
1139 #ifdef DEBUG
1140   g_print("%s: \"menu split\"\n",gtk_widget_get_name(widget));
1141 #endif
1142 
1143   update_status_bar("Triangle Split Mode");
1144 }
1145 static void
switch_to_zoom_start(GtkWidget * widget)1146 switch_to_zoom_start(GtkWidget *widget)
1147 {
1148   mouse_responce_flag=MENU_ZOOM_START;
1149 
1150 #ifdef DEBUG
1151   g_print("%s: \"menu zoom start\"\n",gtk_widget_get_name(widget));
1152 #endif
1153 
1154   update_status_bar("Zooming...");
1155 }
1156 
1157 static void
switch_to_zoom_all(GtkWidget * widget)1158 switch_to_zoom_all(GtkWidget *widget)
1159 {
1160  glLoadIdentity();
1161 #ifdef DEBUG
1162   g_print("%s: \"menu zoom all\"\n",gtk_widget_get_name(widget));
1163 #endif
1164 
1165  gdk_window_invalidate_rect(widget->window, &widget->allocation ,TRUE);
1166 }
1167 
1168 /* callback for toolbar */
1169 static void
switch_to_zoom_all_button(GtkWidget * widget,gpointer data)1170 switch_to_zoom_all_button(GtkWidget *widget, gpointer data)
1171 {
1172 
1173  GtkWidget *w=GTK_WIDGET(data);
1174  glLoadIdentity();
1175 #ifdef DEBUG
1176   g_print("%s: \"menu zoom all\"\n",gtk_widget_get_name(w));
1177 #endif
1178 
1179  gdk_window_invalidate_rect(w->window, &w->allocation ,TRUE);
1180 }
1181 static void
switch_to_zoom_back(GtkWidget * widget)1182 switch_to_zoom_back(GtkWidget *widget)
1183 {
1184  glPopMatrix();
1185 #ifdef DEBUG
1186   g_print("%s: \"menu zoom back\"\n",gtk_widget_get_name(widget));
1187 #endif
1188 
1189  gdk_window_invalidate_rect(widget->window, &widget->allocation ,TRUE);
1190 }
1191 
1192 /* callback for toolbar */
1193 static void
switch_to_zoom_back_button(GtkWidget * widget,gpointer data)1194 switch_to_zoom_back_button(GtkWidget *widget, gpointer data)
1195 {
1196  GtkWidget *w=GTK_WIDGET(data);
1197  glPopMatrix();
1198 #ifdef DEBUG
1199   g_print("%s: \"menu zoom back\"\n",gtk_widget_get_name(w));
1200 #endif
1201 
1202  gdk_window_invalidate_rect(w->window, &w->allocation ,TRUE);
1203 }
1204 
1205 /* used when degree of freedom of points > 1 */
1206 static void
switch_to_next_eigenmode(GtkWidget * widget)1207 switch_to_next_eigenmode(GtkWidget *widget)
1208 {
1209  /* switch to next eigenmode */
1210   if (solve_equation== POISSON || solve_equation == POISSON_SPARSE ) {
1211    current_plotting_contour=0;
1212   } else if (solve_equation == HELMHOLTZ ) {
1213    current_plotting_contour++;
1214   if ( current_plotting_contour >=degree_of_freedom )
1215    current_plotting_contour=0;
1216   } else if ((solve_equation == HELMHOLTZ_INHOMO)
1217      || (solve_equation == HELMHOLTZ_FREQ)
1218      || (solve_equation == HELMHOLTZ_BETA)) {
1219    current_plotting_contour++;
1220   if ( current_plotting_contour >=3*degree_of_freedom )
1221    current_plotting_contour=0;
1222   }
1223 
1224 
1225 #ifdef DEBUG
1226   g_print("%s: \" %d th eigenmode\"\n",gtk_widget_get_name(widget),current_plotting_contour);
1227 #endif
1228 
1229  gdk_window_invalidate_rect(widget->window, &widget->allocation ,FALSE);
1230  if( global_surf_mesh_window != NULL )
1231  gdk_window_invalidate_rect(global_surf_mesh_window->window, &global_surf_mesh_window->allocation,TRUE);
1232 }
1233 
1234 /* key press */
1235 static gboolean
key_press_event(GtkWidget * widget,GdkEventKey * event,gpointer data)1236 key_press_event(GtkWidget *widget,
1237    GdkEventKey *event,
1238 	 gpointer data)
1239 {
1240   GtkWidget *drawing_area=GTK_WIDGET(data);
1241  switch (event->keyval) {
1242     case GDK_n:
1243       /* switch to next eigenmode */
1244       switch_to_next_eigenmode(drawing_area);
1245      /* explicitly send a redraw to drawing area */
1246      gdk_window_invalidate_rect(widget->window, &widget->allocation ,FALSE);
1247      if( global_surf_mesh_window != NULL )
1248       gdk_window_invalidate_rect(global_surf_mesh_window->window, &global_surf_mesh_window->allocation,TRUE);
1249       break;
1250 
1251     case GDK_Escape:
1252       /* quit the program */
1253       gtk_main_quit();
1254       break;
1255 
1256     default:
1257       return FALSE;
1258     }
1259   return TRUE;
1260 }
1261 
1262 
1263 /*static void
1264 switch_to_full_screen(GtkWidget *widget)
1265 {
1266  gtk_window_fullscreen((GtkWindow*)widget->window);
1267  gdk_window_invalidate_rect(widget->window, &widget->allocation ,FALSE);
1268 }*/
1269 /*
1270 static void
1271 switch_to_original_size(GtkWidget *widget)
1272 {
1273  gtk_window_unfullscreen((GtkWindow*)widget->window);
1274  gdk_window_invalidate_rect(widget->window, &widget->allocation ,FALSE);
1275 }
1276 */
1277 
1278 /* popup menu creation */
1279 static GtkWidget *
create_popup_menu(GtkWidget * drawing_area)1280 create_popup_menu(GtkWidget *drawing_area)
1281 {
1282 
1283   GtkWidget *menu;
1284 	GtkWidget *menu_item;
1285 
1286 	menu=gtk_menu_new();
1287 
1288 	/* neutral mode */
1289  menu_item=gtk_menu_item_new_with_label("0_Mode");
1290  gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
1291  g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
1292          G_CALLBACK(switch_to_0_mode),drawing_area);
1293  gtk_widget_show(menu_item);
1294 
1295 
1296 /* info mode */
1297  menu_item=gtk_menu_item_new_with_label("Triangle Info Mode");
1298  gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
1299  g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
1300          G_CALLBACK(switch_to_info_mode),drawing_area);
1301  gtk_widget_show(menu_item);
1302 
1303 /* split mode */
1304  menu_item=gtk_menu_item_new_with_label("Triangle Split Mode");
1305  gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
1306  g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
1307          G_CALLBACK(switch_to_split_mode),drawing_area);
1308  gtk_widget_show(menu_item);
1309 
1310 
1311 /* zoom states */
1312  menu_item=gtk_menu_item_new_with_label("Zoom Window");
1313  gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
1314  g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
1315          G_CALLBACK(switch_to_zoom_start),drawing_area);
1316  gtk_widget_show(menu_item);
1317 
1318 
1319  menu_item=gtk_menu_item_new_with_label("Zoom Back");
1320  gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
1321  g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
1322          G_CALLBACK(switch_to_zoom_back),drawing_area);
1323  gtk_widget_show(menu_item);
1324 
1325  menu_item=gtk_menu_item_new_with_label("Zoom All");
1326  gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
1327  g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
1328          G_CALLBACK(switch_to_zoom_all),drawing_area);
1329  gtk_widget_show(menu_item);
1330 
1331  menu_item=gtk_menu_item_new_with_label("3D Window");
1332  gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
1333  g_signal_connect(G_OBJECT(menu_item),"activate",
1334          G_CALLBACK(display_mesh_grid),(gpointer)drawing_area);
1335  gtk_widget_show(menu_item);
1336 
1337 
1338  /* only in HELMHOLTZ equation */
1339 /* if ( solve_equation==HELMHOLTZ ) { */
1340   menu_item=gtk_menu_item_new_with_label("Next Eigenmode");
1341   gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
1342   g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
1343          G_CALLBACK(switch_to_next_eigenmode),drawing_area);
1344   gtk_widget_show(menu_item);
1345  /*} */
1346 
1347  /* full screen and back */
1348 /* menu_item=gtk_menu_item_new_with_label("Full Screen");
1349  gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
1350  g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
1351          G_CALLBACK(switch_to_full_screen),drawing_area);
1352  gtk_widget_show(menu_item);
1353 
1354  menu_item=gtk_menu_item_new_with_label("Resize");
1355  gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
1356  g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
1357          G_CALLBACK(switch_to_original_size),drawing_area);
1358  gtk_widget_show(menu_item); */
1359 
1360 /* quit option */
1361 	menu_item=gtk_menu_item_new_with_label("Quit");
1362 	gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
1363 	g_signal_connect(G_OBJECT(menu_item), "activate",
1364 	 G_CALLBACK(gtk_main_quit), NULL);
1365 	gtk_widget_show(menu_item);
1366 
1367 
1368 	return(menu);
1369 }
1370 
1371 
1372 static void
menubar_file_open_response_store_filename(GtkWidget * widget,gpointer data)1373 menubar_file_open_response_store_filename(GtkWidget *widget, gpointer data)
1374 {
1375 			GtkWidget *file_selector=(GtkWidget*)data;
1376       const gchar *tempnam;
1377 			tempnam=gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_selector));
1378     input_cord_filename=(char*)realloc((void*)input_cord_filename,sizeof(char)*(size_t)(strlen((char*)tempnam)+1));
1379 	if ( input_cord_filename == 0 ) {
1380 	  fprintf(stderr,"%s: %d: no free memory",__FILE__,__LINE__);
1381 	  exit(1);
1382 	}
1383   strcpy(input_cord_filename,(char*)tempnam);
1384 
1385 #ifdef DEBUG
1386 		g_print("menubar_file_open: filename %s\n",input_cord_filename);
1387 #endif
1388   /* if a new file name was opened, need to generate mesh
1389      so set flag to zero */
1390   mesh_already_present=0;
1391 }
1392 
1393 static void
menubar_file_import_response_store_filename(GtkWidget * widget,gpointer data)1394 menubar_file_import_response_store_filename(GtkWidget *widget, gpointer data)
1395 {
1396 			GtkWidget *file_selector=(GtkWidget*)data;
1397       const gchar *tempnam;
1398 			tempnam=gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_selector));
1399 
1400 #ifdef DEBUG
1401 		g_print("menubar_file_import: filename %s\n",(char*)tempnam);
1402 #endif
1403 
1404     /* process the DXF file */
1405 		free_everything();
1406 
1407     if ( tempnam ) {
1408 		 read_dxf_file_and_triangulate(tempnam);
1409 
1410 		/* now open a new window to edit the mesh */
1411  /* since we are not gettting input from a coord file
1412 		* the user will need to modify properties of each triangle,
1413 		* each boundary edge and each vertex. since this is a big task,
1414 		* we move everything related to this to a new file. (dxf.c) */
1415 		/* note because of this, we do not need explicit definition of boundaries
1416 			* in terms of edges etc. etc */
1417 
1418 		 display_edit_window(tempnam);
1419     }
1420   /* if a new file name was opened, need to generate mesh
1421      so set flag to zero */
1422     mesh_already_present=0;
1423 }
1424 
1425 /* menu bar callback functions */
1426 static void
menubar_file_open_response(GtkWidget * widget)1427 menubar_file_open_response( GtkWidget *widget)
1428 {
1429 
1430 						GtkWidget *file_selector;
1431 						/* create fileselector */
1432 						file_selector=gtk_file_selection_new("Please select a file");
1433 						g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->ok_button),
1434 													"clicked",
1435 													G_CALLBACK(menubar_file_open_response_store_filename),
1436 													(gpointer)file_selector);
1437 						/* ensure that the dialog box is destroyed when user clicks a button */
1438 						g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->ok_button),
1439 											"clicked",
1440 											G_CALLBACK(gtk_widget_destroy),
1441 											(gpointer)file_selector);
1442 						g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->cancel_button),
1443 											"clicked",
1444 											G_CALLBACK(gtk_widget_destroy),
1445 											(gpointer)file_selector);
1446 							/* display */
1447 							gtk_widget_show(file_selector);
1448 }
1449 
1450 /* importing a DXF file */
1451 /* note: input_cord_filename will store the filename */
1452 static void
menubar_file_import_response(gchar * string)1453 menubar_file_import_response( gchar *string )
1454 {
1455 
1456 #ifdef DEBUG
1457 				    printf ("menubar_file_import: %s\n", string);
1458 #endif
1459 						GtkWidget *file_selector;
1460 						/* create fileselector */
1461 						file_selector=gtk_file_selection_new("Please select a DXF file");
1462 						g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->ok_button),
1463 													"clicked",
1464 													G_CALLBACK(menubar_file_import_response_store_filename),
1465 													(gpointer)file_selector);
1466 						/* ensure that the dialog box is destroyed when user clicks a button */
1467 						g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->ok_button),
1468 											"clicked",
1469 											G_CALLBACK(gtk_widget_destroy),
1470 											(gpointer)file_selector);
1471 						g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->cancel_button),
1472 											"clicked",
1473 											G_CALLBACK(gtk_widget_destroy),
1474 											(gpointer)file_selector);
1475 							/* display */
1476 							gtk_widget_show(file_selector);
1477 
1478 
1479 
1480 }
1481 
1482 
1483 static void
menubar_file_save_response(GtkWidget * widget)1484 menubar_file_save_response( GtkWidget *widget)
1485 {
1486 
1487   generate_output_files();
1488 
1489 }
1490 
1491 static void
menubar_solve_only_response(GtkWidget * widget)1492 menubar_solve_only_response(GtkWidget *widget)
1493 {
1494 
1495    /* if mesh already exists, we only solve
1496       if no mesh exists, we generate the mesh before solving */
1497    if (!mesh_already_present) {
1498     free_everything();
1499     if ( input_cord_filename ) {
1500 		 solve_problem_from_scratch(input_cord_filename);
1501      mesh_already_present=1;
1502     }
1503    } else {
1504     if ( solve_equation==HELMHOLTZ ) {
1505 				re_number_and_solve_helmholtz_sparse(M,dt);
1506 		} else if ( (solve_equation==HELMHOLTZ_INHOMO)
1507      || (solve_equation == HELMHOLTZ_FREQ)
1508      || (solve_equation == HELMHOLTZ_BETA)) {
1509        buildup_hash_table_and_equation(M,dt);
1510     } else if(solve_equation==POISSON_SPARSE) {
1511 				re_number_and_solve_poisson_sparse();
1512 	  } else {
1513 				re_number_and_solve_poisson();
1514     }
1515    }
1516 
1517 		gdk_window_invalidate_rect(widget->window, &widget->allocation ,FALSE);
1518 }
1519 
1520 
1521 static void
menubar_solve_mesh_response(gchar * string)1522 menubar_solve_mesh_response( gchar *string )
1523 {
1524 
1525 #ifdef DEBUG
1526 	printf ("menubar_solve_mesh: %s\n", string);
1527 #endif
1528    free_everything();
1529    if ( input_cord_filename ) {
1530      generate_mesh(input_cord_filename);
1531      mesh_already_present=1;
1532   }
1533 }
1534 
1535 static void
menubar_solve_iterative_response(gchar * string)1536 menubar_solve_iterative_response( gchar *string )
1537 {
1538   int i;
1539 	MY_DOUBLE priority;
1540 #ifdef DEBUG
1541 	printf ("menubar_solve_solve: %s\n", string);
1542 #endif
1543    if (mesh_already_present==0) {
1544     free_everything();
1545     if ( input_cord_filename ) {
1546 		 solve_problem_from_scratch(input_cord_filename);
1547     } else {
1548      return;
1549     }
1550    }
1551 #ifdef DEBUG
1552   printf("mesh=%d, iterations=%d solver=%d\n",mesh_already_present,max_iteration_limit, solve_equation);
1553 #endif
1554 		 UPDATE_GUI
1555 		 for ( i=0; i< max_iteration_limit; i++) {
1556 #ifdef DEBUG
1557 		printf ("menubar_solve_solve: iteration %d of %d\n", i,max_iteration_limit);
1558 #endif
1559 
1560 			priority=(MY_DOUBLE)(i+1)/(MY_DOUBLE)max_iteration_limit;
1561        /* refine mesh */
1562 			 if (refine_mesh_with_iterations(priority)) {
1563 
1564 		 UPDATE_GUI
1565     if ( solve_equation==HELMHOLTZ ) {
1566 				re_number_and_solve_helmholtz_sparse(M,dt);
1567 		} else if ( (solve_equation==HELMHOLTZ_INHOMO)
1568      || (solve_equation == HELMHOLTZ_FREQ)
1569      || (solve_equation == HELMHOLTZ_BETA)) {
1570        buildup_hash_table_and_equation(M,dt);
1571     } else if(solve_equation==POISSON_SPARSE) {
1572 				re_number_and_solve_poisson_sparse();
1573 	  } else {
1574 				re_number_and_solve_poisson();
1575     }
1576 		 UPDATE_GUI
1577 			} else {
1578 				break;
1579 			}
1580   }
1581 
1582 }
1583 
1584 /* integrates to find charge */
1585 static void
menubar_solve_integrate_responce(gchar * str)1586 menubar_solve_integrate_responce(gchar *str) {
1587   calc_integral(current_plotting_contour);
1588 }
1589 
1590 /* edit material properties */
1591 static void
menubar_solve_materials_responce(GtkWidget * menuitem,gpointer data)1592 menubar_solve_materials_responce(GtkWidget *menuitem, gpointer data) {
1593   /* get the active state of menu item */
1594   GtkWidget *menu=(GtkWidget *)data;
1595 
1596   if(!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu))) {
1597     /* revert to normal mode */
1598     drawing_mode_flag= DRAW_OUTPUT;
1599     mouse_responce_flag=MENU_0;
1600   } else {
1601    /* change drawing mode to draw material */
1602    drawing_mode_flag= DRAW_INPUT;
1603   /* respond to mouse clicks */
1604   mouse_responce_flag=MENU_INFO;
1605  }
1606 }
1607 
1608 
1609 /* globals for menubar_solve_options */
1610 static double temp_scratch_area_floor;
1611 static double temp_scratch_area_ceil;
1612 static double temp_scratch_triangle_badness;
1613 static double temp_scratch_wave_k0;
1614 static double temp_scratch_wave_beta;
1615 
1616 static int temp_scratch_contour_levels;
1617 static int temp_scratch_equation_type;
1618 static int temp_scratch_iteration_limit;
1619 static int temp_scratch_degree_of_freedom;
1620 
1621 /* callbacks for menubar_solve_options */
1622 static void
menubar_save_cb_area_floor(GtkAdjustment * adj)1623 menubar_save_cb_area_floor(GtkAdjustment *adj)
1624 {
1625 #ifdef DEBUG
1626 		printf("menubar_save_cb_area_floor: value=%lf\n",adj->value);
1627 #endif
1628     temp_scratch_area_floor=(double)adj->value;
1629 }
1630 static void
menubar_save_cb_area_ceil(GtkAdjustment * adj)1631 menubar_save_cb_area_ceil(GtkAdjustment *adj)
1632 {
1633 #ifdef DEBUG
1634 		printf("menubar_save_cb_area_ceil: value=%lf\n",adj->value);
1635 #endif
1636     temp_scratch_area_ceil=(double)adj->value;
1637 }
1638 static void
menubar_save_cb_badness_limit(GtkAdjustment * adj)1639 menubar_save_cb_badness_limit(GtkAdjustment *adj)
1640 {
1641 #ifdef DEBUG
1642 		printf("menubar_save_cb_badness_limit: value=%lf\n",adj->value);
1643 #endif
1644     temp_scratch_triangle_badness=(double)adj->value;
1645 }
1646 static void
menubar_save_cb_contour_levels(GtkAdjustment * adj)1647 menubar_save_cb_contour_levels(GtkAdjustment *adj)
1648 {
1649 #ifdef DEBUG
1650 		printf("menubar_save_cb_contour_levels: value=%d\n",(int)adj->value);
1651 #endif
1652     temp_scratch_contour_levels=(int)adj->value;
1653 }
1654 static void
menubar_save_cb_degree_of_freedom(GtkAdjustment * adj)1655 menubar_save_cb_degree_of_freedom(GtkAdjustment *adj)
1656 {
1657 #ifdef DEBUG
1658 		printf("menubar_save_cb_degree_of_freedom: value=%d\n",(int)adj->value);
1659 #endif
1660     temp_scratch_degree_of_freedom=(int)adj->value;
1661 }
1662 static void
menubar_save_cb_iteration_limit(GtkAdjustment * adj)1663 menubar_save_cb_iteration_limit(GtkAdjustment *adj)
1664 {
1665 #ifdef DEBUG
1666 		printf("menubar_save_cb_iteration_limit: value=%d\n",(int)adj->value);
1667 #endif
1668     temp_scratch_iteration_limit=(int)adj->value;
1669 }
1670 static void
menubar_save_cb_equation_type(GtkWidget * item,gpointer data)1671 menubar_save_cb_equation_type(GtkWidget *item, gpointer data)
1672 {
1673 #ifdef DEBUG
1674    printf("menubar_save_cb_equation_type: type=%d\n",GPOINTER_TO_INT(data));
1675 #endif
1676 	 temp_scratch_equation_type=GPOINTER_TO_INT(data);
1677 }
1678 static void
menubar_save_cb_wave_k0(GtkEntry * textbox)1679 menubar_save_cb_wave_k0(GtkEntry *textbox)
1680 {
1681 #ifdef DEBUG
1682 		printf("menubar_save_cb_wave_k0: value=%s\n",gtk_entry_get_text(textbox));
1683 #endif
1684     temp_scratch_wave_k0=g_strtod(gtk_entry_get_text(textbox),0);
1685 }
1686 static void
menubar_save_cb_wave_beta(GtkEntry * textbox)1687 menubar_save_cb_wave_beta(GtkEntry *textbox)
1688 {
1689 #ifdef DEBUG
1690 		printf("menubar_save_cb_wave_k0: value=%s\n",gtk_entry_get_text(textbox));
1691 #endif
1692     temp_scratch_wave_beta=g_strtod(gtk_entry_get_text(textbox),0);
1693 }
1694 static void
menubar_save_cb_update_values(GtkWidget * widget,gpointer data)1695 menubar_save_cb_update_values(GtkWidget *widget, gpointer data)
1696 {
1697 	  /* sanity check values obtained from options window and
1698 		 * update global values */
1699 /* if any mesh parameter was changed, regenerate mesh */
1700  if (g_area_floor!=temp_scratch_area_floor
1701     ||g_area_ceil!=temp_scratch_area_ceil
1702     ||g_badness_limit!=temp_scratch_triangle_badness) {
1703   mesh_already_present=0;
1704  }
1705  if (temp_scratch_area_floor< temp_scratch_area_ceil)  {
1706      g_area_floor=temp_scratch_area_floor;
1707      g_area_ceil=temp_scratch_area_ceil;
1708 	}
1709     g_badness_limit=temp_scratch_triangle_badness;
1710     contour_levels=temp_scratch_contour_levels;
1711     max_iteration_limit=temp_scratch_iteration_limit;
1712   /* if we have currently solved an eigenproblem
1713      and we switch back to a Poisson problem, since potential
1714      data is lost, we need to re-read the input file */
1715    if((solve_equation!=POISSON) && (solve_equation != POISSON_SPARSE)
1716      && (temp_scratch_equation_type!=solve_equation)) {
1717      mesh_already_present=0;
1718     }
1719     solve_equation=temp_scratch_equation_type;
1720     if ((solve_equation == HELMHOLTZ)
1721      || (solve_equation == HELMHOLTZ_INHOMO)
1722      || (solve_equation == HELMHOLTZ_FREQ)
1723      || (solve_equation == HELMHOLTZ_BETA)) {
1724      requested_degree_of_freedom=temp_scratch_degree_of_freedom;
1725      degree_of_freedom=temp_scratch_degree_of_freedom;
1726      current_plotting_contour=0;
1727 		} else { /* POISSON */
1728      requested_degree_of_freedom=1;
1729      degree_of_freedom=1;
1730      current_plotting_contour=0;
1731      /* do not use ARPACK - not an eigenproblem */
1732      use_arpack_solver=0;
1733 		}
1734     /* resize eigenvalue array */
1735      if((eig_array= (MY_DOUBLE*) realloc((void*)eig_array,(size_t)degree_of_freedom*sizeof(MY_DOUBLE)))==0){
1736    fprintf(stderr, "%s: %d: no free memory\n", __FILE__,__LINE__);
1737    exit(1);
1738    }
1739 
1740    if (temp_scratch_wave_k0>=1.0) {
1741      global_wave_k0=temp_scratch_wave_k0;
1742    }
1743    if (temp_scratch_wave_beta>=1.0) {
1744      global_wave_beta=temp_scratch_wave_beta;
1745    }
1746 
1747 	  gtk_widget_destroy(GTK_WIDGET(data));
1748 }
1749 
1750 static void
menubar_save_cb_close_window(GtkWidget * widget,gpointer data)1751 menubar_save_cb_close_window(GtkWidget *widget, gpointer data)
1752 {
1753 	  gtk_widget_destroy(GTK_WIDGET(data));
1754 }
1755 
1756 
1757 
1758 static void
scale_set_default_values(GtkScale * scale)1759 scale_set_default_values(GtkScale *scale)
1760 {
1761 			gtk_range_set_update_policy(GTK_RANGE(scale),
1762 											GTK_UPDATE_CONTINUOUS);
1763 			gtk_scale_set_digits(scale,5);
1764 			gtk_scale_set_value_pos(scale,GTK_POS_TOP);
1765 			gtk_scale_set_draw_value(scale,TRUE);
1766 
1767 }
1768 
1769 static void
menubar_save_cb_full_solver(GtkWidget * widget,gpointer data)1770 menubar_save_cb_full_solver(GtkWidget *widget, gpointer data) {
1771    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
1772     {
1773       use_full_eigensolver=1;
1774     } else {
1775       use_full_eigensolver=0;
1776     }
1777 }
1778 
1779 static void
menubar_save_cb_arpack_solver(GtkWidget * widget,gpointer data)1780 menubar_save_cb_arpack_solver(GtkWidget *widget, gpointer data) {
1781    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
1782     {
1783       use_arpack_solver=1;
1784     } else {
1785       use_arpack_solver=0;
1786     }
1787 }
1788 
1789 
1790 static void
menubar_solve_options_response(gchar * string)1791 menubar_solve_options_response( gchar *string )
1792 {
1793 
1794 #ifdef DEBUG
1795 				    printf ("menubar_solve_options: %s\n", string);
1796 #endif
1797 						GtkWidget *window;
1798 						GtkWidget *box1, *box2;
1799 						GtkWidget *button;
1800 						GtkWidget *separator;
1801 						GtkWidget *opt, *menu, *item;
1802 					  GtkWidget *check1;
1803 
1804 						GtkWidget *label;
1805 						GtkWidget *scale;
1806 						GtkWidget *adj1;
1807             GtkWidget *textbox;
1808             gchar buf[20];
1809 
1810      temp_scratch_area_floor=g_area_floor;
1811      temp_scratch_area_ceil=g_area_ceil;
1812      temp_scratch_triangle_badness=g_badness_limit;
1813      temp_scratch_contour_levels=contour_levels;
1814      temp_scratch_iteration_limit=max_iteration_limit;
1815      temp_scratch_wave_k0=global_wave_k0;
1816      temp_scratch_wave_beta=global_wave_beta;
1817 
1818      if ( solve_equation == POISSON ) {
1819       temp_scratch_degree_of_freedom=1;
1820 		 } else { /* not POISSON */
1821 		  temp_scratch_degree_of_freedom=requested_degree_of_freedom;
1822 		 }
1823      temp_scratch_equation_type=solve_equation;
1824 /*contour_levels=40;  no of contour levels */
1825 /*current_plotting_contour=0;  number in z array < degree_of_freedom */
1826 /*g_badness_limit=2;  max triangle badness */
1827 /*g_area_floor=0.001;  min triangle area */
1828 /*g_area_ceil=0.005;  max triangle area */
1829 /*solve_equation = POISSON;  POISSON, HELMHOLTZ */
1830 
1831 
1832 						/* create menu window */
1833 						window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
1834            g_signal_connect_swapped(GTK_OBJECT(window),"delete_event",
1835 									G_CALLBACK(gtk_widget_destroy),(gpointer)window);
1836 
1837 						gtk_window_set_title(GTK_WINDOW(window),"Change Options");
1838 
1839 						box1=gtk_vbox_new(FALSE,0);
1840 						gtk_container_add(GTK_CONTAINER(window),box1);
1841 						gtk_widget_show(box1);
1842 
1843 					  /* scale for area_floor */
1844 						box2=gtk_hbox_new(FALSE,10);
1845 						gtk_container_set_border_width(GTK_CONTAINER(box2),10);
1846 						gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
1847 						gtk_widget_show(box2);
1848 
1849 						label=gtk_label_new("Min Area:");
1850 						gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
1851 						gtk_widget_show(label);
1852 						/* value,lower,upper,step_increment,page_increment,page_size */
1853 						adj1=(GtkWidget*)gtk_adjustment_new((gdouble)g_area_floor,0.0,0.1,0.00005,1.0,0.0);
1854             g_signal_connect(G_OBJECT(adj1), "value_changed",
1855 														G_CALLBACK(menubar_save_cb_area_floor),NULL);
1856 
1857 
1858 						scale=gtk_hscale_new(GTK_ADJUSTMENT(adj1));
1859 						scale_set_default_values(GTK_SCALE(scale));
1860 						gtk_box_pack_start(GTK_BOX(box2),scale,TRUE,TRUE,0);
1861 						gtk_widget_show(scale);
1862 
1863 					  /* scale for area_ceil*/
1864 	          box2=gtk_hbox_new(FALSE,10);
1865 						gtk_container_set_border_width(GTK_CONTAINER(box2),10);
1866 						gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
1867 						gtk_widget_show(box2);
1868 
1869 						label=gtk_label_new("Max Area:");
1870 						gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
1871 						gtk_widget_show(label);
1872 						/* value,lower,upper,step_increment,page_increment,page_size */
1873 						adj1=(GtkWidget*)gtk_adjustment_new((gdouble)g_area_ceil,0.0,0.1,0.00005,1.0,0.0);
1874             g_signal_connect(G_OBJECT(adj1), "value_changed",
1875 														G_CALLBACK(menubar_save_cb_area_ceil),NULL);
1876 
1877 
1878 						scale=gtk_hscale_new(GTK_ADJUSTMENT(adj1));
1879 						scale_set_default_values(GTK_SCALE(scale));
1880 						gtk_box_pack_start(GTK_BOX(box2),scale,TRUE,TRUE,0);
1881 						gtk_widget_show(scale);
1882 
1883 
1884             /* scale for badness_max */
1885 	          box2=gtk_hbox_new(FALSE,10);
1886 						gtk_container_set_border_width(GTK_CONTAINER(box2),10);
1887 						gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
1888 						gtk_widget_show(box2);
1889 
1890 						label=gtk_label_new("Tri Badness:");
1891 						gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
1892 						gtk_widget_show(label);
1893 						/* value,lower,upper,step_increment,page_increment,page_size */
1894 						adj1=(GtkWidget*)gtk_adjustment_new((gdouble)g_badness_limit,1.0,5.0,0.1,1.0,0.0);
1895             g_signal_connect(G_OBJECT(adj1), "value_changed",
1896 														G_CALLBACK(menubar_save_cb_badness_limit),NULL);
1897 
1898 
1899 						scale=gtk_hscale_new(GTK_ADJUSTMENT(adj1));
1900 						scale_set_default_values(GTK_SCALE(scale));
1901 						gtk_box_pack_start(GTK_BOX(box2),scale,TRUE,TRUE,0);
1902 						gtk_widget_show(scale);
1903 
1904 
1905 						/* type of equation to solve */
1906 						box2=gtk_hbox_new(FALSE,10);
1907 						gtk_container_set_border_width(GTK_CONTAINER(box2),10);
1908 
1909 						label=gtk_label_new("Equation type:");
1910 						gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
1911             gtk_widget_show(label);
1912 
1913 						opt=gtk_option_menu_new();
1914 						menu=gtk_menu_new();
1915 						item=make_menu_item("Poisson",
1916 														G_CALLBACK(menubar_save_cb_equation_type),
1917 														GINT_TO_POINTER(POISSON));
1918 						gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
1919 						item=make_menu_item("Poisson (Sparse)",
1920 														G_CALLBACK(menubar_save_cb_equation_type),
1921 														GINT_TO_POINTER(POISSON_SPARSE));
1922 						gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
1923 						item=make_menu_item("Homogeneous Helmholtz",
1924 														G_CALLBACK(menubar_save_cb_equation_type),
1925 														GINT_TO_POINTER(HELMHOLTZ));
1926 						gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
1927   					item=make_menu_item("InHomogeneous Helmholtz",
1928 														G_CALLBACK(menubar_save_cb_equation_type),
1929 														GINT_TO_POINTER(HELMHOLTZ_INHOMO));
1930 						gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
1931   					item=make_menu_item("Helmholtz (find beta)",
1932 														G_CALLBACK(menubar_save_cb_equation_type),
1933 														GINT_TO_POINTER(HELMHOLTZ_FREQ));
1934 						gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
1935   					item=make_menu_item("Helmholtz (find k_o)",
1936 														G_CALLBACK(menubar_save_cb_equation_type),
1937 														GINT_TO_POINTER(HELMHOLTZ_BETA));
1938 						gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
1939 
1940 
1941 						gtk_option_menu_set_menu(GTK_OPTION_MENU(opt),menu);
1942 						gtk_option_menu_set_history(GTK_OPTION_MENU(opt),(gint)solve_equation);
1943 						gtk_box_pack_start(GTK_BOX(box2),opt,TRUE,TRUE,0);
1944 						gtk_widget_show(opt);
1945 
1946 						gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
1947 						gtk_widget_show(box2);
1948             /* create check button to choose full or symmetrix matrix
1949               solver for eigenequation */
1950             check1=gtk_check_button_new_with_label("Use Full Matrix Eigensolver");
1951             if(use_full_eigensolver)
1952                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check1),TRUE);
1953             g_signal_connect(G_OBJECT(check1),"clicked",
1954               G_CALLBACK(menubar_save_cb_full_solver), NULL);
1955             gtk_widget_show(check1);
1956 
1957             box2=gtk_hbox_new(FALSE,10);
1958 						gtk_container_set_border_width(GTK_CONTAINER(box2),10);
1959 						gtk_box_pack_start(GTK_BOX(box2),check1,FALSE,FALSE,0);
1960 						gtk_widget_show(box2);
1961 						gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
1962 
1963 #ifdef USE_ARPACK
1964             /* create check button to choose ARPACK
1965               eigensolver for eigenequation */
1966             check1=gtk_check_button_new_with_label("Use ARPACK Eigensolver");
1967             if(use_arpack_solver)
1968                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check1),TRUE);
1969             g_signal_connect(G_OBJECT(check1),"clicked",
1970               G_CALLBACK(menubar_save_cb_arpack_solver), NULL);
1971             gtk_widget_show(check1);
1972 
1973             box2=gtk_hbox_new(FALSE,10);
1974 						gtk_container_set_border_width(GTK_CONTAINER(box2),10);
1975 						gtk_box_pack_start(GTK_BOX(box2),check1,FALSE,FALSE,0);
1976             /* button to change ARPACK params */
1977 						button=gtk_button_new_with_label("Configure");
1978 						g_signal_connect(G_OBJECT(button),"clicked",
1979 														G_CALLBACK(configure_arpack_solver),
1980 														window);
1981 						gtk_box_pack_start(GTK_BOX(box2),button,TRUE,TRUE,0);
1982 						gtk_widget_show(button);
1983 						GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT);
1984 						gtk_widget_show(box2);
1985 						gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
1986 #endif /* !USE_ARPACK */
1987 
1988             /* for Helmholtz only: no. of eigenmodes */
1989             box2=gtk_hbox_new(FALSE,10);
1990 						gtk_container_set_border_width(GTK_CONTAINER(box2),10);
1991 						label=gtk_label_new("No. of Eigenmodes:");
1992 						gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
1993 						gtk_widget_show(label);
1994 
1995 						adj1=(GtkWidget*)gtk_adjustment_new(requested_degree_of_freedom,1.0,150.0,5.0,1.0,0.0);
1996 						g_signal_connect(G_OBJECT(adj1), "value_changed",
1997 														G_CALLBACK(menubar_save_cb_degree_of_freedom),NULL);
1998 						scale=gtk_hscale_new(GTK_ADJUSTMENT(adj1));
1999 						gtk_scale_set_digits(GTK_SCALE(scale),0);
2000 						gtk_box_pack_start(GTK_BOX(box2),scale,TRUE,TRUE,0);
2001 						gtk_widget_show(scale);
2002 						gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
2003 						gtk_widget_show(box2);
2004 
2005 
2006             /* scale for contour levels */
2007 						box2=gtk_hbox_new(FALSE,10);
2008 						gtk_container_set_border_width(GTK_CONTAINER(box2),10);
2009 						label=gtk_label_new("Contour Levels:");
2010 						gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
2011 						gtk_widget_show(label);
2012 
2013 						adj1=(GtkWidget*)gtk_adjustment_new(contour_levels,5.0,150.0,5.0,1.0,0.0);
2014 						g_signal_connect(G_OBJECT(adj1), "value_changed",
2015 														G_CALLBACK(menubar_save_cb_contour_levels),NULL);
2016 						scale=gtk_hscale_new(GTK_ADJUSTMENT(adj1));
2017 						gtk_scale_set_digits(GTK_SCALE(scale),0);
2018 						gtk_box_pack_start(GTK_BOX(box2),scale,TRUE,TRUE,0);
2019 						gtk_widget_show(scale);
2020 						gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
2021 						gtk_widget_show(box2);
2022 
2023             /* iteration limit */
2024             box2=gtk_hbox_new(FALSE,10);
2025 						gtk_container_set_border_width(GTK_CONTAINER(box2),10);
2026 						label=gtk_label_new("Iteration Limit:");
2027 						gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
2028 						gtk_widget_show(label);
2029 
2030 						adj1=(GtkWidget*)gtk_adjustment_new(max_iteration_limit,1.0,150.0,5.0,1.0,0.0);
2031 						g_signal_connect(G_OBJECT(adj1), "value_changed",
2032 														G_CALLBACK(menubar_save_cb_iteration_limit),NULL);
2033 						scale=gtk_hscale_new(GTK_ADJUSTMENT(adj1));
2034 						gtk_scale_set_digits(GTK_SCALE(scale),0);
2035 						gtk_box_pack_start(GTK_BOX(box2),scale,TRUE,TRUE,0);
2036 						gtk_widget_show(scale);
2037 						gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
2038 						gtk_widget_show(box2);
2039 
2040 
2041             /* text entry for k0 */
2042 						box2=gtk_hbox_new(FALSE,10);
2043 						gtk_container_set_border_width(GTK_CONTAINER(box2),10);
2044 						label=gtk_label_new("Wave Frequency k0:");
2045 						gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
2046 						gtk_widget_show(label);
2047 
2048             textbox=gtk_entry_new();
2049             g_snprintf(buf,20,"%5.2lf",global_wave_k0);
2050             gtk_entry_set_text(GTK_ENTRY(textbox),buf);
2051 						gtk_box_pack_start(GTK_BOX(box2),textbox,TRUE,TRUE,0);
2052             gtk_widget_show(textbox);
2053 						g_signal_connect(G_OBJECT(textbox), "changed",
2054 														G_CALLBACK(menubar_save_cb_wave_k0),NULL);
2055 						gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
2056             gtk_widget_show(box2);
2057 
2058             /* text entry for beta*/
2059 						box2=gtk_hbox_new(FALSE,10);
2060 						gtk_container_set_border_width(GTK_CONTAINER(box2),10);
2061 						label=gtk_label_new("Wave Propagation beta:");
2062 						gtk_box_pack_start(GTK_BOX(box2),label,FALSE,FALSE,0);
2063 						gtk_widget_show(label);
2064 
2065             textbox=gtk_entry_new();
2066             g_snprintf(buf,20,"%5.2lf",global_wave_beta);
2067             gtk_entry_set_text(GTK_ENTRY(textbox),buf);
2068 						gtk_box_pack_start(GTK_BOX(box2),textbox,TRUE,TRUE,0);
2069             gtk_widget_show(textbox);
2070 						g_signal_connect(G_OBJECT(textbox), "changed",
2071 														G_CALLBACK(menubar_save_cb_wave_beta),NULL);
2072 						gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
2073             gtk_widget_show(box2);
2074 
2075 						/* seperator and buttons */
2076 						separator=gtk_hseparator_new();
2077 						gtk_box_pack_start(GTK_BOX(box1),separator,FALSE,TRUE,0);
2078 						gtk_widget_show(separator);
2079 
2080 						box2=gtk_hbox_new(FALSE,10);
2081 						gtk_container_set_border_width(GTK_CONTAINER(box2),10);
2082 						gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,TRUE,0);
2083 						gtk_widget_show(box2);
2084 
2085 						button=gtk_button_new_with_label("OK");
2086 						g_signal_connect(G_OBJECT(button),"clicked",
2087 														G_CALLBACK(menubar_save_cb_update_values),
2088 														window);
2089 
2090 						gtk_box_pack_start(GTK_BOX(box2),button,TRUE,TRUE,0);
2091 						GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT);
2092 						gtk_widget_grab_default(button);
2093 						gtk_widget_show(button);
2094 
2095             button=gtk_button_new_with_label("Cancel");
2096 						g_signal_connect (G_OBJECT (button), "clicked",
2097 														     G_CALLBACK(menubar_save_cb_close_window),
2098 																window);
2099 
2100 						gtk_box_pack_start(GTK_BOX(box2),button,TRUE,TRUE,0);
2101 						gtk_widget_show(button);
2102 
2103 						gtk_widget_show(window);
2104 
2105 }
2106 
2107 static void
menubar_plot_toggle_option(gpointer data)2108 menubar_plot_toggle_option(gpointer data)
2109 {
2110 	int opt;
2111 	opt=GPOINTER_TO_INT(data);
2112 
2113 #ifdef DEBUG
2114 	printf ("menubar_plot_option: %d\n",opt);
2115 #endif
2116   switch (opt) {
2117 		case PLOT_MESH:
2118 				plot_mesh =(plot_mesh?0:1);
2119         break;
2120    case PLOT_CONT:
2121 				plot_cont =(plot_cont?0:1);
2122         break;
2123    case PLOT_FILL:
2124 				plot_fill=(plot_fill?0:1);
2125         break;
2126    case PLOT_GRAD:
2127 				plot_grad=(plot_grad?0:1);
2128         break;
2129    default:
2130 				break;
2131 	}
2132 
2133 }
2134 
2135 static void
menubar_plot_display_legend_window(gchar * data)2136 menubar_plot_display_legend_window( gchar *data )
2137 {
2138 #ifdef DEBUG
2139 	printf ("menubar_plot_display_legend: %s\n", data);
2140 #endif
2141  display_legend_window();
2142 
2143 }
2144 
2145 static void
menubar_plot_draw_mode(gpointer data)2146 menubar_plot_draw_mode(gpointer data) {
2147   drawing_mode_flag=GPOINTER_TO_INT(data);
2148 #ifdef DEBUG
2149   printf("switch_drawing_mode: mode=%d IN=%d OUT=%d\n",drawing_mode_flag,DRAW_INPUT,DRAW_OUTPUT);
2150 #endif
2151  update_status_bar("Redrawing...");
2152 }
2153 
2154 /* global color to remember background color */
2155 static GdkColor bg_color;
2156 static GdkColor tmp_bg_color;
2157 static void
change_bg_color(GtkWidget * widget,GtkColorSelection * colorsel)2158 change_bg_color(GtkWidget *widget, GtkColorSelection *colorsel) {
2159   gtk_color_selection_get_current_color(colorsel,&tmp_bg_color);
2160 }
2161 
2162 static void
menubar_plot_preference_change_bg(GtkWidget * widget,gpointer data)2163 menubar_plot_preference_change_bg(GtkWidget *widget, gpointer data) {
2164   GtkWidget *w=GTK_WIDGET(data);
2165   /* copy temp color to actual */
2166   bg_color.red=tmp_bg_color.red;
2167   bg_color.blue=tmp_bg_color.blue;
2168   bg_color.green=tmp_bg_color.green;
2169 
2170   /* change GTK color to OpenGL color */
2171   gl_bg_color[0]=(float)bg_color.red/65536;
2172   gl_bg_color[1]=(float)bg_color.green/65536;
2173   gl_bg_color[2]=(float)bg_color.blue/65536;
2174 
2175   /* send redraw to drawing area (or main window w)*/
2176   if(w != NULL)
2177    gdk_window_invalidate_rect(w->window, &w->allocation ,TRUE);
2178 
2179 }
2180 
2181 static void
menubar_plot_preferences(gpointer data)2182 menubar_plot_preferences(gpointer data) {
2183   GtkWidget *colorseldlg;
2184   GtkColorSelection *colorsel;
2185 
2186   colorseldlg=gtk_color_selection_dialog_new("change background color");
2187   colorsel=GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(colorseldlg)->colorsel);
2188   /*  set intial color value */
2189   gtk_color_selection_set_previous_color(colorsel,&bg_color);
2190   gtk_color_selection_set_current_color(colorsel,&bg_color);
2191 
2192   /* handle changes in color */
2193   g_signal_connect(G_OBJECT(colorsel),"color_changed",
2194     G_CALLBACK(change_bg_color),(gpointer)colorsel);
2195 
2196  /* change actual background color if OK button is pressed */
2197   g_signal_connect(GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(colorseldlg)->ok_button),
2198 	  "clicked",
2199 	  G_CALLBACK(menubar_plot_preference_change_bg),
2200 	  (gpointer)data);
2201 
2202   /* callbacks for proper closing of dialog */
2203   g_signal_connect_swapped(GTK_OBJECT(colorseldlg), "delete_event",
2204    G_CALLBACK(gtk_widget_destroy),(gpointer)colorseldlg);
2205 
2206    g_signal_connect_swapped(GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(colorseldlg)->ok_button),
2207     "clicked",
2208      G_CALLBACK(gtk_widget_destroy),
2209      (gpointer)colorseldlg);
2210    g_signal_connect_swapped(GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(colorseldlg)->cancel_button),
2211     "clicked",
2212     G_CALLBACK(gtk_widget_destroy),
2213     (gpointer)colorseldlg);
2214    /* display */
2215    gtk_widget_show(colorseldlg);
2216 
2217 }
2218 
2219 static void
menubar_help_about_problem(void)2220 menubar_help_about_problem( void )
2221 {
2222  GtkWidget *window, *vbox, *hbox, *llabel, *rlabel, *button;
2223  gchar buf[256];
2224 #ifdef DEBUG
2225 	printf ("menubar_help_about problem:\n");
2226 #endif
2227   window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
2228   g_signal_connect_swapped(GTK_OBJECT(window),"delete_event",
2229 	G_CALLBACK(gtk_widget_destroy),(gpointer)window);
2230 
2231 
2232   gtk_window_set_title(GTK_WINDOW(window),"About Problem");
2233 
2234   vbox=gtk_vbox_new(FALSE,0);
2235   gtk_container_add(GTK_CONTAINER(window),vbox);
2236   gtk_container_set_border_width(GTK_CONTAINER(vbox),10);
2237   gtk_widget_show(vbox);
2238 
2239   hbox=gtk_hbox_new(FALSE,0);
2240   gtk_container_set_border_width(GTK_CONTAINER(hbox),0);
2241   gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,FALSE,0);
2242   gtk_widget_show(hbox);
2243   llabel=gtk_label_new("");
2244 	gtk_box_pack_start(GTK_BOX(hbox),llabel,FALSE,FALSE,0);
2245 	gtk_widget_show(llabel);
2246   gtk_label_set_justify(GTK_LABEL(llabel),GTK_JUSTIFY_CENTER);
2247   g_snprintf(buf, 256, "<u>Mesh</u>");
2248   gtk_label_set_markup(GTK_LABEL(llabel),buf);
2249 
2250   hbox=gtk_hbox_new(FALSE,0);
2251   gtk_container_set_border_width(GTK_CONTAINER(hbox),0);
2252   gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,FALSE,0);
2253   gtk_widget_show(hbox);
2254   llabel=gtk_label_new("");
2255 	gtk_box_pack_start(GTK_BOX(hbox),llabel,FALSE,FALSE,0);
2256 	gtk_widget_show(llabel);
2257   gtk_label_set_justify(GTK_LABEL(llabel),GTK_JUSTIFY_CENTER);
2258   g_snprintf(buf, 256, "Points:");
2259   gtk_label_set_markup(GTK_LABEL(llabel),buf);
2260   rlabel=gtk_label_new("");
2261 	gtk_box_pack_start(GTK_BOX(hbox),rlabel,FALSE,FALSE,0);
2262 	gtk_widget_show(rlabel);
2263   gtk_label_set_justify(GTK_LABEL(rlabel),GTK_JUSTIFY_CENTER);
2264   g_snprintf(buf, 256, "<span foreground=\"blue\">"MIF"</span>",M.count);
2265   gtk_label_set_markup(GTK_LABEL(rlabel),buf);
2266 
2267   hbox=gtk_hbox_new(FALSE,0);
2268   gtk_container_set_border_width(GTK_CONTAINER(hbox),0);
2269   gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,FALSE,0);
2270   gtk_widget_show(hbox);
2271   llabel=gtk_label_new("");
2272 	gtk_box_pack_start(GTK_BOX(hbox),llabel,FALSE,FALSE,0);
2273 	gtk_widget_show(llabel);
2274   gtk_label_set_justify(GTK_LABEL(llabel),GTK_JUSTIFY_CENTER);
2275   g_snprintf(buf, 256, "Triangles:");
2276   gtk_label_set_markup(GTK_LABEL(llabel),buf);
2277   rlabel=gtk_label_new("");
2278 	gtk_box_pack_start(GTK_BOX(hbox),rlabel,FALSE,FALSE,0);
2279 	gtk_widget_show(rlabel);
2280   gtk_label_set_justify(GTK_LABEL(rlabel),GTK_JUSTIFY_CENTER);
2281   g_snprintf(buf, 256, "<span foreground=\"blue\">"MIF"</span>",ntriangles);
2282   gtk_label_set_markup(GTK_LABEL(rlabel),buf);
2283 
2284 
2285   hbox=gtk_hbox_new(FALSE,0);
2286   gtk_container_set_border_width(GTK_CONTAINER(hbox),0);
2287   gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,FALSE,0);
2288   gtk_widget_show(hbox);
2289   llabel=gtk_label_new("");
2290 	gtk_box_pack_start(GTK_BOX(hbox),llabel,FALSE,FALSE,0);
2291 	gtk_widget_show(llabel);
2292   gtk_label_set_justify(GTK_LABEL(llabel),GTK_JUSTIFY_CENTER);
2293   g_snprintf(buf, 256, "<u>Input</u>");
2294   gtk_label_set_markup(GTK_LABEL(llabel),buf);
2295 
2296 
2297   hbox=gtk_hbox_new(FALSE,0);
2298   gtk_container_set_border_width(GTK_CONTAINER(hbox),0);
2299   gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,FALSE,0);
2300   gtk_widget_show(hbox);
2301   llabel=gtk_label_new("");
2302 	gtk_box_pack_start(GTK_BOX(hbox),llabel,FALSE,FALSE,0);
2303 	gtk_widget_show(llabel);
2304   gtk_label_set_justify(GTK_LABEL(llabel),GTK_JUSTIFY_CENTER);
2305   g_snprintf(buf, 256, "Filename:");
2306   gtk_label_set_markup(GTK_LABEL(llabel),buf);
2307   rlabel=gtk_label_new("");
2308 	gtk_box_pack_start(GTK_BOX(hbox),rlabel,FALSE,FALSE,0);
2309 	gtk_widget_show(rlabel);
2310   gtk_label_set_justify(GTK_LABEL(rlabel),GTK_JUSTIFY_CENTER);
2311   if(input_cord_filename){
2312    g_snprintf(buf, 256, "<span foreground=\"blue\">%s</span>",input_cord_filename);
2313   } else {
2314    g_snprintf(buf, 256, "<span foreground=\"blue\">None</span>");
2315   }
2316   gtk_label_set_markup(GTK_LABEL(rlabel),buf);
2317 
2318   hbox=gtk_hbox_new(FALSE,0);
2319   gtk_container_set_border_width(GTK_CONTAINER(hbox),0);
2320   gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,FALSE,0);
2321   gtk_widget_show(hbox);
2322   llabel=gtk_label_new("");
2323 	gtk_box_pack_start(GTK_BOX(hbox),llabel,FALSE,FALSE,0);
2324 	gtk_widget_show(llabel);
2325   gtk_label_set_justify(GTK_LABEL(llabel),GTK_JUSTIFY_CENTER);
2326   g_snprintf(buf, 256, "Edges:");
2327   gtk_label_set_markup(GTK_LABEL(llabel),buf);
2328   rlabel=gtk_label_new("");
2329 	gtk_box_pack_start(GTK_BOX(hbox),rlabel,FALSE,FALSE,0);
2330 	gtk_widget_show(rlabel);
2331   gtk_label_set_justify(GTK_LABEL(rlabel),GTK_JUSTIFY_CENTER);
2332   g_snprintf(buf, 256, "<span foreground=\"blue\">%d</span>",nedges);
2333   gtk_label_set_markup(GTK_LABEL(rlabel),buf);
2334 
2335   hbox=gtk_hbox_new(FALSE,0);
2336   gtk_container_set_border_width(GTK_CONTAINER(hbox),0);
2337   gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,FALSE,0);
2338   gtk_widget_show(hbox);
2339   llabel=gtk_label_new("");
2340 	gtk_box_pack_start(GTK_BOX(hbox),llabel,FALSE,FALSE,0);
2341 	gtk_widget_show(llabel);
2342   gtk_label_set_justify(GTK_LABEL(llabel),GTK_JUSTIFY_CENTER);
2343   g_snprintf(buf, 256, "Equation:");
2344   gtk_label_set_markup(GTK_LABEL(llabel),buf);
2345   rlabel=gtk_label_new("");
2346 	gtk_box_pack_start(GTK_BOX(hbox),rlabel,FALSE,FALSE,0);
2347 	gtk_widget_show(rlabel);
2348   gtk_label_set_justify(GTK_LABEL(rlabel),GTK_JUSTIFY_CENTER);
2349   switch (solve_equation) {
2350    case POISSON:
2351    g_snprintf(buf, 256, "<span foreground=\"blue\">Poisson</span>");
2352    break;
2353    case POISSON_SPARSE:
2354    g_snprintf(buf, 256, "<span foreground=\"blue\">Poisson with sparse storage</span>");
2355    break;
2356    case HELMHOLTZ:
2357    g_snprintf(buf, 256, "<span foreground=\"blue\">Homogeneous Helmholtz</span>");
2358    break;
2359    case HELMHOLTZ_INHOMO:
2360    g_snprintf(buf, 256, "<span foreground=\"blue\">Inhomogeneous Helmholtz</span>");
2361    break;
2362    case HELMHOLTZ_FREQ:
2363    g_snprintf(buf, 256, "<span foreground=\"blue\">Inhomogeneous Helmholtz, find cutoff</span>");
2364    break;
2365    case HELMHOLTZ_BETA:
2366    g_snprintf(buf, 256, "<span foreground=\"blue\">Inhomogeneous Helmholtz, find propagation const.</span>");
2367    break;
2368    default:
2369    g_snprintf(buf, 256, "<span foreground=\"blue\">Unknown</span>");
2370   }
2371   gtk_label_set_markup(GTK_LABEL(rlabel),buf);
2372 
2373 
2374   button=gtk_button_new_with_label("OK");
2375   g_signal_connect_swapped(G_OBJECT(button),"clicked",G_CALLBACK(gtk_widget_destroy), G_OBJECT(window));
2376   gtk_box_pack_start(GTK_BOX(vbox),button,TRUE,FALSE,0);
2377   gtk_widget_show(button);
2378 
2379   gtk_widget_show(window);
2380 }
2381 
2382 static void
menubar_help_about_responce(void)2383 menubar_help_about_responce( void )
2384 {
2385  GtkWidget *window, *box, *label,*button;
2386  gchar buf[1024];
2387 #ifdef DEBUG
2388 	printf ("menubar_help_about:\n");
2389 #endif
2390   window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
2391   g_signal_connect_swapped(GTK_OBJECT(window),"delete_event",
2392 	G_CALLBACK(gtk_widget_destroy),(gpointer)window);
2393 
2394 
2395   gtk_window_set_title(GTK_WINDOW(window),"About pdnMesh");
2396 
2397   box=gtk_vbox_new(FALSE,0);
2398   gtk_container_add(GTK_CONTAINER(window),box);
2399   gtk_container_set_border_width(GTK_CONTAINER(box),10);
2400   gtk_widget_show(box);
2401 
2402   label=gtk_label_new("");
2403 	gtk_box_pack_start(GTK_BOX(box),label,FALSE,FALSE,0);
2404 	gtk_widget_show(label);
2405   gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_CENTER);
2406   g_snprintf(buf, 1024, "<u>"PACKAGE" "VERSION"</u>\nCopyright (C) 2001-2005 Sarod Yatawatta\n"PACKAGE" comes with ABSOLUTELY NO WARRANTY.\nThis is Free Software, and you are welcome to redistribute\nit under conditions given by GNU GENERAL PUBLIC LICENSE.\nFor more information visit <u>http://pdnmesh.sf.net/</u>\n Please report bugs to <u>pdnmesh-bugs@lists.sourceforge.net</u>\n");
2407   gtk_label_set_markup(GTK_LABEL(label),buf);
2408 
2409   button=gtk_button_new_with_label("OK");
2410   g_signal_connect_swapped(G_OBJECT(button),"clicked",G_CALLBACK(gtk_widget_destroy), G_OBJECT(window));
2411   gtk_box_pack_start(GTK_BOX(box),button,TRUE,FALSE,0);
2412   gtk_widget_show(button);
2413 
2414   gtk_widget_show(window);
2415 }
2416 
2417 
2418 /* callbacks for toolbar */
2419 static void
toolbar_plot_toggle_option_contours(GtkWidget * widget,gpointer data)2420 toolbar_plot_toggle_option_contours(GtkWidget *widget, gpointer data)
2421 {
2422   GtkWidget *w,*menu;
2423   int i; /* remember value of plot_cont */
2424   dual_widget *WW=(dual_widget *)data;
2425   i=plot_cont;
2426   if(WW!=NULL) {
2427 	 w=GTK_WIDGET(WW->w1);
2428    menu=GTK_WIDGET(WW->w2);
2429 #ifdef DEBUG
2430   printf("toolbar: starting flag=%d\n",plot_cont);
2431 #endif
2432   if ( plot_cont ==0 ) {
2433 #ifdef DEBUG
2434     printf("toolbar: menu_item: setting active\n");
2435 #endif
2436 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu),TRUE);
2437 	} else {
2438 #ifdef DEBUG
2439     printf("toolbar: menu_item: unsetting active\n");
2440 #endif
2441 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu),FALSE);
2442   }
2443   /* we have to use remembered value because when we toggle menu,
2444    plot_cont will change automatically */
2445   plot_cont =(i?0:1);
2446 #ifdef DEBUG
2447   printf("toolbar: just set to flag=%d\n",plot_cont);
2448 #endif
2449   if(w != NULL)
2450    gdk_window_invalidate_rect(w->window, &w->allocation ,TRUE);
2451 
2452 #ifdef DEBUG
2453    printf("toolbar: ending flag=%d\n",plot_cont);
2454 #endif
2455   }
2456 
2457 #ifdef DEBUG
2458   printf("toolbar: callback 1\n");
2459 #endif
2460 }
2461 
2462 static void
toolbar_plot_toggle_option_fill(GtkWidget * widget,gpointer data)2463 toolbar_plot_toggle_option_fill(GtkWidget *widget, gpointer data)
2464 {
2465   GtkWidget *w,*menu;
2466   int i; /* remember value of plot_fill*/
2467   dual_widget *WW=(dual_widget *)data;
2468   i=plot_fill;
2469   if(WW!=NULL) {
2470 	 w=GTK_WIDGET(WW->w1);
2471    menu=GTK_WIDGET(WW->w2);
2472 #ifdef DEBUG
2473   printf("toolbar: starting flag=%d\n",plot_fill);
2474 #endif
2475   if ( plot_fill==0 ) {
2476 #ifdef DEBUG
2477     printf("toolbar: menu_item: setting active\n");
2478 #endif
2479 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu),TRUE);
2480 	} else {
2481 #ifdef DEBUG
2482     printf("toolbar: menu_item: unsetting active\n");
2483 #endif
2484 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu),FALSE);
2485   }
2486   /* we have to use remembered value because when we toggle menu,
2487    plot_fill will change automatically */
2488   plot_fill=(i?0:1);
2489 #ifdef DEBUG
2490   printf("toolbar: just set to flag=%d\n",plot_fill);
2491 #endif
2492   if(w != NULL)
2493    gdk_window_invalidate_rect(w->window, &w->allocation ,TRUE);
2494 
2495 #ifdef DEBUG
2496    printf("toolbar: ending flag=%d\n",plot_fill);
2497 #endif
2498   }
2499 
2500 #ifdef DEBUG
2501   printf("toolbar: callback 1\n");
2502 #endif
2503 }
2504 
2505 static void
toolbar_plot_toggle_option_mesh(GtkWidget * widget,gpointer data)2506 toolbar_plot_toggle_option_mesh(GtkWidget *widget, gpointer data)
2507 {
2508   GtkWidget *w,*menu;
2509   int i; /* remember value of plot_mesh*/
2510   dual_widget *WW=(dual_widget *)data;
2511   i=plot_mesh;
2512   if(WW!=NULL) {
2513 	 w=GTK_WIDGET(WW->w1);
2514    menu=GTK_WIDGET(WW->w2);
2515 #ifdef DEBUG
2516   printf("toolbar: starting flag=%d\n",plot_mesh);
2517 #endif
2518   if ( plot_mesh==0 ) {
2519 #ifdef DEBUG
2520     printf("toolbar: menu_item: setting active\n");
2521 #endif
2522 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu),TRUE);
2523 	} else {
2524 #ifdef DEBUG
2525     printf("toolbar: menu_item: unsetting active\n");
2526 #endif
2527 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu),FALSE);
2528   }
2529   /* we have to use remembered value because when we toggle menu,
2530    plot_mesh will change automatically */
2531   plot_mesh=(i?0:1);
2532 #ifdef DEBUG
2533   printf("toolbar: just set to flag=%d\n",plot_mesh);
2534 #endif
2535   if(w != NULL)
2536    gdk_window_invalidate_rect(w->window, &w->allocation ,TRUE);
2537 
2538 #ifdef DEBUG
2539    printf("toolbar: ending flag=%d\n",plot_mesh);
2540 #endif
2541   }
2542 
2543 #ifdef DEBUG
2544   printf("toolbar: callback 1\n");
2545 #endif
2546 }
2547 
2548 static void
toolbar_plot_toggle_option_gradient(GtkWidget * widget,gpointer data)2549 toolbar_plot_toggle_option_gradient(GtkWidget *widget, gpointer data)
2550 {
2551   GtkWidget *w,*menu;
2552   int i; /* remember value of plot_mesh*/
2553   dual_widget *WW=(dual_widget *)data;
2554   i=plot_grad;
2555   if(WW!=NULL) {
2556 	 w=GTK_WIDGET(WW->w1);
2557    menu=GTK_WIDGET(WW->w2);
2558 #ifdef DEBUG
2559   printf("toolbar: starting flag=%d\n",plot_grad);
2560 #endif
2561   if ( plot_grad==0 ) {
2562 #ifdef DEBUG
2563     printf("toolbar: menu_item: setting active\n");
2564 #endif
2565 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu),TRUE);
2566 	} else {
2567 #ifdef DEBUG
2568     printf("toolbar: menu_item: unsetting active\n");
2569 #endif
2570 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu),FALSE);
2571   }
2572   /* we have to use remembered value because when we toggle menu,
2573    plot_mesh will change automatically */
2574   plot_grad=(i?0:1);
2575 #ifdef DEBUG
2576   printf("toolbar: just set to flag=%d\n",plot_grad);
2577 #endif
2578   if(w != NULL)
2579    gdk_window_invalidate_rect(w->window, &w->allocation ,TRUE);
2580 
2581 #ifdef DEBUG
2582    printf("toolbar: ending flag=%d\n",plot_grad);
2583 #endif
2584   }
2585 
2586 #ifdef DEBUG
2587   printf("toolbar: callback 1\n");
2588 #endif
2589 }
2590 
2591 /* used when degree of freedom of points > 1 */
2592 static void
toolbar_switch_to_next_eigenmode(GtkWidget * widget,gpointer data)2593 toolbar_switch_to_next_eigenmode(GtkWidget *widget,gpointer data)
2594 {
2595 
2596 	GtkWidget *w=GTK_WIDGET(data);
2597  /* switch to next eigenmode */
2598   if (solve_equation== POISSON || solve_equation == POISSON_SPARSE ) {
2599    current_plotting_contour=0;
2600   } else if (solve_equation == HELMHOLTZ ) {
2601    current_plotting_contour++;
2602   if ( current_plotting_contour >=degree_of_freedom )
2603    current_plotting_contour=0;
2604   } else if ((solve_equation == HELMHOLTZ_INHOMO)
2605      || (solve_equation == HELMHOLTZ_FREQ)
2606      || (solve_equation == HELMHOLTZ_BETA)) {
2607    current_plotting_contour++;
2608   if ( current_plotting_contour >=3*degree_of_freedom )
2609    current_plotting_contour=0;
2610   }
2611 
2612 
2613 #ifdef DEBUG
2614   g_print("%s: \" %d th eigenmode\"\n",gtk_widget_get_name(w),current_plotting_contour);
2615 #endif
2616 
2617  gdk_window_invalidate_rect(w->window, &w->allocation,TRUE);
2618  if( global_surf_mesh_window != NULL )
2619  gdk_window_invalidate_rect(global_surf_mesh_window->window, &global_surf_mesh_window->allocation,TRUE);
2620 }
2621 
2622 /************************************/
2623 /* main window creation */
2624 GtkWidget *
create_window(GdkGLConfig * glconfig)2625 create_window (GdkGLConfig *glconfig)
2626 {
2627  GtkWidget *window;
2628  GtkWidget *vbox;
2629  GtkWidget *hbox;
2630  GtkWidget *drawing_area;
2631  GtkWidget *menu;
2632  GtkWidget *bar_menu,*menu_item,*root_menu,*menu_bar;
2633  GtkWidget *handlebox,*toolbar,*iconw,*button;
2634  GtkWidget *menu_item_plot_contour,*menu_item_plot_fill,*menu_item_plot_mesh,
2635            *menu_item_plot_gradient;
2636  GtkWidget *pref_menu_item;
2637  dual_widget *WW;
2638 
2639  gchar buf[128];
2640  GSList *radio_menu_group = NULL;
2641 
2642  /* top level */
2643  window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
2644  gtk_window_set_title(GTK_WINDOW(window),DEFAULT_TITLE);
2645 
2646  gtk_container_set_reallocate_redraws(GTK_CONTAINER(window),FALSE);
2647 
2648  g_signal_connect(G_OBJECT(window), "delete_event",
2649                   G_CALLBACK(gtk_main_quit),NULL);
2650 
2651 
2652 
2653   /* vbox */
2654 	vbox=gtk_vbox_new(FALSE,0);
2655 	gtk_container_add(GTK_CONTAINER(window),vbox);
2656 	gtk_widget_show(vbox);
2657 
2658 	/* menu bar */
2659   menu_bar=gtk_menu_bar_new();
2660 	gtk_box_pack_start(GTK_BOX(vbox),menu_bar,FALSE,FALSE,2);
2661 	gtk_widget_show(menu_bar);
2662 
2663   /***** start of file menu **********/
2664   /* File menu bar and assorted functions */
2665   bar_menu=gtk_menu_new();
2666 	/* menu items */
2667 	menu_item=gtk_menu_item_new_with_label("Open...");
2668 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2669 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2670 									G_CALLBACK(menubar_file_open_response),
2671 									(gpointer)menu_item);
2672 	gtk_widget_show(menu_item);
2673 
2674   menu_item=gtk_menu_item_new_with_label("Import DXF...");
2675 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2676 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2677 									G_CALLBACK(menubar_file_import_response),
2678 									(gpointer)g_strdup("Import"));
2679 	gtk_widget_show(menu_item);
2680 
2681   menu_item=gtk_menu_item_new_with_label("Save...");
2682 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2683 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2684 									G_CALLBACK(menubar_file_save_response),
2685 									(gpointer)menu_item);
2686 	gtk_widget_show(menu_item);
2687 
2688   menu_item=gtk_menu_item_new_with_label("Quit");
2689 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2690 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2691 									G_CALLBACK(gtk_main_quit),
2692 									NULL);
2693 	gtk_widget_show(menu_item);
2694 
2695 	/* File menu */
2696 	root_menu=gtk_menu_item_new_with_label("File");
2697 	gtk_widget_show(root_menu);
2698 	/* attach menu to root menu */
2699 	gtk_menu_item_set_submenu(GTK_MENU_ITEM(root_menu),bar_menu);
2700 
2701 	/* attach root menu to menu bar */
2702   gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar),root_menu);
2703 
2704   /***** end of file menu **********/
2705 
2706 
2707   /***** start of plot menu **********/
2708   /* File menu bar and assorted functions */
2709   bar_menu=gtk_menu_new();
2710 	/* menu items */
2711 	menu_item_plot_mesh=gtk_check_menu_item_new_with_label("Mesh");
2712 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item_plot_mesh);
2713   if ( plot_mesh ) {
2714 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item_plot_mesh),TRUE);
2715 	}
2716 	g_signal_connect_swapped(G_OBJECT(menu_item_plot_mesh),"toggled",
2717 									G_CALLBACK(menubar_plot_toggle_option),
2718 							    GINT_TO_POINTER(PLOT_MESH));
2719 	gtk_widget_show(menu_item_plot_mesh);
2720 
2721   menu_item_plot_contour=gtk_check_menu_item_new_with_label("Contours");
2722 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item_plot_contour);
2723   if ( plot_cont ) {
2724 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item_plot_contour),TRUE);
2725 	}
2726 	g_signal_connect_swapped(G_OBJECT(menu_item_plot_contour),"toggled",
2727 									G_CALLBACK(menubar_plot_toggle_option),
2728 							    GINT_TO_POINTER(PLOT_CONT));
2729 	gtk_widget_show(menu_item_plot_contour);
2730 
2731   menu_item_plot_fill=gtk_check_menu_item_new_with_label("ColourFill");
2732 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item_plot_fill);
2733   if ( plot_fill ) {
2734 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item_plot_fill),TRUE);
2735 	}
2736 	g_signal_connect_swapped(G_OBJECT(menu_item_plot_fill),"toggled",
2737 									G_CALLBACK(menubar_plot_toggle_option),
2738 							    GINT_TO_POINTER(PLOT_FILL));
2739 	gtk_widget_show(menu_item_plot_fill);
2740 
2741   menu_item_plot_gradient=gtk_check_menu_item_new_with_label("Gradient");
2742 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item_plot_gradient);
2743   if ( plot_grad ) {
2744 		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item_plot_gradient),TRUE);
2745 	}
2746 	g_signal_connect_swapped(G_OBJECT(menu_item_plot_gradient),"toggled",
2747 									G_CALLBACK(menubar_plot_toggle_option),
2748 							    GINT_TO_POINTER(PLOT_GRAD));
2749 	gtk_widget_show(menu_item_plot_gradient);
2750 
2751 
2752   menu_item=gtk_menu_item_new_with_label("Legend");
2753 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2754 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2755 									G_CALLBACK(menubar_plot_display_legend_window),
2756 									(gpointer)g_strdup("Options"));
2757 	gtk_widget_show(menu_item);
2758 
2759   menu_item = gtk_radio_menu_item_new_with_label(radio_menu_group, "Draw Output");
2760   radio_menu_group= gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menu_item));
2761   gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM (menu_item), TRUE);
2762 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2763 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2764 									G_CALLBACK(menubar_plot_draw_mode),
2765 									(gpointer)DRAW_OUTPUT);
2766 	gtk_widget_show(menu_item);
2767 
2768   menu_item = gtk_radio_menu_item_new_with_label(radio_menu_group, "Draw Input");
2769 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2770 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2771 									G_CALLBACK(menubar_plot_draw_mode),
2772 									(gpointer)DRAW_INPUT);
2773 	gtk_widget_show(menu_item);
2774 
2775 
2776   pref_menu_item=gtk_menu_item_new_with_label("Preferences...");
2777 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),pref_menu_item);
2778   /* See section (1) */
2779 /*	g_signal_connect_swapped(G_OBJECT(pref_menu_item),"activate",
2780 									G_CALLBACK(menubar_plot_preferences),
2781 									(gpointer)drawing_area); */
2782 	gtk_widget_show(pref_menu_item);
2783 
2784 	root_menu=gtk_menu_item_new_with_label("View");
2785 	gtk_widget_show(root_menu);
2786 	/* attach menu to root menu */
2787 	gtk_menu_item_set_submenu(GTK_MENU_ITEM(root_menu),bar_menu);
2788 
2789 	/* attach root menu to menu bar */
2790   gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar),root_menu);
2791 
2792   /***** end of plot menu **********/
2793 
2794   /***** start of solve menu **********/
2795   /* File menu bar and assorted functions */
2796   bar_menu=gtk_menu_new();
2797 	/* menu items */
2798   menu_item=gtk_menu_item_new_with_label("Solve Problem");
2799 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2800 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2801 									G_CALLBACK(menubar_solve_only_response),
2802 									(gpointer)menu_item);
2803 	gtk_widget_show(menu_item);
2804 
2805 	menu_item=gtk_menu_item_new_with_label("Generate Mesh");
2806 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2807 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2808 									G_CALLBACK(menubar_solve_mesh_response),
2809 									(gpointer)g_strdup("Mesh"));
2810 	gtk_widget_show(menu_item);
2811 
2812   menu_item=gtk_menu_item_new_with_label("Mesh+Solve Iteratively");
2813 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2814 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2815 									G_CALLBACK(menubar_solve_iterative_response),
2816 									(gpointer)g_strdup("Solve iter"));
2817 	gtk_widget_show(menu_item);
2818   menu_item=gtk_menu_item_new_with_label("Integrate..");
2819 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2820 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2821 									G_CALLBACK(menubar_solve_integrate_responce),
2822 									(gpointer)g_strdup("Intergate"));
2823 	gtk_widget_show(menu_item);
2824 
2825   menu_item=gtk_check_menu_item_new_with_label("Edit Material...");
2826 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2827 	g_signal_connect(G_OBJECT(menu_item),"activate",
2828 									G_CALLBACK(menubar_solve_materials_responce),
2829 									(gpointer)menu_item);
2830 	gtk_widget_show(menu_item);
2831 
2832 
2833 
2834   menu_item=gtk_menu_item_new_with_label("Change Options...");
2835 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2836 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2837 									G_CALLBACK(menubar_solve_options_response),
2838 									(gpointer)g_strdup("Options"));
2839 	gtk_widget_show(menu_item);
2840 
2841 
2842 	root_menu=gtk_menu_item_new_with_label("Solve");
2843 	gtk_widget_show(root_menu);
2844 	/* attach menu to root menu */
2845 	gtk_menu_item_set_submenu(GTK_MENU_ITEM(root_menu),bar_menu);
2846 
2847 	/* attach root menu to menu bar */
2848   gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar),root_menu);
2849 
2850   /***** end of solve menu **********/
2851 
2852  /****** help menu *******************/
2853   bar_menu=gtk_menu_new();
2854 	/* menu items */
2855 	menu_item=gtk_menu_item_new_with_label("About Problem...");
2856 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2857 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2858 									G_CALLBACK(menubar_help_about_problem),
2859 									NULL);
2860 	gtk_widget_show(menu_item);
2861 
2862 
2863 	menu_item=gtk_menu_item_new_with_label("About pdnMesh...");
2864 	gtk_menu_shell_append(GTK_MENU_SHELL(bar_menu),menu_item);
2865 	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",
2866 									G_CALLBACK(menubar_help_about_responce),
2867 									NULL);
2868 	gtk_widget_show(menu_item);
2869 
2870 	root_menu=gtk_menu_item_new_with_label("Help");
2871 	gtk_widget_show(root_menu);
2872 	/* attach menu to root menu */
2873 	gtk_menu_item_set_submenu(GTK_MENU_ITEM(root_menu),bar_menu);
2874 
2875 	/* attach root menu to menu bar */
2876   gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar),root_menu);
2877 
2878  /********* end help menu ****************/
2879  /********** tool bar ******************/
2880   handlebox=gtk_handle_box_new();
2881   gtk_box_pack_start(GTK_BOX(vbox),handlebox,FALSE,FALSE,0);
2882 
2883   toolbar=gtk_toolbar_new();
2884   gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar),GTK_ORIENTATION_HORIZONTAL);
2885   gtk_toolbar_set_style(GTK_TOOLBAR(toolbar),GTK_TOOLBAR_ICONS);
2886   gtk_container_add(GTK_CONTAINER(handlebox),toolbar);
2887 
2888   iconw=gtk_image_new_from_file(PIXMAPS_DIR"/open.xpm");
2889   button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
2890                           "Open", /* button label */
2891                            "Open File...", /* button tooltip */
2892                            "Private", /* tooltip private info */
2893                            iconw, /* icon */
2894                            GTK_SIGNAL_FUNC(menubar_file_open_response), /* callback */
2895                            (gpointer)toolbar);
2896   iconw=gtk_image_new_from_file(PIXMAPS_DIR"/save.xpm");
2897   button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
2898                           "Save", /* button label */
2899                            "Save As...", /* button tooltip */
2900                            "Private", /* tooltip private info */
2901                            iconw, /* icon */
2902                            GTK_SIGNAL_FUNC(menubar_file_save_response), /* callback */
2903                            (gpointer)toolbar);
2904 
2905   gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
2906 
2907   iconw=gtk_image_new_from_file(PIXMAPS_DIR"/zoom_window.xpm");
2908   button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
2909                           "Zoom Window", /* button label */
2910                            "Zoom Window", /* button tooltip */
2911                            "Private", /* tooltip private info */
2912                            iconw, /* icon */
2913                            GTK_SIGNAL_FUNC(switch_to_zoom_start), /* callback */
2914                            (gpointer)window);
2915   iconw=gtk_image_new_from_file(PIXMAPS_DIR"/zoom_back.xpm");
2916   button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
2917                           "Zoom Back", /* button label */
2918                            "Zoom Back", /* button tooltip */
2919                            "Private", /* tooltip private info */
2920                            iconw, /* icon */
2921                            GTK_SIGNAL_FUNC(switch_to_zoom_back_button), /* callback */
2922                            (gpointer)window);
2923   iconw=gtk_image_new_from_file(PIXMAPS_DIR"/zoom_all.xpm");
2924   button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
2925                           "Zoom All", /* button label */
2926                            "Zoom All", /* button tooltip */
2927                            "Private", /* tooltip private info */
2928                            iconw, /* icon */
2929                            GTK_SIGNAL_FUNC(switch_to_zoom_all_button), /* callback */
2930                            (gpointer)window);
2931 
2932   gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
2933 
2934   iconw=gtk_image_new_from_file(PIXMAPS_DIR"/plot_cont.xpm");
2935   /* allocate memory for WW - NOTE: cannot free this memory inside function */
2936   if((WW=(dual_widget*)malloc(sizeof(dual_widget)))==NULL) {
2937    fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__);
2938    exit(1);
2939   }
2940   WW->w1=window; WW->w2=menu_item_plot_contour;
2941   button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
2942                           "Contours", /* button label */
2943                            "Plot Contours", /* button tooltip */
2944                            "Private", /* tooltip private info */
2945                            iconw, /* icon */
2946                            GTK_SIGNAL_FUNC(toolbar_plot_toggle_option_contours), /* callback */
2947                            (gpointer)WW);
2948   /* allocate memory for WW - NOTE: cannot free this memory inside function */
2949   if((WW=(dual_widget*)malloc(sizeof(dual_widget)))==NULL) {
2950    fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__);
2951    exit(1);
2952   }
2953   WW->w1=window; WW->w2=menu_item_plot_fill;
2954   iconw=gtk_image_new_from_file(PIXMAPS_DIR"/plot_fill.xpm");
2955   button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
2956                           "Fill", /* button label */
2957                            "Plot ColorFill", /* button tooltip */
2958                            "Private", /* tooltip private info */
2959                            iconw, /* icon */
2960                            GTK_SIGNAL_FUNC(toolbar_plot_toggle_option_fill), /* callback */
2961                            (gpointer)WW);
2962   /* allocate memory for WW - NOTE: cannot free this memory inside function */
2963   if((WW=(dual_widget*)malloc(sizeof(dual_widget)))==NULL) {
2964    fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__);
2965    exit(1);
2966   }
2967   WW->w1=window; WW->w2=menu_item_plot_gradient;
2968   iconw=gtk_image_new_from_file(PIXMAPS_DIR"/plot_grad.xpm");
2969   button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
2970                           "Gradient", /* button label */
2971                            "Plot Gradient", /* button tooltip */
2972                            "Private", /* tooltip private info */
2973                            iconw, /* icon */
2974                            GTK_SIGNAL_FUNC(toolbar_plot_toggle_option_gradient), /* callback */
2975                            (gpointer)WW);
2976   /* allocate memory for WW - NOTE: cannot free this memory inside function */
2977   if((WW=(dual_widget*)malloc(sizeof(dual_widget)))==NULL) {
2978    fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__);
2979    exit(1);
2980   }
2981   WW->w1=window; WW->w2=menu_item_plot_mesh;
2982   iconw=gtk_image_new_from_file(PIXMAPS_DIR"/plot_mesh.xpm");
2983   button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
2984                           "Mesh", /* button label */
2985                            "Plot Mesh", /* button tooltip */
2986                            "Private", /* tooltip private info */
2987                            iconw, /* icon */
2988                            GTK_SIGNAL_FUNC(toolbar_plot_toggle_option_mesh), /* callback */
2989                            (gpointer)WW);
2990 
2991   gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
2992   iconw=gtk_image_new_from_file(PIXMAPS_DIR"/next_eigenmode.xpm");
2993   button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
2994                           "Next Eigenmode", /* button label */
2995                            "Switch to next Eigenmode",/* button tooltip */
2996                            "Private", /* tooltip private info */
2997                            iconw, /* icon */
2998                            GTK_SIGNAL_FUNC(toolbar_switch_to_next_eigenmode), /* callback */
2999                            (gpointer)window);
3000 
3001   gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
3002   iconw=gtk_image_new_from_file(PIXMAPS_DIR"/help_about.xpm");
3003   button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
3004                           "About...", /* button label */
3005                            "About...",/* button tooltip */
3006                            "Private", /* tooltip private info */
3007                            iconw, /* icon */
3008                            GTK_SIGNAL_FUNC(menubar_help_about_responce), /* callback */
3009                            NULL);
3010 
3011   gtk_widget_show(toolbar);
3012   gtk_widget_show(handlebox);
3013 
3014  /********** end tool bar **************/
3015  /************status bar ***********************/
3016   handlebox=gtk_handle_box_new();
3017   gtk_box_pack_start(GTK_BOX(vbox),handlebox,FALSE,FALSE,0);
3018 	gtk_widget_show(handlebox);
3019 
3020   /* hbox */
3021   hbox=gtk_hbox_new(FALSE,0);
3022   gtk_container_add(GTK_CONTAINER(handlebox),hbox);
3023   gtk_widget_show(hbox);
3024 
3025   /* label to display coords */
3026   global_status_label=gtk_label_new("x: 0.000 y: 0.000 z: 0.000");
3027   g_snprintf(buf, 128, "x: <span foreground=\"blue\">0.000</span> y: <span foreground=\"blue\">0.000</span> z: <span foreground=\"blue\">0.000</span>");
3028  gtk_label_set_markup(GTK_LABEL(global_status_label),buf);
3029 
3030   gtk_label_set_justify(GTK_LABEL(global_status_label),GTK_JUSTIFY_LEFT);
3031   gtk_box_pack_start(GTK_BOX(hbox),global_status_label,FALSE,TRUE,0);
3032   gtk_widget_show(global_status_label);
3033 
3034   /* label to display eigenvalues and mode */
3035   global_mode_label=gtk_label_new("|");
3036   gtk_label_set_justify(GTK_LABEL(global_mode_label),GTK_JUSTIFY_LEFT);
3037   gtk_box_pack_start(GTK_BOX(hbox),global_mode_label,FALSE,TRUE,0);
3038   gtk_widget_show(global_mode_label);
3039   /************** end status bar *************/
3040 
3041 	/**************** drawing area for output */
3042 	drawing_area=gtk_drawing_area_new();
3043 	gtk_widget_set_size_request(drawing_area,DEFAULT_WIDTH,DEFAULT_HEIGHT);
3044 
3045 	/* set openGL capability */
3046 	gtk_widget_set_gl_capability(drawing_area,
3047 	                 glconfig,
3048 									 NULL,
3049 									 TRUE,
3050 									 GDK_GL_RGBA_TYPE);
3051 	gtk_widget_add_events(drawing_area,
3052              GDK_BUTTON1_MOTION_MASK    |
3053              GDK_BUTTON2_MOTION_MASK    |
3054 	           GDK_POINTER_MOTION_MASK |  /* passive motion of mouse */
3055 						 GDK_BUTTON_PRESS_MASK | /* mouse clicks */
3056 						 GDK_VISIBILITY_NOTIFY_MASK);
3057 
3058 
3059  /* connect signal handlers for drawing area */
3060  g_signal_connect_after(G_OBJECT(drawing_area), "realize",
3061                     G_CALLBACK(realize), NULL);
3062  g_signal_connect(G_OBJECT(drawing_area), "configure_event",
3063                    G_CALLBACK(configure_event), NULL);
3064  g_signal_connect(G_OBJECT(drawing_area), "expose_event",
3065                    G_CALLBACK(expose_event), NULL);
3066  g_signal_connect(G_OBJECT(drawing_area), "button_press_event",
3067                    G_CALLBACK(button_press_event), NULL);
3068  g_signal_connect(G_OBJECT(drawing_area),"motion_notify_event",
3069                    G_CALLBACK(motion_notify_event), NULL);
3070 /* key press event handled by top level window */
3071  g_signal_connect_swapped(G_OBJECT(window),"key_press_event",
3072                    G_CALLBACK(key_press_event),drawing_area);
3073 
3074   /* pack */
3075  /* attach drawing area to notebook */
3076  gtk_box_pack_start(GTK_BOX(vbox),drawing_area,TRUE,TRUE,0);
3077 	gtk_widget_show(drawing_area);
3078 
3079   /**************** additional callbacks related to drawing area */
3080 	g_signal_connect_swapped(G_OBJECT(pref_menu_item),"activate",
3081 									G_CALLBACK(menubar_plot_preferences),
3082 									(gpointer)drawing_area);
3083 
3084 	/**************** popup menu */
3085 	menu=create_popup_menu(drawing_area);
3086 	g_signal_connect_swapped(G_OBJECT(drawing_area), "button_press_event",
3087 	           G_CALLBACK(button_press_event_popup_menu), menu);
3088 
3089 
3090 
3091 	hbox=gtk_hbox_new(FALSE,0);
3092 	gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);
3093 	gtk_widget_show(hbox);
3094 
3095 /* finally, a status bar */
3096  global_status_bar=gtk_label_new(PACKAGE":"VERSION);
3097  gtk_label_set_justify(GTK_LABEL(global_status_bar),GTK_JUSTIFY_LEFT);
3098  gtk_box_pack_start(GTK_BOX (hbox), global_status_bar, FALSE, TRUE, 0);
3099  gtk_widget_show(global_status_bar);
3100 
3101  return(window);
3102 }
3103 
3104 /* openGL framebuffer configuratiion */
3105 GdkGLConfig *
configure_gl(void)3106 configure_gl(void)
3107 {
3108 GdkGLConfig *glconfig;
3109 
3110 /* try double buffered */
3111 glconfig=gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB |
3112            GDK_GL_MODE_DEPTH |
3113 					 GDK_GL_MODE_DOUBLE);
3114 
3115 		if (glconfig==NULL) {
3116 
3117 #ifdef DEBUG
3118 	     g_print("\n connot find double buffered visual, tring single\n");
3119 #endif
3120 			 glconfig=gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB |
3121 			    GDK_GL_MODE_DEPTH);
3122 			 if (glconfig==NULL) {
3123 
3124 #ifdef DEBUG
3125 			   g_print("*** No OpenGL capable visual, quitting\n");
3126 #endif
3127 				 exit(1);
3128 			 }
3129 		}
3130 	return(glconfig);
3131 }
3132 #endif /*WIN32*/
3133