Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

GUIDir.cc

Go to the documentation of this file.
00001 /*
00002 
00003     Direction finding GUI
00004     Copyright (C) 1999-2002 Jussi Laako
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 */
00021 
00022 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <math.h>
00027 #include <time.h>
00028 #include <signal.h>
00029 #include <gtk/gtk.h>
00030 #include <gdk/gdkrgb.h>
00031 
00032 #include "GUIDir.hh"
00033 
00034 
00035 G_LOCK_DEFINE_STATIC(gmInputMutex);
00036 
00037 static const char *cpWindowTxt = "Direction";
00038 // Table 1
00039 static const char *cpLServerTxt = "Server";
00040 static const char *cpBConnectTxt = "Connect";
00041 static const char *cpBDisconnectTxt = "Disconnect";
00042 static const char *cpCBFreezeTxt = "Freeze";
00043 // Table 2
00044 static const char *cpLAlgorithmTxt = "Algorithm";
00045 static const char *cpaLAlgorithmMenu[] = { "Beamforming", "Correlation",
00046     "Beamforming & Correlation", "Spectrum power/phase" };
00047 static const char *cpLSoundSpeedTxt = "Sound speed";
00048 static const char *cpLLowFrequencyLimitTxt = "Low frequency limit";
00049 static const char *cpLIntegrationTimeTxt = "Integration time";
00050 // Table 3
00051 static const char *cpLScalingTxt = "Scaling";
00052 static const char *cpaLScalingMenu[] = { "Linear", "Logarithmic",
00053     "Exponential", "Sine" };
00054 static const char *cpLScalingExponentTxt = "Scaling exponent";
00055 static const char *cpLRemoveNoiseTxt = "Remove noise";
00056 static const char *cpaLRemoveNoiseMenu[] = { "None", "TPSW", "OTA",
00057     "Diff", "InvDiff" };
00058 static const char *cpLAlphaTxt = "Alpha";
00059 static const char *cpLMeanLengthTxt = "Mean length";
00060 static const char *cpLGapLengthTxt = "Gap length";
00061 static const char *cpCBNormalizeTxt = "Normalize";
00062 static const char *cpCBNoFilterTxt = "No filter";
00063 static const char *cpLPaletteTxt = "Palette";
00064 static const char *cpaLPaletteMenu[] = { "BW", "HSV", "Light", "Temp",
00065     "Dir", "Green", "Green2", "PureGreen", "WB" };
00066 // Table 4
00067 static const char *cpLLeftDirectionTxt = "Left direction";
00068 static const char *cpLRightDirectionTxt = "Right direction";
00069 static const char *cpLSectorCountTxt = "Sector count";
00070 static const char *cpLDirectionScaleTxt = "Direction scale";
00071 static const char *cpCBSavingTxt = "Saving";
00072 static const char *cpBSaveTxt = "Save";
00073 static const char *cpFSSaveTxt = "Save to TIFF file";
00074 
00075 
00076 clGUIDir *GUIDir;
00077 
00078 
00079 int main (int argc, char *argv[])
00080 {
00081     int iRetVal;
00082 
00083     signal(SIGPIPE, SIG_IGN);
00084     signal(SIGFPE, SIG_IGN);
00085     GUIDir = new clGUIDir(&argc, &argv);
00086     iRetVal = GUIDir->Exec();
00087     delete GUIDir;
00088     return iRetVal;
00089 }
00090 
00091 
00092 gint WrapOnDelete (GtkWidget *gwSender, GdkEventAny *geaEvent)
00093 {
00094     return GUIDir->OnDelete(gwSender, geaEvent);
00095 }
00096 
00097 
00098 void WrapOnHideToggled (GtkToggleButton *gtbSender, gpointer gpData)
00099 {
00100     GUIDir->OnHideToggled(gtbSender, gpData);
00101 }
00102 
00103 
00104 gint WrapOnConnectClick (GtkWidget *gwSender, gpointer gpData)
00105 {
00106     return GUIDir->OnConnectClick(gwSender, gpData);
00107 }
00108 
00109 
00110 void WrapOnFreezeToggled (GtkToggleButton *gtbSender, gpointer gpData)
00111 {
00112     GUIDir->OnFreezeToggled(gtbSender, gpData);
00113 }
00114 
00115 
00116 gint WrapOnExposeWorm (GtkWidget *gwSender, GdkEventExpose *geeEvent)
00117 {
00118     return GUIDir->OnExposeWorm(gwSender, geeEvent);
00119 }
00120 
00121 
00122 gint WrapOnMotionWorm (GtkWidget *gwSender, GdkEventMotion *gemEvent)
00123 {
00124     return GUIDir->OnMotionWorm(gwSender, gemEvent);
00125 }
00126 
00127 
00128 gint WrapOnPaletteActivate (GtkWidget *gwSender, gpointer gpData)
00129 {
00130     return GUIDir->OnPaletteActivate(gwSender, gpData);
00131 }
00132 
00133 
00134 void WrapOnSaveClicks (GtkWidget *gwSender, gpointer gpData)
00135 {
00136     GUIDir->OnSaveClicks(gwSender, gpData);
00137 }
00138 
00139 
00140 void WrapOnGdkInput (gpointer gpData, gint giSource,
00141     GdkInputCondition gicCondition)
00142 {
00143     GUIDir->OnGdkInput(gpData, giSource, gicCondition);
00144 }
00145 
00146 
00147 bool clGUIDir::Build ()
00148 {
00149     // --- Main window
00150     gwWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00151     gtk_window_set_title(GTK_WINDOW(gwWindow), cpWindowTxt);
00152     // shrink, grow, auto-shrink
00153     gtk_window_set_policy(GTK_WINDOW(gwWindow), FALSE, FALSE, TRUE);
00154     // gtk_widget_show(gwWindow);
00155 
00156     // --- Vertical box
00157     // homogenous, spacing
00158     gwVBox = gtk_vbox_new(FALSE, DGUI_PADDING);
00159     gtk_container_add(GTK_CONTAINER(gwWindow), gwVBox);
00160     gtk_widget_show(gwVBox);
00161 
00162     // --- Hide button
00163     gwCBHide = gtk_check_button_new();
00164     gtk_box_pack_start(GTK_BOX(gwVBox), gwCBHide, FALSE, FALSE, 0);
00165     gtk_widget_show(gwCBHide);
00166 
00167     // --- Table 1
00168     if (!BuildTable1()) return false;
00169 
00170     // --- Table 2
00171     if (!BuildTable2()) return false;
00172 
00173     // --- Table 3
00174     if (!BuildTable3()) return false;
00175 
00176     // --- Table 4
00177     if (!BuildTable4()) return false;
00178 
00179     // --- Table worm
00180     if (!BuildTableWorm()) return false;
00181 
00182     // --- Status bar
00183     gwStatusBar = gtk_statusbar_new();
00184     gtk_box_pack_start(GTK_BOX(gwVBox), gwStatusBar, FALSE, FALSE, 0);
00185     gtk_widget_show(gwStatusBar);
00186     guSbCtxt = gtk_statusbar_get_context_id(GTK_STATUSBAR(gwStatusBar),
00187         "status");
00188     gtk_statusbar_push(GTK_STATUSBAR(gwStatusBar), guSbCtxt, "");
00189     
00190     // Delayed realization of main window
00191     gtk_widget_show(gwWindow);
00192 
00193     // Set ruler starting sizes
00194     gtk_widget_set_usize(gwHRDirection, 180 * iDirectionScale,
00195         gwHRDirection->allocation.height);
00196     gtk_widget_set_usize(gwVRTime, gwVRTime->allocation.width, iHistoryLines);
00197 
00198     // Build drawing primitives
00199     if (!BuildDrawingPrims()) return false;
00200 
00201     // Set cursors
00202     gdk_window_set_cursor(gwDAWorm->window, gcCrossHair);
00203 
00204     // Enable backing store
00205     GtkUtils.EnableBackingStore(gwDAWorm);
00206 
00207     // Set default widget
00208     //gtk_window_set_default(GTK_WINDOW(gwWindow), gwBConnect);
00209     
00210     return true;
00211 }
00212 
00213 
00214 bool clGUIDir::ConnectSignals ()
00215 {
00216     int iWidgetCntr;
00217     
00218     gtk_signal_connect(GTK_OBJECT(gwWindow), "delete_event",
00219         GTK_SIGNAL_FUNC(WrapOnDelete), NULL);
00220 
00221     gtk_signal_connect(GTK_OBJECT(gwCBHide), "toggled",
00222         GTK_SIGNAL_FUNC(WrapOnHideToggled), NULL);
00223 
00224     gtk_widget_add_events(gwDAWorm, GDK_POINTER_MOTION_MASK);
00225     GtkUtils.ConnectMotionEvent(gwHRDirection, gwDAWorm);
00226     GtkUtils.ConnectMotionEvent(gwVRTime, gwDAWorm);
00227     gtk_signal_connect(GTK_OBJECT(gwDAWorm), "expose_event",
00228         GTK_SIGNAL_FUNC(WrapOnExposeWorm), NULL);
00229     gtk_signal_connect(GTK_OBJECT(gwDAWorm), "motion_notify_event",
00230         GTK_SIGNAL_FUNC(WrapOnMotionWorm), NULL);
00231 
00232     gtk_signal_connect(GTK_OBJECT(gwBConnect), "clicked",
00233         GTK_SIGNAL_FUNC(WrapOnConnectClick), NULL);
00234     gtk_signal_connect(GTK_OBJECT(gwBDisconnect), "clicked",
00235         GTK_SIGNAL_FUNC(WrapOnConnectClick), NULL);
00236     gtk_signal_connect(GTK_OBJECT(gwCBFreeze), "toggled",
00237         GTK_SIGNAL_FUNC(WrapOnFreezeToggled), NULL);
00238 
00239     for (iWidgetCntr = 0; iWidgetCntr < DGUI_PALETTE_ITEMS; iWidgetCntr++)
00240     {
00241         gtk_signal_connect(GTK_OBJECT(gwaMIPalette[iWidgetCntr]), "activate",
00242             GTK_SIGNAL_FUNC(WrapOnPaletteActivate), NULL);
00243     }
00244 
00245     gtk_signal_connect(GTK_OBJECT(gwCBSaving), "toggled",
00246         GTK_SIGNAL_FUNC(WrapOnSaveClicks), GINT_TO_POINTER(3));
00247     gtk_signal_connect(GTK_OBJECT(gwBSave), "clicked",
00248         GTK_SIGNAL_FUNC(WrapOnSaveClicks), GINT_TO_POINTER(2));
00249     gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(gwFSSave)->ok_button),
00250         "clicked", GTK_SIGNAL_FUNC(WrapOnSaveClicks), GINT_TO_POINTER(1));
00251     gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(gwFSSave)->cancel_button),
00252         "clicked", GTK_SIGNAL_FUNC(WrapOnSaveClicks), GINT_TO_POINTER(0));
00253 
00254     return true;
00255 }
00256 
00257 
00258 bool clGUIDir::BuildTable1 ()
00259 {
00260     // rows, columns, homogenous
00261     gwTable1 = gtk_table_new(2, 4, FALSE);
00262     // box, child, expand, fill, padding
00263     gtk_box_pack_start(GTK_BOX(gwVBox), gwTable1, FALSE, FALSE, 0);
00264     gtk_widget_show(gwTable1);
00265 
00266     // - Label & Combo: Server
00267     gwLServer = gtk_label_new(cpLServerTxt);
00268     gtk_label_set_justify(GTK_LABEL(gwLServer), GTK_JUSTIFY_LEFT);
00269     gtk_table_attach(GTK_TABLE(gwTable1), gwLServer,
00270         0, 1, 0, 1,
00271         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00272         (GtkAttachOptions) 0,
00273         DGUI_PADDING / 2, 0);
00274     gtk_widget_show(gwLServer);
00275     gwCServer = gtk_combo_new();
00276     gtk_entry_set_max_length(GTK_ENTRY(GTK_COMBO(gwCServer)->entry),
00277         DGUI_SERVER_MAXLEN);
00278     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(gwCServer)->entry),
00279         "127.0.0.1:30001");
00280     // table, child, left attach, right attach, top attach, bottom attach,
00281     // x-options, y-options, x-padding, y-padding
00282     gtk_table_attach(GTK_TABLE(gwTable1), gwCServer,
00283         0, 1, 1, 2,
00284         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00285         (GtkAttachOptions) 0,
00286         DGUI_PADDING / 2, 0);
00287     gtk_widget_show(gwCServer);
00288     GtkUtils.ComboListFromFile(gwCServer, &glServers, DGUI_HOSTFILE);
00289 
00290     // - Button: Connect
00291     gwBConnect = gtk_button_new_with_label(cpBConnectTxt);
00292     gtk_table_attach(GTK_TABLE(gwTable1), gwBConnect,
00293         2, 3, 1, 2,
00294         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00295         DGUI_PADDING / 2, 0);
00296     gtk_widget_show(gwBConnect);
00297 
00298     // - Button: Disconnect
00299     gwBDisconnect = gtk_button_new_with_label(cpBDisconnectTxt);
00300     gtk_table_attach(GTK_TABLE(gwTable1), gwBDisconnect,
00301         3, 4, 1, 2,
00302         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00303         DGUI_PADDING / 2, 0);
00304     gtk_widget_show(gwBDisconnect);
00305 
00306     // - CheckButton: Freeze
00307     gwCBFreeze = gtk_check_button_new_with_label(cpCBFreezeTxt);
00308     gtk_table_attach(GTK_TABLE(gwTable1), gwCBFreeze,
00309         4, 5, 1, 2,
00310         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00311         DGUI_PADDING / 2, 0);
00312     gtk_widget_show(gwCBFreeze);
00313 
00314     return true;
00315 }
00316 
00317 
00318 bool clGUIDir::BuildTable2 ()
00319 {
00320     char cpConvBuf[DGUI_CONV_BUF_SIZE];
00321 
00322     // rows, columns, homogenous
00323     gwTable2 = gtk_table_new(2, 4, FALSE);
00324     // box, child, expand, fill, padding
00325     gtk_box_pack_start(GTK_BOX(gwVBox), gwTable2, FALSE, FALSE, 0);
00326     gtk_widget_show(gwTable2);
00327 
00328     // Label & OptionMenu: Algorithm
00329     gwLAlgorithm = gtk_label_new(cpLAlgorithmTxt);
00330     gtk_label_set_justify(GTK_LABEL(gwLAlgorithm), GTK_JUSTIFY_LEFT);
00331     gtk_table_attach(GTK_TABLE(gwTable2), gwLAlgorithm,
00332         0, 1, 0, 1,
00333         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00334         DGUI_PADDING / 2, 0);
00335     gtk_widget_show(gwLAlgorithm);
00336     gwOMAlgorithm = gtk_option_menu_new();
00337     gtk_table_attach(GTK_TABLE(gwTable2), gwOMAlgorithm,
00338         0, 1, 1, 2,
00339         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00340         DGUI_PADDING / 2, 0);
00341     gtk_widget_show(gwOMAlgorithm);
00342     GtkUtils.BuildOptionMenu(gwOMAlgorithm, &gwMAlgorithm, gwaMIAlgorithm,
00343         cpaLAlgorithmMenu, DGUI_ALGORITHM_ITEMS);
00344 
00345     // Label & Entry: Soundspeed
00346     gwLSoundSpeed = gtk_label_new(cpLSoundSpeedTxt);
00347     gtk_label_set_justify(GTK_LABEL(gwLSoundSpeed), GTK_JUSTIFY_LEFT);
00348     gtk_table_attach(GTK_TABLE(gwTable2), gwLSoundSpeed,
00349         1, 2, 0, 1,
00350         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK), 
00351         (GtkAttachOptions) 0,
00352         DGUI_PADDING / 2, 0);
00353     gtk_widget_show(gwLSoundSpeed);
00354     gwESoundSpeed = gtk_entry_new();
00355     gtk_table_attach(GTK_TABLE(gwTable2), gwESoundSpeed,
00356         1, 2, 1, 2,
00357         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00358         (GtkAttachOptions) 0,
00359         DGUI_PADDING / 2, 0);
00360     gtk_widget_show(gwESoundSpeed);
00361     gtk_widget_set_usize(gwESoundSpeed, DGUI_ENTRY_WIDTH,
00362         gwESoundSpeed->requisition.height);
00363     g_snprintf(cpConvBuf, DGUI_CONV_BUF_SIZE, "%.1f", fSoundSpeed);
00364     gtk_entry_set_text(GTK_ENTRY(gwESoundSpeed), cpConvBuf);
00365 
00366     // Label & Entry: Low frequency limit
00367     gwLLowFrequencyLimit = gtk_label_new(cpLLowFrequencyLimitTxt);
00368     gtk_label_set_justify(GTK_LABEL(gwLLowFrequencyLimit), GTK_JUSTIFY_LEFT);
00369     gtk_table_attach(GTK_TABLE(gwTable2), gwLLowFrequencyLimit,
00370         2, 3, 0, 1,
00371         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00372         (GtkAttachOptions) 0,
00373         DGUI_PADDING / 2, 0);
00374     gtk_widget_show(gwLLowFrequencyLimit);
00375     gwELowFrequencyLimit = gtk_entry_new();
00376     gtk_table_attach(GTK_TABLE(gwTable2), gwELowFrequencyLimit,
00377         2, 3, 1, 2,
00378         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00379         (GtkAttachOptions) 0,
00380         DGUI_PADDING / 2, 0);
00381     gtk_widget_show(gwELowFrequencyLimit);
00382     gtk_widget_set_usize(gwELowFrequencyLimit, DGUI_ENTRY_WIDTH,
00383         gwELowFrequencyLimit->requisition.height);
00384     gtk_entry_set_text(GTK_ENTRY(gwELowFrequencyLimit), "0.0");
00385 
00386     // Label & Entry: Integration time
00387     gwLIntegrationTime = gtk_label_new(cpLIntegrationTimeTxt);
00388     gtk_label_set_justify(GTK_LABEL(gwLIntegrationTime), GTK_JUSTIFY_LEFT);
00389     gtk_table_attach(GTK_TABLE(gwTable2), gwLIntegrationTime,
00390         3, 4, 0, 1,
00391         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00392         (GtkAttachOptions) 0,
00393         DGUI_PADDING / 2, 0);
00394     gtk_widget_show(gwLIntegrationTime);
00395     gwEIntegrationTime = gtk_entry_new();
00396     gtk_table_attach(GTK_TABLE(gwTable2), gwEIntegrationTime,
00397         3, 4, 1, 2,
00398         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00399         (GtkAttachOptions) 0,
00400         DGUI_PADDING / 2, 0);
00401     gtk_widget_show(gwEIntegrationTime);
00402     gtk_widget_set_usize(gwEIntegrationTime, DGUI_ENTRY_WIDTH,
00403         gwEIntegrationTime->requisition.height);
00404     gtk_entry_set_text(GTK_ENTRY(gwEIntegrationTime), "1.0");
00405 
00406     return true;
00407 }
00408 
00409 
00410 bool clGUIDir::BuildTable3 ()
00411 {
00412     // rows, columns, homogenous
00413     gwTable3 = gtk_table_new(2, 8, FALSE);
00414     // box, child, expand, fill, padding
00415     gtk_box_pack_start(GTK_BOX(gwVBox), gwTable3, FALSE, FALSE, 0);
00416     gtk_widget_show(gwTable3);
00417 
00418     // Label & OptionMenu: Scaling
00419     gwLScaling = gtk_label_new(cpLScalingTxt);
00420     gtk_label_set_justify(GTK_LABEL(gwLScaling), GTK_JUSTIFY_LEFT);
00421     gtk_table_attach(GTK_TABLE(gwTable3), gwLScaling,
00422         0, 1, 0, 1,
00423         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00424         DGUI_PADDING / 2, 0);
00425     gtk_widget_show(gwLScaling);
00426     gwOMScaling = gtk_option_menu_new();
00427     gtk_table_attach(GTK_TABLE(gwTable3), gwOMScaling,
00428         0, 1, 1, 2,
00429         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00430         DGUI_PADDING / 2, 0);
00431     gtk_widget_show(gwOMScaling);
00432     GtkUtils.BuildOptionMenu(gwOMScaling, &gwMScaling, gwaMIScaling,
00433         cpaLScalingMenu, DGUI_SCALING_ITEMS);
00434 
00435     // Label & Entry: Scaling exponent
00436     gwLScalingExponent = gtk_label_new(cpLScalingExponentTxt);
00437     gtk_label_set_justify(GTK_LABEL(gwLScalingExponent), GTK_JUSTIFY_LEFT);
00438     gtk_table_attach(GTK_TABLE(gwTable3), gwLScalingExponent,
00439         1, 2, 0, 1,
00440         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00441         (GtkAttachOptions) 0,
00442         DGUI_PADDING / 2, 0);
00443     gtk_widget_show(gwLScalingExponent);
00444     gwEScalingExponent = gtk_entry_new();
00445     gtk_table_attach(GTK_TABLE(gwTable3), gwEScalingExponent,
00446         1, 2, 1, 2,
00447         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00448         (GtkAttachOptions) 0,
00449         DGUI_PADDING / 2, 0);
00450     gtk_widget_show(gwEScalingExponent);
00451     gtk_widget_set_usize(gwEScalingExponent, DGUI_ENTRY_WIDTH,
00452         gwEScalingExponent->requisition.height);
00453     gtk_entry_set_text(GTK_ENTRY(gwEScalingExponent), "2.0");
00454 
00455     // Label & OptionMenu: Remove noise
00456     gwLRemoveNoise = gtk_label_new(cpLRemoveNoiseTxt);
00457     gtk_label_set_justify(GTK_LABEL(gwLRemoveNoise), GTK_JUSTIFY_LEFT);
00458     gtk_table_attach(GTK_TABLE(gwTable3), gwLRemoveNoise,
00459         2, 3, 0, 1,
00460         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00461         DGUI_PADDING / 2, 0);
00462     gtk_widget_show(gwLRemoveNoise);
00463     gwOMRemoveNoise = gtk_option_menu_new();
00464     gtk_table_attach(GTK_TABLE(gwTable3), gwOMRemoveNoise,
00465         2, 3, 1, 2,
00466         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00467         DGUI_PADDING / 2, 0);
00468     gtk_widget_show(gwOMRemoveNoise);
00469     GtkUtils.BuildOptionMenu(gwOMRemoveNoise, &gwMRemoveNoise, 
00470         gwaMIRemoveNoise, cpaLRemoveNoiseMenu, DGUI_REMOVE_NOISE_ITEMS);
00471 
00472     // Label & Entry: Alpha
00473     gwLAlpha = gtk_label_new(cpLAlphaTxt);
00474     gtk_label_set_justify(GTK_LABEL(gwLAlpha), GTK_JUSTIFY_LEFT);
00475     gtk_table_attach(GTK_TABLE(gwTable3), gwLAlpha,
00476         3, 4, 0, 1,
00477         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00478         (GtkAttachOptions) 0,
00479         DGUI_PADDING / 2, 0);
00480     gtk_widget_show(gwLAlpha);
00481     gwEAlpha = gtk_entry_new();
00482     gtk_table_attach(GTK_TABLE(gwTable3), gwEAlpha,
00483         3, 4, 1, 2,
00484         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00485         (GtkAttachOptions) 0,
00486         DGUI_PADDING / 2, 0);
00487     gtk_widget_show(gwEAlpha);
00488     gtk_widget_set_usize(gwEAlpha, DGUI_ENTRY_WIDTH,
00489         gwEAlpha->requisition.height);
00490     gtk_entry_set_text(GTK_ENTRY(gwEAlpha), "2.0");  // 0.9
00491 
00492     // Label & Entry: Mean length
00493     gwLMeanLength = gtk_label_new(cpLMeanLengthTxt);
00494     gtk_label_set_justify(GTK_LABEL(gwLMeanLength), GTK_JUSTIFY_LEFT);
00495     gtk_table_attach(GTK_TABLE(gwTable3), gwLMeanLength,
00496         4, 5, 0, 1,
00497         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00498         (GtkAttachOptions) 0,
00499         DGUI_PADDING / 2, 0);
00500     gtk_widget_show(gwLMeanLength);
00501     gwEMeanLength = gtk_entry_new();
00502     gtk_table_attach(GTK_TABLE(gwTable3), gwEMeanLength,
00503         4, 5, 1, 2,
00504         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00505         (GtkAttachOptions) 0,
00506         DGUI_PADDING / 2, 0);
00507     gtk_widget_show(gwEMeanLength);
00508     gtk_widget_set_usize(gwEMeanLength, DGUI_ENTRY_WIDTH,
00509         gwEMeanLength->requisition.height);
00510     gtk_entry_set_text(GTK_ENTRY(gwEMeanLength), "10");  // 18
00511 
00512     // Label & Entry: Gap length
00513     gwLGapLength = gtk_label_new(cpLGapLengthTxt);
00514     gtk_label_set_justify(GTK_LABEL(gwLGapLength), GTK_JUSTIFY_LEFT);
00515     gtk_table_attach(GTK_TABLE(gwTable3), gwLGapLength,
00516         5, 6, 0, 1,
00517         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00518         (GtkAttachOptions) 0,
00519         DGUI_PADDING / 2, 0);
00520     gtk_widget_show(gwLGapLength);
00521     gwEGapLength = gtk_entry_new();
00522     gtk_table_attach(GTK_TABLE(gwTable3), gwEGapLength,
00523         5, 6, 1, 2,
00524         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00525         (GtkAttachOptions) 0,
00526         DGUI_PADDING / 2, 0);
00527     gtk_widget_show(gwEGapLength);
00528     gtk_widget_set_usize(gwEGapLength, DGUI_ENTRY_WIDTH, 
00529         gwEGapLength->requisition.height);
00530     gtk_entry_set_text(GTK_ENTRY(gwEGapLength), "3");
00531 
00532     // CheckButton: No filter
00533     gwCBNoFilter = gtk_check_button_new_with_label(cpCBNoFilterTxt);
00534     gtk_table_attach(GTK_TABLE(gwTable3), gwCBNoFilter,
00535         6, 7, 0, 1,
00536         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00537         DGUI_PADDING / 2, 0);
00538     gtk_widget_show(gwCBNoFilter);
00539 
00540     // CheckButton: Normalize
00541     gwCBNormalize = gtk_check_button_new_with_label(cpCBNormalizeTxt);
00542     gtk_table_attach(GTK_TABLE(gwTable3), gwCBNormalize,
00543         6, 7, 1, 2,
00544         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00545         DGUI_PADDING / 2, 0);
00546     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gwCBNormalize), TRUE);
00547     gtk_widget_show(gwCBNormalize);
00548 
00549     // Label & OptionMenu: Palette
00550     gwLPalette = gtk_label_new(cpLPaletteTxt);
00551     gtk_label_set_justify(GTK_LABEL(gwLPalette), GTK_JUSTIFY_LEFT);
00552     gtk_table_attach(GTK_TABLE(gwTable3), gwLPalette,
00553         7, 8, 0, 1,
00554         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00555         DGUI_PADDING / 2, 0);
00556     gtk_widget_show(gwLPalette);
00557     gwOMPalette = gtk_option_menu_new();
00558     gtk_table_attach(GTK_TABLE(gwTable3), gwOMPalette,
00559         7, 8, 1, 2,
00560         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00561         DGUI_PADDING / 2, 0);
00562     gtk_widget_show(gwOMPalette);
00563     GtkUtils.BuildOptionMenu(gwOMPalette, &gwMPalette, gwaMIPalette,
00564         cpaLPaletteMenu, DGUI_PALETTE_ITEMS);
00565     gtk_option_menu_set_history(GTK_OPTION_MENU(gwOMPalette), iPalette);
00566 
00567     return true;
00568 }
00569 
00570 
00571 bool clGUIDir::BuildTable4 ()
00572 {
00573     char cpConvBuf[DGUI_CONV_BUF_SIZE];
00574 
00575     // rows, columns, homogenous
00576     gwTable4 = gtk_table_new(2, 5, FALSE);
00577     // box, child, expand, fill, padding
00578     gtk_box_pack_start(GTK_BOX(gwVBox), gwTable4, FALSE, FALSE, 0);
00579     gtk_widget_show(gwTable4);
00580 
00581     // Label & Entry: Left direction
00582     gwLLeftDirection = gtk_label_new(cpLLeftDirectionTxt);
00583     gtk_label_set_justify(GTK_LABEL(gwLLeftDirection), GTK_JUSTIFY_LEFT);
00584     gtk_table_attach(GTK_TABLE(gwTable4), gwLLeftDirection,
00585         0, 1, 0, 1,
00586         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00587         (GtkAttachOptions) 0,
00588         DGUI_PADDING / 2, 0);
00589     gtk_widget_show(gwLLeftDirection);
00590     gwELeftDirection = gtk_entry_new();
00591     gtk_table_attach(GTK_TABLE(gwTable4), gwELeftDirection,
00592         0, 1, 1, 2,
00593         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00594         (GtkAttachOptions) 0,
00595         DGUI_PADDING / 2, 0);
00596     gtk_widget_show(gwELeftDirection);
00597     gtk_widget_set_usize(gwELeftDirection, DGUI_ENTRY_WIDTH,
00598         gwELeftDirection->requisition.height);
00599     gtk_entry_set_text(GTK_ENTRY(gwELeftDirection), "-90.0");
00600 
00601     // Label & Entry: Right direction
00602     gwLRightDirection = gtk_label_new(cpLRightDirectionTxt);
00603     gtk_label_set_justify(GTK_LABEL(gwLRightDirection), GTK_JUSTIFY_LEFT);
00604     gtk_table_attach(GTK_TABLE(gwTable4), gwLRightDirection,
00605         1, 2, 0, 1,
00606         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00607         (GtkAttachOptions) 0,
00608         DGUI_PADDING / 2, 0);
00609     gtk_widget_show(gwLRightDirection);
00610     gwERightDirection = gtk_entry_new();
00611     gtk_table_attach(GTK_TABLE(gwTable4), gwERightDirection,
00612         1, 2, 1, 2,
00613         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00614         (GtkAttachOptions) 0,
00615         DGUI_PADDING / 2, 0);
00616     gtk_widget_show(gwERightDirection);
00617     gtk_widget_set_usize(gwERightDirection, DGUI_ENTRY_WIDTH,
00618         gwERightDirection->requisition.height);
00619     gtk_entry_set_text(GTK_ENTRY(gwERightDirection), "90.0");
00620 
00621     // Label & Entry: Sector count
00622     gwLSectorCount = gtk_label_new(cpLSectorCountTxt);
00623     gtk_label_set_justify(GTK_LABEL(gwLSectorCount), GTK_JUSTIFY_LEFT);
00624     gtk_table_attach(GTK_TABLE(gwTable4), gwLSectorCount,
00625         2, 3, 0, 1,
00626         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00627         (GtkAttachOptions) 0,
00628         DGUI_PADDING / 2, 0);
00629     gtk_widget_show(gwLSectorCount);
00630     gwESectorCount = gtk_entry_new();
00631     gtk_table_attach(GTK_TABLE(gwTable4), gwESectorCount,
00632         2, 3, 1, 2,
00633         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00634         (GtkAttachOptions) 0,
00635         DGUI_PADDING / 2, 0);
00636     gtk_widget_show(gwESectorCount);
00637     gtk_widget_set_usize(gwESectorCount, DGUI_ENTRY_WIDTH,
00638         gwESectorCount->requisition.height);
00639     gtk_entry_set_text(GTK_ENTRY(gwESectorCount), "180");
00640 
00641     // Label & Entry: Direction scale factor
00642     gwLDirectionScale = gtk_label_new(cpLDirectionScaleTxt);
00643     gtk_label_set_justify(GTK_LABEL(gwLDirectionScale), GTK_JUSTIFY_LEFT);
00644     gtk_table_attach(GTK_TABLE(gwTable4), gwLDirectionScale,
00645         3, 4, 0, 1,
00646         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00647         (GtkAttachOptions) 0,
00648         DGUI_PADDING / 2, 0);
00649     gtk_widget_show(gwLDirectionScale);
00650     gwEDirectionScale = gtk_entry_new();
00651     gtk_table_attach(GTK_TABLE(gwTable4), gwEDirectionScale,
00652         3, 4, 1, 2,
00653         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00654         (GtkAttachOptions) 0,
00655         DGUI_PADDING / 2, 0);
00656     gtk_widget_show(gwEDirectionScale);
00657     gtk_widget_set_usize(gwEDirectionScale, DGUI_ENTRY_WIDTH,
00658         gwEDirectionScale->requisition.height);
00659     g_snprintf(cpConvBuf, DGUI_CONV_BUF_SIZE, "%i", iDirectionScale);
00660     gtk_entry_set_text(GTK_ENTRY(gwEDirectionScale), cpConvBuf);
00661 
00662     gwCBSaving = gtk_check_button_new_with_label(cpCBSavingTxt);
00663     gtk_table_attach(GTK_TABLE(gwTable4), gwCBSaving,
00664         4, 5, 0, 1,
00665         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00666         DGUI_PADDING / 2, 0);
00667     gtk_widget_show(gwCBSaving);
00668 
00669     // Button: Save
00670     gwBSave = gtk_button_new_with_label(cpBSaveTxt);
00671     gtk_table_attach(GTK_TABLE(gwTable4), gwBSave,
00672         4, 5, 1, 2,
00673         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00674         DGUI_PADDING / 2, 0);
00675     gtk_widget_show(gwBSave);
00676 
00677     // FileSelection: Save
00678     gwFSSave = gtk_file_selection_new(cpFSSaveTxt);
00679 
00680     return true;
00681 }
00682 
00683 
00684 bool clGUIDir::BuildTableWorm ()
00685 {
00686     // rows, columns, homogenous
00687     gwTableWorm = gtk_table_new(2, 2, FALSE);
00688     // box, child, expand, fill, padding
00689     gtk_box_pack_start(GTK_BOX(gwVBox), gwTableWorm, FALSE, FALSE, 0);
00690     gtk_widget_show(gwTableWorm);
00691 
00692     // HorizontalRuler: Direction
00693     gwHRDirection = gtk_hruler_new();
00694     gtk_ruler_set_metric(GTK_RULER(gwHRDirection), GTK_PIXELS);
00695     // ruler, lower, upper, position, max size
00696     gtk_ruler_set_range(GTK_RULER(gwHRDirection), -90.0, 90.0, 0.0, 180.0);
00697     gtk_table_attach(GTK_TABLE(gwTableWorm), gwHRDirection,
00698         1, 2, 0, 1,
00699         (GtkAttachOptions) (GTK_EXPAND|GTK_SHRINK),  // GTK_FILL
00700         (GtkAttachOptions) 0,
00701         0, 0);
00702     gtk_widget_show(gwHRDirection);
00703 
00704     // VerticalRuler: Time
00705     gwVRTime = gtk_vruler_new();
00706     gtk_ruler_set_metric(GTK_RULER(gwVRTime), GTK_PIXELS);
00707     // ruler, lower, upper, position, max size
00708     gtk_ruler_set_range(GTK_RULER(gwVRTime), 0.0, 
00709         (gfloat) iHistoryLines / (gfloat) 60.0 , 0.0, 1.0);
00710     gtk_table_attach(GTK_TABLE(gwTableWorm), gwVRTime,
00711         0, 1, 1, 2,
00712         (GtkAttachOptions) 0,
00713         (GtkAttachOptions) (GTK_EXPAND|GTK_SHRINK),  // GTK_FILL
00714         0, 0);
00715     gtk_widget_show(gwVRTime);
00716 
00717     // DrawingArea: Direction display (Worm)
00718     gwDAWorm = gtk_drawing_area_new();
00719     // drawing area, width, height
00720     gtk_drawing_area_size(GTK_DRAWING_AREA(gwDAWorm), 180 * iDirectionScale, 
00721         iHistoryLines);
00722     gtk_table_attach(GTK_TABLE(gwTableWorm), gwDAWorm,
00723         1, 2, 1, 2,
00724         (GtkAttachOptions) (GTK_EXPAND|GTK_SHRINK),  // GTK_FILL
00725         (GtkAttachOptions) (GTK_EXPAND|GTK_SHRINK),  // GTK_FILL
00726         0, 0);
00727     gtk_widget_show(gwDAWorm);
00728 
00729     return true;
00730 }
00731 
00732 
00733 bool clGUIDir::BuildDrawingPrims ()
00734 {
00735     // Create graphics contexts
00736     ggcWormBG = gdk_gc_new(gwDAWorm->window);
00737     gdk_rgb_gc_set_foreground(ggcWormBG, DGUI_WORM_BG);
00738     gdk_rgb_gc_set_background(ggcWormBG, DGUI_WORM_BG);
00739     gdk_gc_set_function(ggcWormBG, GDK_COPY);
00740     gdk_gc_set_fill(ggcWormBG, GDK_SOLID);
00741 
00742     ggcWormFG = gdk_gc_new(gwDAWorm->window);
00743     gdk_rgb_gc_set_foreground(ggcWormFG, DGUI_WORM_FG);
00744     gdk_rgb_gc_set_background(ggcWormFG, DGUI_WORM_BG);
00745     gdk_gc_set_function(ggcWormFG, GDK_COPY);
00746     gdk_gc_set_fill(ggcWormFG, GDK_SOLID);
00747 
00748     // Create cursors
00749     gcCrossHair = gdk_cursor_new(GDK_CROSSHAIR);
00750 
00751     // Create specified palette for direction display
00752     switch (iPalette)
00753     {
00754         case DGUI_PAL_BW:
00755             FBDir.PalGenBW();
00756             break;
00757         case DGUI_PAL_HSV:
00758             FBDir.PalGenHSV();
00759             break;
00760         case DGUI_PAL_LIGHT:
00761             FBDir.PalGenLight();
00762             break;
00763         case DGUI_PAL_TEMP:
00764             FBDir.PalGenTemp();
00765             break;
00766         case DGUI_PAL_DIR:
00767             FBDir.PalGenDir();
00768             break;
00769         case DGUI_PAL_GREEN:
00770             FBDir.PalGenGreen();
00771             break;
00772         case DGUI_PAL_GREEN2:
00773             FBDir.PalGenGreen2();
00774             break;
00775         case DGUI_PAL_PUREGREEN:
00776             FBDir.PalGenPureGreen();
00777             break;
00778         case DGUI_PAL_WB:
00779             FBDir.PalGenWB();
00780             break;
00781         default:
00782             FBDir.PalGenDir();
00783     }
00784 
00785     return true;
00786 }
00787 
00788 
00789 void clGUIDir::FreeDrawingPrims ()
00790 {
00791     gdk_cursor_destroy(gcCrossHair);
00792     gdk_gc_destroy(ggcWormBG);
00793     gdk_gc_destroy(ggcWormFG);
00794 }
00795 
00796 
00797 bool clGUIDir::ParseServerStr (char *cpHostRes, int *ipPortRes,
00798     const char *cpSourceStr)
00799 {
00800     char cpTempStr[DGUI_SERVER_MAXLEN + 1];
00801     char *cpTempHost;
00802     char *cpTempPort;
00803 
00804     strncpy(cpTempStr, cpSourceStr, DGUI_SERVER_MAXLEN);
00805     cpTempHost = strtok(cpTempStr, ": \t\n");
00806     if (cpTempHost != NULL)
00807     {
00808         strcpy(cpHostRes, cpTempHost);
00809         cpTempPort = strtok(NULL, " \t\n");
00810         if (cpTempPort != NULL)
00811         {
00812             *ipPortRes = atoi(cpTempPort);
00813             if (*ipPortRes > 0) return true;
00814         }
00815     }
00816     return false;
00817 }
00818 
00819 
00820 bool clGUIDir::InitConnection (const char *cpServerHost, int iServerPort)
00821 {
00822     char cpReqProcName[GLOBAL_HEADER_LEN];
00823 
00824     GetSettings();
00825     iSockH = SClient.Connect(cpServerHost, NULL, iServerPort);
00826     if (iSockH < 0) return false;
00827     g_print("Connection established - sending process request...\n");
00828     bConnected = true;
00829     SOp = new clSockOp(iSockH);
00830     switch (sDirRq.iAlgorithm)
00831     {
00832         case MSG_DIR_ALG_BEAM:
00833         case MSG_DIR_ALG_CORR:
00834         case (MSG_DIR_ALG_BEAM | MSG_DIR_ALG_CORR):
00835             strcpy(cpReqProcName, DGUI_REQ_PROC);
00836             break;
00837         case MSG_DIR_ALG_SPECT:
00838             strcpy(cpReqProcName, DGUI_REQ_PROC2);
00839             break;
00840         default:
00841             g_print("Unknown algorithm or combination!? This is bug.\n");
00842     }
00843     if (SOp->WriteN(cpReqProcName, GLOBAL_HEADER_LEN) < GLOBAL_HEADER_LEN)
00844         return false;
00845     g_print("Sending settings...\n");
00846     if (!SendSettings()) return false;
00847     iWormWidth = lResultCount * iDirectionScale;
00848     iWormHeight = iHistoryLines;
00849     FBDir.SetSize(iWormWidth, iWormHeight);
00850     //FBDir.Clear();
00851     lResultMsgBufSize = GLOBAL_HEADER_LEN + lResultCount * sizeof(GDT);
00852     ResultMsgBuf.Size(lResultMsgBufSize);
00853     Results.Size(lResultCount * sizeof(GDT));
00854     ScaledResults.Size(iWormWidth * sizeof(GDT));
00855     iClips = 0;
00856     gtk_drawing_area_size(GTK_DRAWING_AREA(gwDAWorm), iWormWidth, iWormHeight);
00857     gtk_widget_set_usize(gwHRDirection, iWormWidth,
00858         gwHRDirection->allocation.height);
00859     gtk_widget_set_usize(gwVRTime, gwVRTime->allocation.width, iWormHeight);
00860     gdk_draw_rgb_32_image(gwDAWorm->window, ggcWormFG,
00861         0, 0, iWormWidth, iWormHeight,
00862         GDK_RGB_DITHER_NONE, FBDir.GetCurPtr(0,0), FBDir.GetRowStride());
00863     giGdkTag = gdk_input_add(iSockH, GDK_INPUT_READ, WrapOnGdkInput, NULL);
00864     return true;
00865 }
00866 
00867 
00868 void clGUIDir::GetSettings ()
00869 {
00870     sscanf(gtk_entry_get_text(GTK_ENTRY(gwEDirectionScale)), "%i",
00871         &iDirectionScale);
00872     switch (GtkUtils.OptionMenuGetActive(gwOMAlgorithm, gwaMIAlgorithm, 
00873         DGUI_ALGORITHM_ITEMS))
00874     {
00875         case 0:
00876             sDirRq.iAlgorithm = MSG_DIR_ALG_BEAM;
00877             break;
00878         case 1:
00879             sDirRq.iAlgorithm = MSG_DIR_ALG_CORR;
00880             break;
00881         case 2:
00882             sDirRq.iAlgorithm = (MSG_DIR_ALG_BEAM | MSG_DIR_ALG_CORR);
00883             break;
00884         case 3:
00885             sDirRq.iAlgorithm = MSG_DIR_ALG_SPECT;
00886             break;
00887         default:
00888             sDirRq.iAlgorithm = MSG_DIR_ALG_BEAM;
00889     }
00890     sscanf(gtk_entry_get_text(GTK_ENTRY(gwESoundSpeed)), "%f",
00891         &sDirRq.fSoundSpeed);
00892     sscanf(gtk_entry_get_text(GTK_ENTRY(gwELowFrequencyLimit)), "%f",
00893         &sDirRq.fLowFreqLimit);
00894     sscanf(gtk_entry_get_text(GTK_ENTRY(gwEIntegrationTime)), "%f",
00895         &fIntegrationTime);
00896     sDirRq.fIntegrationTime = fIntegrationTime;
00897     gtk_ruler_set_range(GTK_RULER(gwVRTime), 0.0, 
00898         fIntegrationTime / 60.0 * iHistoryLines, 0.0, 
00899         fIntegrationTime / 60.0 * iHistoryLines);
00900     sDirRq.iScaling = GtkUtils.OptionMenuGetActive(gwOMScaling,
00901         gwaMIScaling, DGUI_SCALING_ITEMS);
00902     sscanf(gtk_entry_get_text(GTK_ENTRY(gwEScalingExponent)), "%f",
00903         &sDirRq.fScalingExp);
00904     sDirRq.iRemoveNoise = GtkUtils.OptionMenuGetActive(gwOMRemoveNoise,
00905         gwaMIRemoveNoise, DGUI_REMOVE_NOISE_ITEMS);
00906     sscanf(gtk_entry_get_text(GTK_ENTRY(gwEAlpha)), "%f",
00907         &sDirRq.fAlpha);
00908     sDirRq.lMeanLength = atol(gtk_entry_get_text(GTK_ENTRY(gwEMeanLength)));
00909     sDirRq.lGapLength = atol(gtk_entry_get_text(GTK_ENTRY(gwEGapLength)));
00910     sDirRq.bNormalize = 
00911         (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gwCBNormalize))) ?
00912         true : false;
00913     sDirRq.bDisableFilter = 
00914         (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gwCBNoFilter))) ?
00915         true : false;
00916     sscanf(gtk_entry_get_text(GTK_ENTRY(gwELeftDirection)), "%f",
00917         &fLeftDirDeg);
00918     sDirRq.fLeftDir = DSP.DegToRad(fLeftDirDeg);
00919     sscanf(gtk_entry_get_text(GTK_ENTRY(gwERightDirection)), "%f",
00920         &fRightDirDeg);
00921     sDirRq.fRightDir = DSP.DegToRad(fRightDirDeg);
00922     gtk_ruler_set_range(GTK_RULER(gwHRDirection), fLeftDirDeg, fRightDirDeg,
00923         0.0, fRightDirDeg - fLeftDirDeg);
00924     sscanf(gtk_entry_get_text(GTK_ENTRY(gwESectorCount)), "%li",
00925         &sDirRq.lSectorCount);
00926     lResultCount = sDirRq.lSectorCount;
00927 }
00928 
00929 
00930 bool clGUIDir::SendSettings ()
00931 {
00932     char cpMsgBuf[GLOBAL_HEADER_LEN];
00933 
00934     DirMsg.SetRequest(cpMsgBuf, &sDirRq);
00935     if (SOp->WriteN(cpMsgBuf, GLOBAL_HEADER_LEN) < GLOBAL_HEADER_LEN)
00936     {
00937         g_print("Error (%i) sending settings\n\n", SOp->GetErrno());
00938         return false;
00939     }
00940     g_print("Settings sent\n");
00941     return true;
00942 }
00943 
00944 
00945 void clGUIDir::PrintStatus ()
00946 {
00947     float fCursorDirection;
00948     time_t ttCurrentTime;
00949     time_t ttCursorTime;
00950     char cpTimeConv[DGUI_CONV_BUF_SIZE];
00951     char cpStatusBarTxt[DGUI_CONV_BUF_SIZE];
00952 
00953     if (sResultHeader.lSectorCount > 0 && iDirectionScale > 0)
00954     {
00955         fCursorDirection = ((fRightDirDeg - fLeftDirDeg) / 
00956             (sResultHeader.lSectorCount * iDirectionScale)) * iCursorX +
00957             fLeftDirDeg;
00958     }
00959     else
00960     {
00961         fCursorDirection = 0.0f;
00962     }
00963     time(&ttCurrentTime);
00964     ttCursorTime = (time_t) 
00965         (ttCurrentTime - iCursorY * fIntegrationTime + 0.5f);
00966     strftime(cpTimeConv, DGUI_CONV_BUF_SIZE,
00967         "%H:%M:%S", localtime(&ttCursorTime));
00968     g_snprintf(cpStatusBarTxt, DGUI_CONV_BUF_SIZE,
00969         "%.1f deg / %s / %.1f dB / %i clips", fCursorDirection, cpTimeConv,
00970         sResultHeader.fPeakLevel, iClips);
00971     gtk_statusbar_pop(GTK_STATUSBAR(gwStatusBar), guSbCtxt);
00972     gtk_statusbar_push(GTK_STATUSBAR(gwStatusBar), guSbCtxt, cpStatusBarTxt);
00973 }
00974 
00975 
00976 void clGUIDir::SaveInfo (const char *cpFileName, time_t ttStartTime)
00977 {
00978     char *cpFullFileName;
00979     char cpTime[20];
00980     FILE *fileInfo;
00981 
00982     cpFullFileName = g_strdup_printf("%s.inf", cpFileName);
00983     fileInfo = fopen(cpFullFileName, FB_TIFF_MODE);
00984     g_free(cpFullFileName);
00985     if (fileInfo == NULL) return;
00986     strftime(cpTime, 20, "%Y/%m/%d %H:%M:%S", localtime(&ttStartTime));
00987     fprintf(fileInfo, "Time: %s\n", cpTime);
00988     fprintf(fileInfo, "LeftDir: %f\n", sDirRq.fLeftDir);
00989     fprintf(fileInfo, "RightDir: %f\n", sDirRq.fRightDir);
00990     fprintf(fileInfo, "IntTime: %f\n", sResultHeader.fIntegrationTime);
00991     fprintf(fileInfo, "HighFreq: %f\n", sResultHeader.fHighFreqLimit);
00992     fprintf(fileInfo, "Sectors: %li\n", sResultHeader.lSectorCount);
00993     fclose(fileInfo);
00994 }
00995 
00996 
00997 void clGUIDir::StartNewImgFile ()
00998 {
00999     char *cpCompleteFileName;
01000 
01001     FBDir.StopSaveToFile();
01002     cpCompleteFileName = g_strdup_printf("%s%02i.tif",
01003         strImgFileName.c_str(), iImgCount);
01004     if (!FBDir.StartSaveToFile(cpCompleteFileName, iCompressMode,
01005         iJPEGQuality, "Direction", FB_TIFF_CONT_VERTICAL))
01006     {
01007         g_warning("Saving to file failed!");
01008         gtk_toggle_button_toggled(GTK_TOGGLE_BUTTON(gwCBSaving));
01009         bSaving = false;
01010     }
01011     SaveInfo(cpCompleteFileName, time(NULL));
01012     g_free(cpCompleteFileName);
01013 }
01014 
01015 
01016 clGUIDir::clGUIDir (int *ipArgC, char ***cpapArgV)
01017 {
01018     bRun = true;
01019     bConnected = false;
01020     bFreezed = false;
01021     glServers = NULL;
01022     g_print("%s GUI v%i.%i.%i\n", cpWindowTxt,
01023         DGUI_VER_MAJ, DGUI_VER_MIN, DGUI_VER_PL);
01024     g_print("Copyright (C) 2000-2001 Jussi Laako\n\n");
01025     g_print("Gtk+ version %i.%i.%i\n", gtk_major_version, gtk_minor_version,
01026         gtk_micro_version);
01027     g_print("Locale set to %s\n", gtk_set_locale());
01028     gtk_init(ipArgC, cpapArgV);
01029     gdk_rgb_init();
01030     gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
01031     gtk_widget_set_default_visual(gdk_rgb_get_visual());
01032     Cfg = new clCfgFile(DGUI_CFGFILE);
01033     if (!Cfg->GetInt("Palette", &iPalette))
01034         iPalette = DGUI_PAL_DIR;
01035 }
01036 
01037 
01038 clGUIDir::~clGUIDir ()
01039 {
01040     delete Cfg;
01041 }
01042 
01043 
01044 int clGUIDir::Exec ()
01045 {
01046     if (!Cfg->GetInt("HistoryLines", &iHistoryLines))
01047         iHistoryLines = DGUI_DEF_LINES;
01048     if (!Cfg->GetInt("DirectionScale", &iDirectionScale))
01049         iDirectionScale = 1;
01050     if (!Cfg->GetInt("Palette", &iPalette))
01051         iPalette = 0;
01052     if (!Cfg->GetFlt("SoundSpeed", &fSoundSpeed))
01053         fSoundSpeed = DGUI_DEF_SOUNDSPEED;
01054     if (!Cfg->GetInt("TIFFCompression", &iTIFFCompression))
01055         iTIFFCompression = 0;
01056     if (!Cfg->GetInt("JPEGQuality", &iJPEGQuality))
01057         iJPEGQuality = 100;
01058     if (!Cfg->GetInt("ContSaveScans", &iContSaveScans))
01059         iContSaveScans = 1024;
01060     switch (iTIFFCompression)
01061     {
01062         case 0:
01063             iCompressMode = FB_TIFF_COMPRESS_NONE;
01064             break;
01065         case 1:
01066             iCompressMode = FB_TIFF_COMPRESS_RLE;
01067             break;
01068         case 2:
01069             iCompressMode = FB_TIFF_COMPRESS_LZW;
01070             break;
01071         case 3:
01072             iCompressMode = FB_TIFF_COMPRESS_JPEG;
01073             break;
01074         case 4:
01075             iCompressMode = FB_TIFF_COMPRESS_DEFLATE;
01076             break;
01077         default:
01078             iCompressMode = FB_TIFF_COMPRESS_NONE;
01079     }
01080     iWormWidth = 180 * iDirectionScale;
01081     iWormHeight = iHistoryLines;
01082     FBDir.SetSize(iWormWidth, iWormHeight);
01083     FBDir.Clear();
01084     if (!Build())
01085     {
01086         g_print("User interface creation failed\n");
01087         return 1;
01088     }
01089     if (!ConnectSignals())
01090     {
01091         g_print("User interface signal connection failed\n");
01092         return 1;
01093     }
01094     gtk_main();
01095     FreeDrawingPrims();
01096     return 0;
01097 }
01098 
01099 
01100 gint clGUIDir::OnDelete (GtkWidget *gwSender, GdkEventAny *geaEvent)
01101 {
01102     bRun = false;
01103     if (bSaving)
01104     {
01105         FBDir.StopSaveToFile();
01106     }
01107     gtk_main_quit();
01108     return 0;
01109 }
01110 
01111 
01112 void clGUIDir::OnHideToggled (GtkToggleButton *gtbSender, gpointer gpData)
01113 {
01114     if (gtk_toggle_button_get_active(gtbSender))
01115     {
01116         gtk_widget_hide(gwTable1);
01117         gtk_widget_hide(gwTable2);
01118         gtk_widget_hide(gwTable3);
01119         gtk_widget_hide(gwTable4);
01120     }
01121     else
01122     {
01123         gtk_widget_show(gwTable1);
01124         gtk_widget_show(gwTable2);
01125         gtk_widget_show(gwTable3);
01126         gtk_widget_show(gwTable4);
01127     }
01128 }
01129 
01130 
01131 gint clGUIDir::OnConnectClick (GtkWidget *gwSender, gpointer gpData)
01132 {
01133     char cpHost[DGUI_SERVER_MAXLEN + 1];
01134     int iPort;
01135 
01136     if (bConnected)
01137     {
01138         gdk_input_remove(giGdkTag);
01139         SOp->Shutdown(2);
01140         delete SOp;
01141         bConnected = false;
01142     }
01143     if (gwSender == gwBConnect)
01144     {
01145         if (ParseServerStr(cpHost, &iPort,
01146             gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(gwCServer)->entry))))
01147         {
01148             g_print("Connecting to host %s port %i...\n",
01149                 cpHost, iPort);
01150             if (InitConnection(cpHost, iPort))
01151             {
01152                 g_print("OK\n\n");
01153             }
01154             else
01155             {
01156                 g_print("Failed\n\n");
01157             }
01158         }
01159         else
01160         {
01161             g_print("Incorrect server entry! Format: <host>:<port>\n");
01162         }
01163     }
01164 
01165     return 0;
01166 }
01167 
01168 
01169 void clGUIDir::OnFreezeToggled (GtkToggleButton *gtbSender, gpointer gpData)
01170 {
01171     bFreezed = (gtk_toggle_button_get_active(gtbSender)) ? true : false;
01172 }
01173 
01174 
01175 gint clGUIDir::OnExposeWorm(GtkWidget *gwSender, GdkEventExpose *geeEvent)
01176 {
01177     int iExposeX;
01178     int iExposeY;
01179     int iExposeWidth;
01180     int iExposeHeight;
01181 
01182     iExposeX = (geeEvent->area.x >= iWormWidth) ? 0 : geeEvent->area.x;
01183     iExposeY = (geeEvent->area.y >= iWormHeight) ? 0 : geeEvent->area.y;
01184     iExposeWidth = (geeEvent->area.width > iWormWidth) ? 
01185         iWormWidth : geeEvent->area.width;
01186     iExposeHeight = (geeEvent->area.height > iWormHeight) ?
01187         iWormHeight : geeEvent->area.height;
01188     gdk_draw_rgb_32_image(gwDAWorm->window, ggcWormFG,
01189         iExposeX, iExposeY, iExposeWidth, iExposeHeight,
01190         GDK_RGB_DITHER_NONE, FBDir.GetCurPtr(iExposeX, iExposeY),
01191         FBDir.GetRowStride());
01192     return 0;
01193 }
01194 
01195 
01196 gint clGUIDir::OnMotionWorm (GtkWidget *gwSender, GdkEventMotion *gemEvent)
01197 {
01198     iCursorX = (int) gemEvent->x;
01199     iCursorY = (int) gemEvent->y;
01200     PrintStatus();
01201     return 0;
01202 }
01203 
01204 
01205 gint clGUIDir::OnPaletteActivate (GtkWidget *gwSender, gpointer gpData)
01206 {
01207     int iPalType;
01208 
01209     if (gwSender == gwaMIPalette[DGUI_PAL_BW])
01210     {
01211         FBDir.PalGenBW();
01212     }
01213     else if (gwSender == gwaMIPalette[DGUI_PAL_HSV])
01214     {
01215         FBDir.PalGenHSV();
01216     }
01217     else if (gwSender == gwaMIPalette[DGUI_PAL_LIGHT])
01218     {
01219         FBDir.PalGenLight();
01220     }
01221     else if (gwSender == gwaMIPalette[DGUI_PAL_TEMP])
01222     {
01223         FBDir.PalGenTemp();
01224     }
01225     else if (gwSender == gwaMIPalette[DGUI_PAL_DIR])
01226     {
01227         FBDir.PalGenDir();
01228     }
01229     else if (gwSender == gwaMIPalette[DGUI_PAL_GREEN])
01230     {
01231         FBDir.PalGenGreen();
01232     }
01233     else if (gwSender == gwaMIPalette[DGUI_PAL_GREEN2])
01234     {
01235         FBDir.PalGenGreen2();
01236     }
01237     else if (gwSender == gwaMIPalette[DGUI_PAL_PUREGREEN])
01238     {
01239         FBDir.PalGenPureGreen();
01240     }
01241     else if (gwSender == gwaMIPalette[DGUI_PAL_WB])
01242     {
01243         FBDir.PalGenWB();
01244     }
01245     else
01246     {
01247         Cfg->GetInt("Palette", &iPalType);
01248         switch (iPalType)
01249         {
01250             case DGUI_PAL_BW:
01251                 FBDir.PalGenBW();
01252                 break;
01253             case DGUI_PAL_HSV:
01254                 FBDir.PalGenHSV();
01255                 break;
01256             case DGUI_PAL_LIGHT:
01257                 FBDir.PalGenLight();
01258                 break;
01259             case DGUI_PAL_TEMP:
01260                 FBDir.PalGenTemp();
01261                 break;
01262             case DGUI_PAL_DIR:
01263                 FBDir.PalGenDir();
01264                 break;
01265             case DGUI_PAL_GREEN:
01266                 FBDir.PalGenGreen();
01267                 break;
01268             default:
01269                 FBDir.PalGenBW();
01270         }
01271     }
01272 
01273     return 0;
01274 }
01275 
01276 
01277 void clGUIDir::OnSaveClicks (GtkWidget *gwSender, gpointer gpData)
01278 {
01279     int iAction = GPOINTER_TO_INT(gpData);
01280     const char *cpFileName;
01281     char *cpParseFileName;
01282     char *cpParsePtr;
01283     char *cpCompleteFileName;
01284 
01285     bSaving = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gwCBSaving)) ?
01286         true : false;
01287     switch (iAction)
01288     {
01289         case 0:
01290             gtk_widget_hide(gwFSSave);
01291             if (bSaving)
01292             {
01293                 gtk_toggle_button_toggled(GTK_TOGGLE_BUTTON(gwCBSaving));
01294             }
01295             break;
01296         case 1:
01297             gtk_widget_hide(gwFSSave);
01298             cpFileName =
01299                 gtk_file_selection_get_filename(GTK_FILE_SELECTION(gwFSSave));
01300             if (cpFileName == NULL) break;
01301             cpParseFileName = g_strdup(cpFileName);
01302             cpParsePtr = strtok(cpParseFileName, ".");
01303             if (cpParsePtr != NULL)
01304             {
01305                 strImgFileName = cpParsePtr;
01306             }
01307             g_free(cpParseFileName);
01308             if (cpParsePtr == NULL) break;
01309             if (!bSaving)
01310             {
01311                 cpCompleteFileName = g_strdup_printf("%s.tif",
01312                     strImgFileName.c_str());
01313                 /*if (!FBDir.SaveToFile(cpCompleteFileName, iCompressMode, 
01314                     iJPEGQuality, "Direction", 
01315                     sDirRq.fLeftDir, sDirRq.fRightDir,
01316                     -(iWormHeight * sResultHeader.fIntegrationTime), 0))*/
01317                 if (!FBDir.SaveToFile(cpCompleteFileName, iCompressMode, 
01318                     iJPEGQuality, "Direction"))
01319                 {
01320                     g_warning("Saving to file failed!");
01321                 }
01322                 SaveInfo(cpCompleteFileName, time(NULL) - (time_t)
01323                     (FBDir.GetHeight() * sResultHeader.fIntegrationTime + 0.5f));
01324             }
01325             else
01326             {
01327                 iScanCount = 0;
01328                 iImgCount = 0;
01329                 cpCompleteFileName = g_strdup_printf("%s%02i.tif",
01330                     strImgFileName.c_str(), iImgCount);
01331                 if (!FBDir.StartSaveToFile(cpCompleteFileName, iCompressMode,
01332                     iJPEGQuality, "Direction", FB_TIFF_CONT_VERTICAL))
01333                 {
01334                     g_warning("Saving to file failed!");
01335                     gtk_toggle_button_toggled(GTK_TOGGLE_BUTTON(gwCBSaving));
01336                 }
01337                 SaveInfo(cpCompleteFileName, time(NULL));
01338             }
01339             g_free(cpCompleteFileName);
01340             break;
01341         case 2:
01342             if (!bSaving)
01343             {
01344                 gtk_widget_show(gwFSSave);
01345             }
01346             break;
01347         case 3:
01348             if (bSaving)
01349             {
01350                 gtk_widget_show(gwFSSave);
01351             }
01352             else
01353             {
01354                 FBDir.StopSaveToFile();
01355             }
01356             break;
01357     }
01358 }
01359 
01360 
01361 void clGUIDir::OnGdkInput (gpointer gpData, gint giSource,
01362     GdkInputCondition gicCondition)
01363 {
01364     int iReadRes;
01365     char cpConvBuf[DGUI_CONV_BUF_SIZE];
01366     GDT *fpResults = Results;
01367     GDT *fpScaledResults = ScaledResults;
01368     
01369     if (!bRun) return;
01370     G_LOCK(gmInputMutex);
01371     iReadRes = SOp->ReadN(ResultMsgBuf, lResultMsgBufSize);
01372     if (iReadRes == lResultMsgBufSize)
01373     {
01374         if (bFreezed)
01375         {
01376             G_UNLOCK(gmInputMutex);
01377             return;
01378         }
01379         DirMsg.GetResult(ResultMsgBuf, &sResultHeader, fpResults);
01380         if (sResultHeader.lSectorCount > lResultCount)
01381         {
01382             g_print("Fatal error: more sectors than requested!\n\n");
01383             gdk_input_remove(giGdkTag);
01384             gtk_main_quit();
01385             exit(2);
01386         }
01387         //g_print("Peak level: %f dB\n", sResultHeader.fPeakLevel);
01388         if (sResultHeader.fPeakLevel >= 0.0f) iClips++;
01389         DSP.InterpolateAvg(fpScaledResults, fpResults, iDirectionScale,
01390             lResultCount);
01391         FBDir.DrawLine(fpScaledResults);
01392         gdk_window_copy_area(gwDAWorm->window, ggcWormFG,
01393             0, 1,
01394             gwDAWorm->window,
01395             0, 0, iWormWidth, iWormHeight - 1);
01396         gdk_draw_rgb_32_image(gwDAWorm->window, ggcWormFG,
01397             0, 0, iWormWidth, 1,
01398             GDK_RGB_DITHER_NONE,
01399             FBDir.GetCurPtr(0,0), FBDir.GetRowStride());
01400         PrintStatus();
01401         if (fIntegrationTime != sResultHeader.fIntegrationTime)
01402         {
01403             fIntegrationTime = sResultHeader.fIntegrationTime;
01404             gtk_ruler_set_range(GTK_RULER(gwVRTime), 0.0,
01405                 fIntegrationTime / 60.0 * iHistoryLines, 0.0,
01406                 fIntegrationTime / 60.0 * iHistoryLines);
01407             g_snprintf(cpConvBuf, DGUI_CONV_BUF_SIZE, "%g",
01408                 fIntegrationTime);
01409             gtk_entry_set_text(GTK_ENTRY(gwEIntegrationTime), cpConvBuf);
01410         }
01411     }
01412     else if (iReadRes > 0)
01413     {
01414         g_print("Error %i while reading result data; disconnecting\n\n",
01415             SOp->GetErrno());
01416         gdk_input_remove(giGdkTag);
01417         SOp->Shutdown(2);
01418         delete SOp;
01419         bConnected = false;
01420     }
01421     else
01422     {
01423         g_print("Warning: clGUIDir::OnGdkInput() called without data,\n");
01424         g_print("         server disconnected?\n");
01425         gdk_input_remove(giGdkTag);
01426         delete SOp;
01427         bConnected = false;
01428     }
01429     if (bSaving)
01430     {
01431         iScanCount++;
01432         if (iScanCount >= iContSaveScans)
01433         {
01434             iImgCount++;
01435             StartNewImgFile();
01436             iScanCount = 0;
01437         }
01438     }
01439     G_UNLOCK(gmInputMutex);
01440 }
01441 

Generated on Sun Oct 26 19:11:20 2003 for HASAS by doxygen 1.3.3