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