1 /*
2 * xnec2c - GTK2-based version of nec2c, the C translation of NEC2
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 /* callback_func.c
20 *
21 * Functions to handle GTK callbacks for xnec2c
22 */
23
24 #include "callback_func.h"
25 #include "shared.h"
26
27 /*-----------------------------------------------------------------------*/
28
29 /* Save_Pixmap()
30 *
31 * Saves pixmaps as png files
32 */
33 void
Save_Pixmap(GdkPixmap * pixmap,int pixmap_width,int pixmap_height,char * filename)34 Save_Pixmap(
35 GdkPixmap *pixmap, int pixmap_width,
36 int pixmap_height, char *filename )
37 {
38 GdkPixbuf *pixbuf;
39 GError *error = NULL;
40
41 /* Get image from pixmap */
42 gtk_widget_grab_focus( structure_drawingarea );
43 pixbuf = gdk_pixbuf_get_from_drawable(
44 NULL, pixmap, gdk_drawable_get_colormap(pixmap),
45 0, 0, 0, 0, pixmap_width, pixmap_height );
46
47 /* Save image as PNG file */
48 gdk_pixbuf_save( pixbuf, filename, "png", &error, NULL );
49 g_object_unref( pixbuf );
50
51 } /* Save_Pixmap() */
52
53 /*-----------------------------------------------------------------------*/
54
55 /* New_Viewer_Angle()
56 *
57 * Sets parameters for a new viewer angle
58 */
59 void
New_Viewer_Angle(double wr,double wi,GtkSpinButton * wr_spb,GtkSpinButton * wi_spb,projection_parameters_t * params)60 New_Viewer_Angle(
61 double wr, double wi,
62 GtkSpinButton *wr_spb,
63 GtkSpinButton *wi_spb,
64 projection_parameters_t *params )
65 {
66 /* Recalculate projection paramenters */
67 params->Wr = wr;
68 params->Wi = wi;
69
70 /* Set new value */
71 Set_Spin_Button( wr_spb, (gdouble)params->Wr );
72 Set_Spin_Button( wi_spb, (gdouble)params->Wi );
73
74 } /* New_Viewer_Angle() */
75
76 /*-----------------------------------------------------------------------*/
77
78 /* Set_Spin_Button()
79 *
80 * Sets the value of a spin button
81 */
82 void
Set_Spin_Button(GtkSpinButton * spin,gdouble value)83 Set_Spin_Button( GtkSpinButton *spin, gdouble value )
84 {
85 /* Save original value and set new */
86 gdouble sav = gtk_spin_button_get_value( spin );
87 gtk_spin_button_set_value( spin, value );
88
89 /* Issue a value_changed signal if needed (given same values) */
90 if( sav == value )
91 g_signal_emit_by_name( G_OBJECT(spin), "value_changed", NULL );
92
93 } /* Set_Spin_Button() */
94
95 /*-----------------------------------------------------------------------*/
96
97 /* Create_Pixmap()
98 *
99 * Creates or resizes a pixmap after a configure event
100 */
101 void
Create_Pixmap(GdkPixmap ** pixmap,int * pixmap_width,int * pixmap_height,GtkWidget * widget,GdkEventConfigure * event,projection_parameters_t * params)102 Create_Pixmap(
103 GdkPixmap **pixmap,
104 int *pixmap_width,
105 int *pixmap_height,
106 GtkWidget *widget,
107 GdkEventConfigure *event,
108 projection_parameters_t *params )
109 {
110 /* Create or resize pixmap */
111 if( *pixmap != NULL )
112 {
113 g_object_unref( *pixmap );
114 *pixmap = NULL;
115 }
116
117 *pixmap = gdk_pixmap_new(
118 widget->window,
119 event->width,
120 event->height, -1 );
121 *pixmap_width = event->width;
122 *pixmap_height = event->height;
123
124 /* Calculate new projection parameters */
125 if( params != NULL )
126 New_Projection_Parameters( *pixmap_width, *pixmap_height, params );
127
128 } /* Create_Pixmap() */
129
130 /*-----------------------------------------------------------------------*/
131
132 /* Motion_Event()
133 *
134 * Handles pointer motion event on drawingareas
135 */
136 void
Motion_Event(GdkEventMotion * event,projection_parameters_t * params)137 Motion_Event(
138 GdkEventMotion *event,
139 projection_parameters_t *params )
140 {
141 /* Save previous pointer position */
142 static gdouble x_old = 0.0, y_old = 0.0;
143
144 gdouble x = event->x;
145 gdouble y = event->y;
146 gdouble dx, dy;
147 gchar value[6];
148 size_t s = sizeof( value );
149
150 /* Initialize saved x,y */
151 if( params->reset )
152 {
153 x_old = x;
154 y_old = y;
155 params->reset = FALSE;
156 }
157
158 /* Recalculate projection parameters
159 * according to pointer motion */
160 dx = x - x_old;
161 dy = y - y_old;
162 x_old = x;
163 y_old = y;
164
165 /* Other buttons are used for moving axes on screen */
166 if( event->state & GDK_BUTTON1_MASK )
167 {
168 /* Set the structure rotate/incline spinbuttons */
169 if( isFlagSet(COMMON_PROJECTION) ||
170 (params->type == STRUCTURE_DRAWINGAREA) )
171 {
172 structure_proj_params.Wr -= dx / (gdouble)MOTION_EVENTS_COUNT;
173 structure_proj_params.Wi += dy / (gdouble)MOTION_EVENTS_COUNT;
174 snprintf( value, s, "%d", (int)structure_proj_params.Wr );
175 gtk_entry_set_text( GTK_ENTRY(rotate_structure), value );
176 snprintf( value, s, "%d", (int)structure_proj_params.Wi );
177 gtk_entry_set_text( GTK_ENTRY(incline_structure), value );
178 }
179
180 /* Set the rdpattern rotate/incline spinbuttons */
181 if( (isFlagSet(DRAW_ENABLED) &&
182 isFlagSet(COMMON_PROJECTION)) ||
183 (params->type == RDPATTERN_DRAWINGAREA) )
184 {
185 rdpattern_proj_params.Wr -= dx / (gdouble)MOTION_EVENTS_COUNT;
186 rdpattern_proj_params.Wi += dy / (gdouble)MOTION_EVENTS_COUNT;
187 snprintf( value, s, "%d", (int)rdpattern_proj_params.Wr );
188 gtk_entry_set_text( GTK_ENTRY(rotate_rdpattern), value );
189 snprintf( value, s, "%d", (int)rdpattern_proj_params.Wi );
190 gtk_entry_set_text( GTK_ENTRY(incline_rdpattern), value );
191 }
192
193 /* Rotate/incline structure */
194 if( params->type == STRUCTURE_DRAWINGAREA )
195 {
196 New_Structure_Projection_Angle();
197 if( isFlagSet(DRAW_ENABLED) &&
198 isFlagSet(COMMON_PROJECTION) )
199 New_Radiation_Projection_Angle();
200 }
201 else if( params->type == RDPATTERN_DRAWINGAREA )
202 {
203 /* Rotate/incline rdpattern */
204 New_Radiation_Projection_Angle();
205 if( isFlagSet(COMMON_PROJECTION) )
206 New_Structure_Projection_Angle();
207 }
208 } /* if( event->state & GDK_BUTTON1_MASK ) */
209 else
210 {
211 /* Move structure or rdpattern axes on screen */
212 params->x_center += dx;
213 params->y_center -= dy;
214 if( params->type == STRUCTURE_DRAWINGAREA )
215 Draw_Structure( structure_drawingarea );
216 if( params->type == RDPATTERN_DRAWINGAREA )
217 Draw_Radiation( rdpattern_drawingarea );
218 }
219
220 } /* Motion_Event() */
221
222 /*-----------------------------------------------------------------------*/
223
224 /* Plot_Select()
225 *
226 * Sets up plotting of requested freq data
227 */
228 void
Plot_Select(GtkToggleButton * togglebutton,unsigned long long int flag)229 Plot_Select( GtkToggleButton *togglebutton, unsigned long long int flag )
230 {
231 if( gtk_toggle_button_get_active(togglebutton) )
232 {
233 SetFlag( flag | PLOT_SELECT );
234 calc_data.ngraph++;
235 }
236 else
237 {
238 ClearFlag( flag );
239 calc_data.ngraph--;
240 }
241
242 /* Trigger a redraw of frequency plots drawingarea */
243 if( isFlagSet(PLOT_ENABLED) && isFlagSet(FREQ_LOOP_DONE) )
244 Plot_Frequency_Data();
245
246 } /* Plot_Select() */
247
248 /*-----------------------------------------------------------------------*/
249
250 /* Delete_Event()
251 *
252 * Handles user request to delete a window
253 */
254 void
Delete_Event(gchar * mesg)255 Delete_Event( gchar *mesg )
256 {
257 quit_dialog = create_quit_dialog();
258 gtk_widget_show( quit_dialog );
259
260 if( isFlagSet(FREQ_LOOP_RUNNING) )
261 {
262 if( isFlagSet(MAIN_QUIT) )
263 gtk_label_set_text( GTK_LABEL(lookup_widget(
264 quit_dialog, "quit_label")),
265 _("The frequency loop is running\n"\
266 "Really end operation?") );
267 else gtk_label_set_text( GTK_LABEL(lookup_widget(
268 quit_dialog, "quit_label")),
269 _("The frequency loop is running\n"\
270 "Really close this window?") );
271 }
272 else gtk_label_set_text( GTK_LABEL(lookup_widget(
273 quit_dialog, "quit_label")), mesg );
274
275 } /* Delete_Event() */
276
277 /*-----------------------------------------------------------------------*/
278
279 /* Set_Pol_Menuitem()
280 *
281 * Sets the polarization type menuitem to current setting
282 */
283 void
Set_Pol_Menuitem(GtkMenuItem * menuitem)284 Set_Pol_Menuitem( GtkMenuItem *menuitem )
285 {
286 gchar *pol_menu[NUM_POL] =
287 {
288 "rdpattern_total",
289 "rdpattern_horizontal",
290 "rdpattern_vertical",
291 "rdpattern_right_hand",
292 "rdpattern_left_hand",
293 };
294
295 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(lookup_widget(
296 GTK_WIDGET(menuitem), pol_menu[calc_data.pol_type])), TRUE );
297
298 } /* Set_Pol_Menuitem() */
299
300 /*-----------------------------------------------------------------------*/
301
302 /* Close_Windows()
303 *
304 * Closes some open windows
305 */
306 void
Close_Windows(void)307 Close_Windows( void )
308 {
309 if( isFlagSet(PLOT_ENABLED) )
310 {
311 gtk_widget_destroy( freqplots_window );
312 gtk_check_menu_item_set_active(
313 GTK_CHECK_MENU_ITEM(lookup_widget(
314 main_window, "main_freqplots")), FALSE );
315 }
316
317 if( isFlagSet(DRAW_ENABLED) )
318 {
319 gtk_widget_destroy( rdpattern_window );
320 gtk_check_menu_item_set_active(
321 GTK_CHECK_MENU_ITEM(lookup_widget(
322 main_window, "main_rdpattern")), FALSE );
323 }
324
325 } /* Close_Windows() */
326
327 /*-----------------------------------------------------------------------*/
328
329 /* Open_Editor()
330 *
331 * Pops up a Editor window on user
332 * right-click on a NEC2 Editor treeview
333 */
334 gboolean
Open_Editor(GtkTreeView * view)335 Open_Editor( GtkTreeView *view )
336 {
337 GtkTreeSelection *selection;
338 GtkTreeIter iter;
339 GtkTreeModel *model;
340 gchar *card;
341 GtkWidget *button;
342
343 /* Find the selected treeview row */
344 selection = gtk_tree_view_get_selection( view );
345 if( !gtk_tree_selection_get_selected(selection, &model, &iter) )
346 return( FALSE );
347
348 /* Get the "card" name from first column */
349 gtk_tree_model_get( model, &iter, 0, &card, -1);
350 size_t s = strlen( card );
351
352 /* Some "cards" have common editors */
353 if( strcmp(card, "GC") == 0 )
354 Strlcpy( card, "GW", s );
355 else if( strcmp(card, "SC") == 0 )
356 Strlcpy( card, "SP", s );
357 else if( strcmp(card, "SM") == 0 )
358 Strlcpy( card, "SP", s );
359 else if( strcmp(card, "NH") == 0 )
360 Strlcpy( card, "NE", s );
361 else if( strcmp(card, "GE") == 0 )
362 {
363 Gend_Editor( EDITOR_EDIT );
364 return( TRUE );
365 } /* EN Not editable */
366 else if( strcmp(card, "EN") == 0 )
367 return( TRUE );
368
369 /* Send a "clicked" signal to the appropriate editor button */
370 card[0] = (gchar)tolower((int)card[0]);
371 card[1] = (gchar)tolower((int)card[1]);
372 button = lookup_widget( GTK_WIDGET(view), card );
373 g_free(card);
374 if( button != NULL )
375 g_signal_emit_by_name( button, "clicked" );
376 else return( FALSE );
377
378 return( TRUE );
379 } /* Open_Editor() */
380
381 /*-----------------------------------------------------------------------*/
382
383 /* Main_Rdpattern_Activate()
384 *
385 * Callback function for the Radiation Pattern draw button
386 */
387 void
Main_Rdpattern_Activate(gboolean from_menu)388 Main_Rdpattern_Activate( gboolean from_menu )
389 {
390 /* Set E field check menu item */
391 if( fpat.nfeh & NEAR_EFIELD )
392 {
393 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(
394 lookup_widget(rdpattern_window,
395 "rdpattern_e_field")), TRUE );
396 SetFlag( DRAW_EFIELD );
397 }
398 else
399 {
400 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(
401 lookup_widget(rdpattern_window,
402 "rdpattern_e_field")), FALSE );
403 ClearFlag( DRAW_EFIELD );
404 }
405
406 /* Set H field check menu item */
407 if( fpat.nfeh & NEAR_HFIELD )
408 {
409 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(
410 lookup_widget(rdpattern_window,
411 "rdpattern_h_field")), TRUE );
412 SetFlag( DRAW_HFIELD );
413 }
414 else
415 {
416 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(
417 lookup_widget(rdpattern_window,
418 "rdpattern_h_field")), FALSE );
419 ClearFlag( DRAW_HFIELD );
420 }
421
422 /* Set Poynting vector check menu item */
423 if( (fpat.nfeh & NEAR_EHFIELD) == NEAR_EHFIELD )
424 {
425 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(
426 lookup_widget(rdpattern_window,
427 "rdpattern_poynting_vector")), TRUE );
428 SetFlag( DRAW_POYNTING );
429 }
430 else
431 {
432 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(
433 lookup_widget(rdpattern_window,
434 "rdpattern_poynting_vector")), FALSE );
435 ClearFlag( DRAW_POYNTING );
436 }
437
438 /* Set structure overlay in Rad Pattern window */
439 if( isFlagClear(OVERLAY_STRUCT) )
440 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(
441 lookup_widget(rdpattern_window,
442 "rdpattern_overlay_structure")), FALSE );
443 else
444 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(
445 lookup_widget(rdpattern_window,
446 "rdpattern_overlay_structure")), TRUE );
447
448
449 /* Sync common projection spinbuttons */
450 if( isFlagSet(COMMON_PROJECTION) )
451 {
452 gchar value[6];
453 size_t s = sizeof( value ) - 1;
454
455 rdpattern_proj_params.Wr = structure_proj_params.Wr;
456 rdpattern_proj_params.Wi = structure_proj_params.Wi;
457 snprintf( value, s, "%d", (int)rdpattern_proj_params.Wr );
458 value[s] = '\0';
459 gtk_entry_set_text( GTK_ENTRY(rotate_rdpattern), value );
460 snprintf( value, s, "%d", (int)rdpattern_proj_params.Wi );
461 value[s] = '\0';
462 gtk_entry_set_text( GTK_ENTRY(incline_rdpattern), value );
463 }
464 else /* Initialize radiation pattern projection angles */
465 {
466 rdpattern_proj_params.Wr =
467 gtk_spin_button_get_value(rotate_rdpattern);
468 rdpattern_proj_params.Wi =
469 gtk_spin_button_get_value(incline_rdpattern);
470 }
471 New_Radiation_Projection_Angle();
472
473 /* Redo currents if not reaching this function
474 * from the menu callback (e.g. not user action) */
475 if( !crnt.valid && !from_menu ) Redo_Currents( NULL );
476
477 /* Display frequency in freq spinbutton */
478 if( from_menu )
479 {
480 char value[9];
481 size_t s = sizeof( value );
482 snprintf( value, s, "%.3f", calc_data.fmhz );
483 value[s - 1] = '\0';
484 gtk_entry_set_text(
485 GTK_ENTRY(rdpattern_frequency), value );
486 }
487
488 /* Enable Gain or E/H field drawing */
489 SetFlag( DRAW_ENABLED );
490
491 } /* Main_Rdpattern_Activate() */
492
493 /*-----------------------------------------------------------------------*/
494
495 /* Main_Freqplots_Activate()
496 *
497 * Callback function for for the main Frequency Plots button
498 */
499 gboolean
Main_Freqplots_Activate(void)500 Main_Freqplots_Activate( void )
501 {
502 /* No plots for Incident Field and
503 * Elementary Current Source Excitation */
504 if( (fpat.ixtyp != 0) && (fpat.ixtyp != 5) )
505 {
506 stop( _("Not available for Incident Field or\n"\
507 "Elementary Current Source Excitation.\n"\
508 "(Excitation Types 1 to 4)"), ERR_OK );
509 return( FALSE );
510 }
511
512 /* Enable freq data graph plotting */
513 SetFlag( PLOT_ENABLED );
514
515 return( TRUE );
516 } /* Main_Freqplots_Activate() */
517
518 /*-----------------------------------------------------------------------*/
519
520 /* Rdpattern_Gain_Togglebutton_Toggled()
521 *
522 * Callback function for Rad Pattern window Gain button
523 */
524 void
Rdpattern_Gain_Togglebutton_Toggled(gboolean flag)525 Rdpattern_Gain_Togglebutton_Toggled( gboolean flag )
526 {
527 /* If radiation pattern data do not
528 * allow drawing of radiation pattern */
529 if( isFlagClear(ENABLE_RDPAT) ) return;
530
531 /* Enable or not gain (radiation) pattern plotting */
532 if( flag )
533 {
534 SetFlag( DRAW_GAIN );
535 ClearFlag( DRAW_EHFIELD );
536 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(lookup_widget(
537 rdpattern_window, "rdpattern_eh_togglebutton")), FALSE );
538
539 /* Redraw radiation pattern drawingarea */
540 if( isFlagSet(DRAW_ENABLED) &&
541 isFlagClear(FREQ_LOOP_RUNNING) )
542 {
543 if( !crnt.valid ) Redo_Currents( NULL );
544 SetFlag( DRAW_NEW_RDPAT );
545 Draw_Radiation( rdpattern_drawingarea );
546 }
547
548 Set_Window_Labels();
549 }
550 else
551 {
552 ClearFlag( DRAW_GAIN );
553 /* Clear radiation pattern drawingarea */
554 if( isFlagClear(DRAW_EHFIELD) &&
555 isFlagSet(DRAW_ENABLED) )
556 Draw_Radiation( rdpattern_drawingarea );
557 Free_Draw_Buffers();
558 }
559
560 return;
561 } /* Rdpattern_Gain_Togglebutton_Toggled() */
562
563 /*-----------------------------------------------------------------------*/
564
565 /* Rdpattern_EH_Togglebutton_Toggled()
566 *
567 * Callback function for Rad Pattern window E/H field button
568 */
569 void
Rdpattern_EH_Togglebutton_Toggled(gboolean flag)570 Rdpattern_EH_Togglebutton_Toggled( gboolean flag )
571 {
572 /* If no near EH data */
573 if( !fpat.nfeh ) return;
574
575 /* Enable or not E/H fields plotting */
576 if( flag )
577 {
578 SetFlag( DRAW_EHFIELD );
579 ClearFlag( DRAW_GAIN );
580 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(lookup_widget(
581 rdpattern_window, "rdpattern_gain_togglebutton")), FALSE );
582
583 /* Delegate near field calcuations to child
584 * processes if forked and near field data valid */
585 if( FORKED )
586 {
587 Alloc_Nearfield_Buffers(fpat.nrx, fpat.nry, fpat.nrz);
588 Pass_EH_Flags();
589 }
590
591 /* Redraw radiation pattern drawingarea */
592 if( isFlagSet(DRAW_ENABLED) &&
593 isFlagClear(FREQ_LOOP_RUNNING) )
594 {
595 if( !near_field.valid ) Redo_Currents(NULL);
596 Near_Field_Pattern();
597 SetFlag( DRAW_NEW_EHFIELD );
598 Draw_Radiation( rdpattern_drawingarea );
599 }
600
601 Set_Window_Labels();
602 }
603 else
604 {
605 ClearFlag( NEAREH_ANIMATE );
606 ClearFlag( DRAW_EHFIELD );
607
608 /* Clear radiation pattern drawingarea */
609 if( isFlagClear(DRAW_GAIN) &&
610 isFlagSet(DRAW_ENABLED) )
611 Draw_Radiation( rdpattern_drawingarea );
612
613 /* Disable near field calcuations
614 * by child processes if forked */
615 Pass_EH_Flags();
616 }
617
618 } /* Rdpattern_EH_Togglebutton_Toggled() */
619
620 /*-----------------------------------------------------------------------*/
621
622 /* Main_Currents_Togglebutton_Toggled()
623 *
624 * Callback function for Main Currents toggle button
625 */
626 void
Main_Currents_Togglebutton_Toggled(gboolean flag)627 Main_Currents_Togglebutton_Toggled( gboolean flag )
628 {
629 /* Enable calculation and rendering of structure curents */
630 if( flag )
631 {
632 SetFlag( DRAW_CURRENTS );
633 ClearFlag( DRAW_CHARGES );
634 crnt.newer = 1;
635 Alloc_Crnt_Buffs();
636
637 gtk_toggle_button_set_active(
638 GTK_TOGGLE_BUTTON(lookup_widget(main_window,
639 "main_charges_togglebutton")), FALSE );
640 gtk_label_set_text(
641 GTK_LABEL(lookup_widget(main_window, "struct_label")),
642 _("View Currents") );
643
644 if( !crnt.valid && isFlagClear(FREQ_LOOP_RUNNING) )
645 Redo_Currents( NULL );
646 else if( crnt.valid )
647 Draw_Structure( structure_drawingarea );
648
649 if( isFlagSet(OVERLAY_STRUCT) )
650 Draw_Radiation( rdpattern_drawingarea );
651 }
652 else
653 {
654 ClearFlag( DRAW_CURRENTS );
655 if( isFlagClear(DRAW_CHARGES) )
656 {
657 /* Redraw structure on screen if frequency loop is not running */
658 gtk_label_set_text(
659 GTK_LABEL(lookup_widget(main_window, "struct_label")),
660 _("View Geometry") );
661 if( isFlagClear(FREQ_LOOP_RUNNING) )
662 Draw_Structure( structure_drawingarea );
663 Free_Crnt_Buffs();
664 }
665 if( isFlagSet(OVERLAY_STRUCT) )
666 Draw_Radiation( rdpattern_drawingarea );
667 }
668 } /* Main_Currents_Togglebutton_Toggled() */
669
670 /*-----------------------------------------------------------------------*/
671
672 /* Main_Charges_Togglebutton_Toggled()
673 *
674 * Callback function for Main Charges toggle button
675 */
676 void
Main_Charges_Togglebutton_Toggled(gboolean flag)677 Main_Charges_Togglebutton_Toggled( gboolean flag )
678 {
679 if( flag )
680 {
681 SetFlag( DRAW_CHARGES );
682 ClearFlag( DRAW_CURRENTS );
683 crnt.newer = 1;
684 Alloc_Crnt_Buffs();
685
686 gtk_toggle_button_set_active(
687 GTK_TOGGLE_BUTTON(lookup_widget(main_window,
688 "main_currents_togglebutton")), FALSE );
689 gtk_label_set_text(
690 GTK_LABEL(lookup_widget(main_window, "struct_label")),
691 _("View Charges") );
692
693 if( !crnt.valid && isFlagClear(FREQ_LOOP_RUNNING) )
694 Redo_Currents( NULL );
695 else if( crnt.valid )
696 Draw_Structure( structure_drawingarea );
697
698 if( isFlagSet(OVERLAY_STRUCT) )
699 Draw_Radiation( rdpattern_drawingarea );
700 }
701 else
702 {
703 ClearFlag( DRAW_CHARGES );
704 if( isFlagClear(DRAW_CURRENTS) )
705 {
706 /* Redraw structure on screen if frequency loop is not running */
707 gtk_label_set_text(
708 GTK_LABEL(lookup_widget(main_window, "struct_label")),
709 _("View Geometry") );
710 if( isFlagClear(FREQ_LOOP_RUNNING) )
711 Draw_Structure( structure_drawingarea );
712 Free_Crnt_Buffs();
713 }
714 if( isFlagSet(OVERLAY_STRUCT) )
715 Draw_Radiation( rdpattern_drawingarea );
716 }
717 } /* Main_Charges_Togglebutton_Toggled() */
718
719 /*-----------------------------------------------------------------------*/
720
721 /* Open_Nec2_Editor()
722 *
723 * Opens NEC2 editor window and fills
724 * tree view according to action flag
725 */
726 void
Open_Nec2_Editor(int action)727 Open_Nec2_Editor( int action )
728 {
729 nec2_edit_window = create_nec2_editor();
730 gtk_widget_show( nec2_edit_window );
731
732 geom_treeview = GTK_TREE_VIEW(
733 lookup_widget(nec2_edit_window, "nec2_geom_treeview") );
734 cmnd_treeview = GTK_TREE_VIEW(
735 lookup_widget(nec2_edit_window, "nec2_cmnd_treeview") );
736
737 Nec2_Input_File_Treeview( action );
738
739 geom_adjustment = gtk_scrolled_window_get_vadjustment(
740 GTK_SCROLLED_WINDOW(lookup_widget(nec2_edit_window,
741 "scrolledwindow4")) );
742 cmnd_adjustment = gtk_scrolled_window_get_vadjustment(
743 GTK_SCROLLED_WINDOW(lookup_widget(nec2_edit_window,
744 "scrolledwindow3")) );
745 } /* Open_Nec2_Editor() */
746
747 /*-----------------------------------------------------------------------*/
748
749 /* Nec2_Apply_Checkbuton()
750 *
751 * Checks whether the NEC2 editor's "Apply" check button is active
752 */
753
754 gboolean
Nec2_Apply_Checkbutton(void)755 Nec2_Apply_Checkbutton( void )
756 {
757 return( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
758 lookup_widget(nec2_edit_window,
759 "nec2_apply_checkbutton" ))) );
760 }
761
762 /*-----------------------------------------------------------------------*/
763
764 /* Gtk_Quit()
765 *
766 * Quits gtk main
767 */
768 void
Gtk_Quit(void)769 Gtk_Quit( void )
770 {
771 int i, k;
772
773 Close_File( &input_fp );
774 SetFlag( MAIN_QUIT );
775
776 /* Kill child processes */
777 if( FORKED && !CHILD )
778 while( num_child_procs )
779 {
780 num_child_procs--;
781 kill( forked_proc_data[num_child_procs]->child_pid, SIGKILL );
782 }
783
784 /* Kill possibly nested loops */
785 k = (int)gtk_main_level();
786 for( i = 0; i < k; i++ )
787 gtk_main_quit();
788
789 } /* Gtk_Quit() */
790
791 /*-----------------------------------------------------------------------*/
792
793 /* Pass_EH_Flags
794 *
795 * Passes near field related flags to child processes
796 */
797 void
Pass_EH_Flags(void)798 Pass_EH_Flags( void )
799 {
800 char flag;
801 size_t cnt;
802 int idx;
803
804 /* Abort if not forked */
805 if( !FORKED ) return;
806
807 /* Tell child process to calculate near field data */
808 cnt = strlen( fork_commands[EHFIELD] );
809 for( idx = 0; idx < calc_data.num_jobs; idx++ )
810 Write_Pipe( idx, fork_commands[EHFIELD], (ssize_t)cnt, TRUE );
811
812 /* Tell child to set near field flags */
813 flag = 0;
814 if( isFlagSet(DRAW_EHFIELD) ) flag |= 0x01;
815 if( isFlagSet(NEAREH_SNAPSHOT) ) flag |= 0x02;
816 if( isFlagSet(DRAW_EFIELD) ) flag |= 0x04;
817 if( isFlagSet(DRAW_HFIELD) ) flag |= 0x08;
818
819 cnt = sizeof( flag );
820 for( idx = 0; idx < calc_data.num_jobs; idx++ )
821 Write_Pipe( idx, &flag, (ssize_t)cnt, TRUE );
822
823 } /* Pass_EH_Flags */
824
825 /*-----------------------------------------------------------------------*/
826
827 /* Alloc_Crnt_Buffs()
828 *
829 * Allocates memory for current/charge draw buffers
830 */
831 void
Alloc_Crnt_Buffs(void)832 Alloc_Crnt_Buffs( void )
833 {
834 /* Patch currents buffer */
835 if( data.m > 0 )
836 {
837 size_t mreq = (size_t)data.m * sizeof( double );
838 mem_realloc( (void **)&ct1m, mreq, "in callback_func.c" );
839 mem_realloc( (void **)&ct2m, mreq, "in callback_func.c" );
840 }
841
842 /* Segment currents buffer */
843 if( data.n > 0 )
844 {
845 size_t mreq = (size_t)data.n * sizeof( double );
846 mem_realloc( (void **)&cmag, mreq, "in callback_func.c" );
847 }
848
849 } /* Alloc_Crnt_Buffs() */
850
851 /*-----------------------------------------------------------------------*/
852
853 /* Free_Crnt_Buffs()
854 *
855 * Frees current/charge draw buffers
856 */
857 void
Free_Crnt_Buffs(void)858 Free_Crnt_Buffs( void )
859 {
860 free_ptr( (void **)&ct1m );
861 free_ptr( (void **)&ct2m );
862 free_ptr( (void **)&cmag );
863 } /* Free_Crnt_Buffs() */
864
865 /*-----------------------------------------------------------------------*/
866
867