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

GUILevel.cc

Go to the documentation of this file.
00001 /*
00002 
00003     GUI for level server
00004     Copyright (C) 2000-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 <stdlib.h>
00024 #include <string.h>
00025 #include <signal.h>
00026 #include <unistd.h>
00027 #include <math.h>
00028 #include <float.h>
00029 #include <gtk/gtk.h>
00030 #include <gdk/gdkrgb.h>
00031 
00032 #include "GUILevel.hh"
00033 
00034 
00035 G_LOCK_DEFINE_STATIC(gmInputMutex);
00036 
00037 static const char *cpWindowTxt = "Level";
00038 // Table 1
00039 static const char *cpLServerTxt = "Server";
00040 static const char *cpaLChannelTxt[] = { "Channel", "Direction" };
00041 static const char *cpBConnectTxt = "Connect";
00042 // Table 2
00043 static const char *cpLAlgorithmTxt = "Algorithm";
00044 static const char *cpaLAlgorithmMenu[] = { "Peak", "RMS", "Mean", "Median",
00045     "StdDev" };
00046 static const char *cpLIntegrationTimeTxt = "Integration time";
00047 static const char *cpLLowFrequencyTxt = "Lower frequency";
00048 static const char *cpLHighFrequencyTxt = "Higher frequency";
00049 static const char *cpLDisplayLowTxt = "Display low limit";
00050 static const char *cpLDisplayHighTxt = "Display high limit";
00051 
00052 clGUILevel GUILevel;
00053 
00054 
00055 int main (int argc, char *argv[])
00056 {
00057     signal(SIGPIPE, SIG_IGN);
00058     signal(SIGFPE, SIG_IGN);
00059     return GUILevel.Main(&argc, &argv);
00060 }
00061 
00062 
00063 gboolean WrapOnDelete (GtkWidget *gwSender, GdkEvent *geEvent, 
00064     gpointer gpData)
00065 {
00066     return GUILevel.OnDelete(gwSender, geEvent, gpData);
00067 }
00068 
00069 
00070 void WrapOnConnectClick (GtkButton *gbSender, gpointer gpData)
00071 {
00072     GUILevel.OnConnectClick(gbSender, gpData);
00073 }
00074 
00075 
00076 gboolean WrapOnSofarExpose (GtkWidget *gwSender, GdkEventExpose *geeEvent,
00077     gpointer gpData)
00078 {
00079     return GUILevel.OnSofarExpose(gwSender, geeEvent, gpData);
00080 }
00081 
00082 
00083 gboolean WrapOnSofarMotion (GtkWidget *gwSender, GdkEventMotion *gemEvent,
00084     gpointer gpData)
00085 {
00086     return GUILevel.OnSofarMotion(gwSender, gemEvent, gpData);
00087 }
00088 
00089 
00090 gboolean WrapOnSofarConfigure (GtkWidget *gwSender, 
00091     GdkEventConfigure *gecEvent, gpointer gpData)
00092 {
00093     return GUILevel.OnSofarConfigure(gwSender, gecEvent, gpData);
00094 }
00095 
00096 
00097 void WrapOnGdkInput (gpointer gpData, gint iSource, 
00098     GdkInputCondition gicCondition)
00099 {
00100     GUILevel.OnGdkInput(gpData, iSource, gicCondition);
00101 }
00102 
00103 
00104 bool clGUILevel::GetCfg ()
00105 {
00106     CfgFile.SetFileName(GUILEV_CFGFILE);
00107     CfgFile.GetFlt("DisplayLow", &fDisplayLow);
00108     CfgFile.GetFlt("DisplayHigh", &fDisplayHigh);
00109     CfgFile.GetFlt("IntegrationTime", &sRequest.fIntegrationTime);
00110     if (!CfgFile.GetInt("BeamCount", &iBeamCount))
00111         iBeamCount = 0;
00112     return true;
00113 }
00114 
00115 
00116 bool clGUILevel::Build ()
00117 {
00118     gwWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00119     gtk_window_set_title(GTK_WINDOW(gwWindow), cpWindowTxt);
00120     // shrink, grow, auto-shrink
00121     gtk_window_set_policy(GTK_WINDOW(gwWindow), TRUE, TRUE, FALSE);
00122     // homogenous, spacing
00123     gwVBox = gtk_vbox_new(FALSE, GUILEV_WSPACING);
00124     gtk_container_add(GTK_CONTAINER(gwWindow), gwVBox);
00125     gtk_widget_show(gwVBox);
00126     if (!BuildTable1()) return false;
00127     if (!BuildTable2()) return false;
00128     if (!BuildSofar()) return false;
00129     gwStatusBar = gtk_statusbar_new();
00130     // box, child, expand, fill, padding
00131     gtk_box_pack_start(GTK_BOX(gwVBox), gwStatusBar, FALSE, FALSE, 0);
00132     gtk_widget_show(gwStatusBar);
00133     guSbCtxt = gtk_statusbar_get_context_id(GTK_STATUSBAR(gwStatusBar),
00134         "Status");
00135     gtk_statusbar_push(GTK_STATUSBAR(gwStatusBar), guSbCtxt, "");
00136     if (!ConnectSignals()) return false;
00137     gtk_widget_show(gwWindow);
00138     if (!BuildDrawingPrims()) return false;
00139     gdk_window_set_cursor(gwDASofar->window, gcCrossHair);
00140     return true;
00141 }
00142 
00143 
00144 bool clGUILevel::BuildTable1 ()
00145 {
00146     // rows, columns, homogenous
00147     gwTable1 = gtk_table_new(2, 3, FALSE);
00148     // box, child, expand, fill, padding
00149     gtk_box_pack_start(GTK_BOX(gwVBox), gwTable1, FALSE, FALSE, 0);
00150     gtk_widget_show(gwTable1);
00151 
00152     // - Label & Combo: Server
00153     gwLServer = gtk_label_new(cpLServerTxt);
00154     gtk_label_set_justify(GTK_LABEL(gwLServer), GTK_JUSTIFY_LEFT);
00155     gtk_table_attach(GTK_TABLE(gwTable1), gwLServer,
00156         0, 1, 0, 1,
00157         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00158         (GtkAttachOptions) 0,
00159         GUILEV_WSPACING / 2, 0);
00160     gtk_widget_show(gwLServer);
00161     gwCServer = gtk_combo_new();
00162     gtk_entry_set_max_length(GTK_ENTRY(GTK_COMBO(gwCServer)->entry),
00163         GUILEV_SERVER_MAXLEN);
00164     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(gwCServer)->entry),
00165         "127.0.0.1:30001");
00166     // table, child, left attach, right attach, top attach, bottom attach,
00167     // x-options, y-options, x-padding, y-padding
00168     gtk_table_attach(GTK_TABLE(gwTable1), gwCServer,
00169         0, 1, 1, 2,
00170         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00171         (GtkAttachOptions) 0,
00172         GUILEV_WSPACING / 2, 0);
00173     gtk_widget_show(gwCServer);
00174     GtkUtils.ComboListFromFile(gwCServer, &glServer, GUILEV_HOSTFILE);
00175 
00176     // - Label & SpinButton: Channel
00177     if (iBeamCount)
00178         gwLChannel = gtk_label_new(cpaLChannelTxt[1]);
00179     else
00180         gwLChannel = gtk_label_new(cpaLChannelTxt[0]);
00181     gtk_label_set_justify(GTK_LABEL(gwLChannel), GTK_JUSTIFY_LEFT);
00182     gtk_table_attach(GTK_TABLE(gwTable1), gwLChannel,
00183         1, 2, 0, 1,
00184         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00185         GUILEV_WSPACING / 2, 0);
00186     gtk_widget_show(gwLChannel);
00187     if (iBeamCount)
00188     {
00189         // value, lower limit, upper limit, step increment, page increment,
00190         // page size
00191         goAChannel = gtk_adjustment_new(0.0, -90.0, 90.0, 1.0, 1.0, 1.0);
00192         // adjustment, climb rate, digits
00193         gwSBChannel = gtk_spin_button_new(GTK_ADJUSTMENT(goAChannel), 1.0, 1);
00194     }
00195     else
00196     {
00197         // value, lower limit, upper limit, step increment, page increment,
00198         // page size
00199         goAChannel = gtk_adjustment_new(1.0, GUILEV_CH_LOWER, GUILEV_CH_UPPER, 
00200             1.0, 1.0, 1.0);
00201         // adjustment, climb rate, digits
00202         gwSBChannel = gtk_spin_button_new(GTK_ADJUSTMENT(goAChannel), 1.0, 0);
00203     }
00204     gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(gwSBChannel), TRUE);
00205     gtk_table_attach(GTK_TABLE(gwTable1), gwSBChannel,
00206         1, 2, 1, 2,
00207         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00208         GUILEV_WSPACING / 2, 0);
00209     gtk_widget_show(gwSBChannel);
00210 
00211     // - Button: Connect
00212     gwBConnect = gtk_button_new_with_label(cpBConnectTxt);
00213     gtk_table_attach(GTK_TABLE(gwTable1), gwBConnect,
00214         2, 3, 1, 2,
00215         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00216         GUILEV_WSPACING / 2, 0);
00217     gtk_widget_show(gwBConnect);
00218     
00219     return true;
00220 }
00221 
00222 
00223 bool clGUILevel::BuildTable2 ()
00224 {
00225     char *cpConvBuf;
00226 
00227     // rows, columns, homogenous
00228     gwTable2 = gtk_table_new(2, 6, FALSE);
00229     // box, child, expand, fill, padding
00230     gtk_box_pack_start(GTK_BOX(gwVBox), gwTable2, FALSE, FALSE, 0);
00231     gtk_widget_show(gwTable2);
00232 
00233     // Label & OptionMenu: Algorithm
00234     gwLAlgorithm = gtk_label_new(cpLAlgorithmTxt);
00235     gtk_label_set_justify(GTK_LABEL(gwLAlgorithm), GTK_JUSTIFY_LEFT);
00236     gtk_table_attach(GTK_TABLE(gwTable2), gwLAlgorithm,
00237         0, 1, 0, 1,
00238         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00239         GUILEV_WSPACING / 2, 0);
00240     gtk_widget_show(gwLAlgorithm);
00241     gwOMAlgorithm = gtk_option_menu_new();
00242     gtk_table_attach(GTK_TABLE(gwTable2), gwOMAlgorithm,
00243         0, 1, 1, 2,
00244         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00245         GUILEV_WSPACING / 2, 0);
00246     gtk_widget_show(gwOMAlgorithm);
00247     GtkUtils.BuildOptionMenu(gwOMAlgorithm, &gwMAlgorithm, gwaMIAlgorithm,
00248         cpaLAlgorithmMenu, GUILEV_ALGORITHM_ITEMS);
00249 
00250     // Label & Entry: Integration time
00251     gwLIntegrationTime = gtk_label_new(cpLIntegrationTimeTxt);
00252     gtk_label_set_justify(GTK_LABEL(gwLIntegrationTime), GTK_JUSTIFY_LEFT);
00253     gtk_table_attach(GTK_TABLE(gwTable2), gwLIntegrationTime,
00254         1, 2, 0, 1,
00255         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00256         (GtkAttachOptions) 0,
00257         GUILEV_WSPACING / 2, 0);
00258     gtk_widget_show(gwLIntegrationTime);
00259     gwEIntegrationTime = gtk_entry_new();
00260     gtk_table_attach(GTK_TABLE(gwTable2), gwEIntegrationTime,
00261         1, 2, 1, 2,
00262         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00263         (GtkAttachOptions) 0,
00264         GUILEV_WSPACING / 2, 0);
00265     gtk_widget_show(gwEIntegrationTime);
00266     gtk_widget_set_usize(gwEIntegrationTime, GUILEV_ENTRY_WIDTH,
00267         gwEIntegrationTime->requisition.height);
00268     cpConvBuf = g_strdup_printf("%g", sRequest.fIntegrationTime);
00269     gtk_entry_set_text(GTK_ENTRY(gwEIntegrationTime), cpConvBuf);
00270     g_free(cpConvBuf);
00271 
00272     // Label & Entry: Lower frequency
00273     gwLLowFrequency = gtk_label_new(cpLLowFrequencyTxt);
00274     gtk_label_set_justify(GTK_LABEL(gwLLowFrequency), GTK_JUSTIFY_LEFT);
00275     gtk_table_attach(GTK_TABLE(gwTable2), gwLLowFrequency,
00276         2, 3, 0, 1,
00277         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00278         (GtkAttachOptions) 0,
00279         GUILEV_WSPACING / 2, 0);
00280     gtk_widget_show(gwLLowFrequency);
00281     gwELowFrequency = gtk_entry_new();
00282     gtk_table_attach(GTK_TABLE(gwTable2), gwELowFrequency,
00283         2, 3, 1, 2,
00284         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00285         (GtkAttachOptions) 0,
00286         GUILEV_WSPACING / 2, 0);
00287     gtk_widget_show(gwELowFrequency);
00288     gtk_widget_set_usize(gwELowFrequency, GUILEV_ENTRY_WIDTH,
00289         gwELowFrequency->requisition.height);
00290 
00291     // Label & Entry: Higher frequency
00292     gwLHighFrequency = gtk_label_new(cpLHighFrequencyTxt);
00293     gtk_label_set_justify(GTK_LABEL(gwLHighFrequency), GTK_JUSTIFY_LEFT);
00294     gtk_table_attach(GTK_TABLE(gwTable2), gwLHighFrequency,
00295         3, 4, 0, 1,
00296         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00297         (GtkAttachOptions) 0,
00298         GUILEV_WSPACING / 2, 0);
00299     gtk_widget_show(gwLHighFrequency);
00300     gwEHighFrequency = gtk_entry_new();
00301     gtk_table_attach(GTK_TABLE(gwTable2), gwEHighFrequency,
00302         3, 4, 1, 2,
00303         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00304         (GtkAttachOptions) 0,
00305         GUILEV_WSPACING / 2, 0);
00306     gtk_widget_show(gwEHighFrequency);
00307     gtk_widget_set_usize(gwEHighFrequency, GUILEV_ENTRY_WIDTH,
00308         gwEHighFrequency->requisition.height);
00309 
00310     // Label & Entry: Display low limit
00311     gwLDisplayLow = gtk_label_new(cpLDisplayLowTxt);
00312     gtk_label_set_justify(GTK_LABEL(gwLDisplayLow), GTK_JUSTIFY_LEFT);
00313     gtk_table_attach(GTK_TABLE(gwTable2), gwLDisplayLow,
00314         4, 5, 0, 1,
00315         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00316         (GtkAttachOptions) 0,
00317         GUILEV_WSPACING / 2, 0);
00318     gtk_widget_show(gwLDisplayLow);
00319     gwEDisplayLow = gtk_entry_new();
00320     gtk_table_attach(GTK_TABLE(gwTable2), gwEDisplayLow,
00321         4, 5, 1, 2,
00322         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00323         (GtkAttachOptions) 0,
00324         GUILEV_WSPACING / 2, 0);
00325     gtk_widget_show(gwEDisplayLow);
00326     gtk_widget_set_usize(gwEDisplayLow, GUILEV_ENTRY_WIDTH,
00327         gwEDisplayLow->requisition.height);
00328     cpConvBuf = g_strdup_printf("%g", fDisplayLow);
00329     gtk_entry_set_text(GTK_ENTRY(gwEDisplayLow), cpConvBuf);
00330     g_free(cpConvBuf);
00331 
00332     // Label & Entry: Display high limit
00333     gwLDisplayHigh = gtk_label_new(cpLDisplayHighTxt);
00334     gtk_label_set_justify(GTK_LABEL(gwLDisplayHigh), GTK_JUSTIFY_LEFT);
00335     gtk_table_attach(GTK_TABLE(gwTable2), gwLDisplayHigh,
00336         5, 6, 0, 1,
00337         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00338         (GtkAttachOptions) 0,
00339         GUILEV_WSPACING / 2, 0);
00340     gtk_widget_show(gwLDisplayHigh);
00341     gwEDisplayHigh = gtk_entry_new();
00342     gtk_table_attach(GTK_TABLE(gwTable2), gwEDisplayHigh,
00343         5, 6, 1, 2,
00344         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00345         (GtkAttachOptions) 0,
00346         GUILEV_WSPACING / 2, 0);
00347     gtk_widget_show(gwEDisplayHigh);
00348     gtk_widget_set_usize(gwEDisplayHigh, GUILEV_ENTRY_WIDTH,
00349         gwEDisplayHigh->requisition.height);
00350     cpConvBuf = g_strdup_printf("%g", fDisplayHigh);
00351     gtk_entry_set_text(GTK_ENTRY(gwEDisplayHigh), cpConvBuf);
00352     g_free(cpConvBuf);
00353 
00354     return true;
00355 }
00356 
00357 
00358 bool clGUILevel::BuildSofar ()
00359 {
00360     // rows, columns, homogenous
00361     gwTableSofar = gtk_table_new(2, 2, FALSE);
00362     // box, child, expand, fill, padding
00363     gtk_box_pack_start(GTK_BOX(gwVBox), gwTableSofar, TRUE, TRUE, 0);
00364     gtk_widget_show(gwTableSofar);
00365 
00366     // Horizontal Ruler: Time
00367     gwHRTime = gtk_hruler_new();
00368     gtk_table_attach(GTK_TABLE(gwTableSofar), gwHRTime,
00369         1, 2, 0, 1,
00370         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00371         (GtkAttachOptions) 0,
00372         0, 0);
00373     gtk_widget_show(gwHRTime);
00374     gtk_ruler_set_metric(GTK_RULER(gwHRTime), GTK_PIXELS);
00375     // lower, upper, position, max size
00376     gtk_ruler_set_range(GTK_RULER(gwHRTime), -1.0, 0.0, 0.0, 1.0);
00377 
00378     // Vertical Ruler: Level
00379     gwVRLevel = gtk_vruler_new();
00380     gtk_table_attach(GTK_TABLE(gwTableSofar), gwVRLevel,
00381         0, 1, 1, 2,
00382         (GtkAttachOptions) 0,
00383         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00384         0, 0);
00385     gtk_widget_show(gwVRLevel);
00386     gtk_ruler_set_metric(GTK_RULER(gwVRLevel), GTK_PIXELS);
00387     // lower, upper, position, max size
00388     gtk_ruler_set_range(GTK_RULER(gwVRLevel), fDisplayHigh, fDisplayLow, 
00389         0.0, fabs(fDisplayHigh - fDisplayLow));
00390 
00391     gwDASofar = gtk_drawing_area_new();
00392     gtk_table_attach(GTK_TABLE(gwTableSofar), gwDASofar,
00393         1, 2, 1, 2,
00394         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00395         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00396         0, 0);
00397     gtk_drawing_area_size(GTK_DRAWING_AREA(gwDASofar), 
00398         GUILEV_SOFAR_WIDTH, GUILEV_SOFAR_HEIGHT);
00399     gtk_widget_show(gwDASofar);
00400     
00401     return true;
00402 }
00403 
00404 
00405 bool clGUILevel::ConnectSignals ()
00406 {
00407     gtk_signal_connect(GTK_OBJECT(gwWindow), "delete-event", 
00408         GTK_SIGNAL_FUNC(WrapOnDelete), NULL);
00409 
00410     gtk_signal_connect(GTK_OBJECT(gwBConnect), "clicked",
00411         GTK_SIGNAL_FUNC(WrapOnConnectClick), NULL);
00412 
00413     gtk_widget_add_events(gwDASofar, GDK_POINTER_MOTION_MASK);
00414     GtkUtils.ConnectMotionEvent(gwHRTime, gwDASofar);
00415     GtkUtils.ConnectMotionEvent(gwVRLevel, gwDASofar);
00416     gtk_signal_connect(GTK_OBJECT(gwDASofar), "expose-event", 
00417         GTK_SIGNAL_FUNC(WrapOnSofarExpose), NULL);
00418     gtk_signal_connect(GTK_OBJECT(gwDASofar), "motion-notify-event",
00419         GTK_SIGNAL_FUNC(WrapOnSofarMotion), NULL);
00420     gtk_signal_connect(GTK_OBJECT(gwDASofar), "configure-event",
00421         GTK_SIGNAL_FUNC(WrapOnSofarConfigure), NULL);
00422 
00423     return true;
00424 }
00425 
00426 
00427 bool clGUILevel::BuildDrawingPrims ()
00428 {
00429     ggcSofarBG = gdk_gc_new(gwDASofar->window);
00430     gdk_rgb_gc_set_foreground(ggcSofarBG, GUILEV_LINE_BG);
00431     gdk_rgb_gc_set_background(ggcSofarBG, GUILEV_LINE_BG);
00432     gdk_gc_set_function(ggcSofarBG, GDK_COPY);
00433     gdk_gc_set_fill(ggcSofarBG, GDK_SOLID);
00434 
00435     ggcSofarFG = gdk_gc_new(gwDASofar->window);
00436     gdk_rgb_gc_set_foreground(ggcSofarFG, GUILEV_LINE_FG);
00437     gdk_rgb_gc_set_background(ggcSofarFG, GUILEV_LINE_BG);
00438     gdk_gc_set_function(ggcSofarFG, GDK_COPY);
00439     gdk_gc_set_fill(ggcSofarFG, GDK_SOLID);
00440 
00441     gcCrossHair = gdk_cursor_new(GDK_CROSSHAIR);
00442 
00443     return true;
00444 }
00445 
00446 
00447 bool clGUILevel::ConnectToServer (const char *cpHostAddr, int iHostPort)
00448 {
00449     int iSockH;
00450     char cpReqProcName[GLOBAL_HEADER_LEN];
00451     
00452     iSockH = SClient.Connect(cpHostAddr, NULL, iHostPort);
00453     if (iSockH < 0) return false;
00454     SOp.SetHandle(iSockH);
00455     strcpy(cpReqProcName, GUILEV_REQ_PROC);
00456     if (SOp.WriteN(cpReqProcName, GLOBAL_HEADER_LEN) < GLOBAL_HEADER_LEN)
00457         return false;
00458     return true;
00459 }
00460 
00461 
00462 bool clGUILevel::SendSettings ()
00463 {
00464     float fDirection;
00465     char cpRequestMsg[GLOBAL_HEADER_LEN];
00466 
00467     if (iBeamCount)
00468     {
00469         fDirection = gtk_spin_button_get_value_as_float(
00470             GTK_SPIN_BUTTON(gwSBChannel)) + 90.0f;
00471         sRequest.iChannel = (int)
00472             (fDirection / (180.0f / (float) (iBeamCount - 1)));
00473         g_print("Channel: %i\n", sRequest.iChannel);
00474     }
00475     else
00476     {
00477         sRequest.iChannel = gtk_spin_button_get_value_as_int(
00478             GTK_SPIN_BUTTON(gwSBChannel)) - 1;
00479     }
00480     sRequest.iAlgorithm = GtkUtils.OptionMenuGetActive(gwOMAlgorithm,
00481         gwaMIAlgorithm, GUILEV_ALGORITHM_ITEMS);
00482     sRequest.fIntegrationTime = strtod(
00483         gtk_entry_get_text(GTK_ENTRY(gwEIntegrationTime)), NULL);
00484     sRequest.fLowFrequency = strtod(
00485         gtk_entry_get_text(GTK_ENTRY(gwELowFrequency)), NULL);
00486     sRequest.fHighFrequency = strtod(
00487         gtk_entry_get_text(GTK_ENTRY(gwEHighFrequency)), NULL);
00488     Msg.SetRequest(cpRequestMsg, &sRequest);
00489     if (SOp.WriteN(cpRequestMsg, GLOBAL_HEADER_LEN) < GLOBAL_HEADER_LEN)
00490         return false;
00491     return true;
00492 }
00493 
00494 
00495 void clGUILevel::DisplayResults ()
00496 {
00497     //long lXCntr;
00498     long lResultIdx;
00499     gint iPointY;
00500     float fScaler;
00501 
00502     fScaler = gwDASofar->allocation.height / fabs(fDisplayHigh - fDisplayLow);
00503     /*gdk_window_clear(gwDASofar->window);
00504     for (lXCntr = 0L; lXCntr < lResultCount; lXCntr++)
00505     {
00506         lResultIdx = lXCntr + lResultPos + 1;
00507         iPointY = (gint) (fabs(spResults[lResultIdx].fResult - fDisplayHigh) *
00508             fScaler + 0.5F);
00509         gdk_draw_line(gwDASofar->window, ggcSofarFG,
00510             lXCntr, iPointY,
00511             lXCntr, gwDASofar->allocation.height - 1);
00512     }*/
00513     gdk_window_copy_area(gwDASofar->window, ggcSofarFG,
00514         0, 0,
00515         gwDASofar->window,
00516         1, 0, gwDASofar->allocation.width - 1, gwDASofar->allocation.height);
00517     gdk_window_clear_area(gwDASofar->window, 
00518         gwDASofar->allocation.width - 1, 0,
00519         1, gwDASofar->allocation.height);
00520     lResultIdx = lResultCount + lResultPos;
00521     iPointY = (gint) (fabs(spResults[lResultIdx].fResult - fDisplayHigh) *
00522         fScaler + 0.5F);
00523     gdk_draw_line(gwDASofar->window, ggcSofarFG,
00524         gwDASofar->allocation.width - 1, iPointY,
00525         gwDASofar->allocation.width - 1, gwDASofar->allocation.height - 1);
00526 }
00527 
00528 
00529 void clGUILevel::InitializeDisplay ()
00530 {
00531     gfloat fTimeRange;
00532     char *cpConvBuf;
00533 
00534     fDisplayLow = strtod(gtk_entry_get_text(GTK_ENTRY(gwEDisplayLow)), NULL);
00535     fDisplayHigh = strtod(gtk_entry_get_text(GTK_ENTRY(gwEDisplayHigh)), NULL);
00536     fTimeRange = gwDASofar->allocation.width * 
00537         spResults[lResultPos].fIntegrationTime;
00538     gtk_ruler_set_range(GTK_RULER(gwHRTime), 
00539         -fTimeRange, 0.0, 
00540         0.0, fTimeRange);
00541     gtk_ruler_set_range(GTK_RULER(gwVRLevel),
00542         fDisplayHigh, fDisplayLow,
00543         0.0, fabs(fDisplayHigh - fDisplayLow));
00544     cpConvBuf = g_strdup_printf("%g", spResults[lResultPos].fIntegrationTime);
00545     gtk_entry_set_text(GTK_ENTRY(gwEIntegrationTime), cpConvBuf);
00546     g_free(cpConvBuf);
00547 }
00548 
00549 
00550 clGUILevel::clGUILevel ()
00551 {
00552     bRun = true;
00553     bConnected = false;
00554     lResultPos = 0L;
00555     lResultCount = 0L;
00556     spResults = NULL;
00557 }
00558 
00559 
00560 clGUILevel::~clGUILevel ()
00561 {
00562     if (spResults != NULL) g_free(spResults);
00563 }
00564 
00565 
00566 int clGUILevel::Main (int *ipArgC, char ***cppArgV)
00567 {
00568     g_print("%s GUI v%i.%i.%i\n", cpWindowTxt,
00569         GUILEV_VER_MAJ, GUILEV_VER_MIN, GUILEV_VER_PL);
00570     g_print("Copyright (C) 2000-2002 Jussi Laako\n\n");
00571     g_print("Gtk+ version %i.%i.%i\n", gtk_major_version, gtk_minor_version,
00572         gtk_micro_version);
00573     g_print("Locale set to %s\n", gtk_set_locale());
00574     gtk_init(ipArgC, cppArgV);
00575     gdk_rgb_init();
00576     gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
00577     gtk_widget_set_default_visual(gdk_rgb_get_visual());
00578     if (!GetCfg()) return 1;
00579     if (!Build()) return 1;
00580     gtk_main();
00581     return 0;
00582 }
00583 
00584 
00585 gboolean clGUILevel::OnDelete (GtkWidget *gwSender, GdkEvent *geEvent,
00586     gpointer gpData)
00587 {
00588     bRun = false;
00589     gtk_main_quit();
00590     return TRUE;
00591 }
00592 
00593 
00594 void clGUILevel::OnConnectClick (GtkButton *gbSender, gpointer gpData)
00595 {
00596     char **cpaServerAddr;
00597 
00598     if (bConnected)
00599     {
00600         gdk_input_remove(iGdkInputTag);
00601         SOp.Close();
00602     }
00603     cpaServerAddr = g_strsplit(
00604         gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(gwCServer)->entry)),
00605         ":", 2);
00606     if (cpaServerAddr[0] != NULL && cpaServerAddr[1] != NULL)
00607     {
00608         g_print("\nConnecting to %s port %s...\n", cpaServerAddr[0],
00609             cpaServerAddr[1]);
00610         if (ConnectToServer(cpaServerAddr[0], atoi(cpaServerAddr[1])))
00611         {
00612             bConnected = true;
00613             g_print("Connected, sending settings...\n");
00614             if (SendSettings())
00615             {
00616                 g_print("OK\n");
00617                 bFirstResult = true;
00618                 iGdkInputTag = gdk_input_add(SOp.GetHandle(), GDK_INPUT_READ,
00619                     WrapOnGdkInput, NULL);
00620             }
00621             else
00622             {
00623                 g_print("Failed to send settings!\n");
00624             }
00625         }
00626         else
00627         {
00628             g_print("Failed to connect to specified server!\n");
00629         }
00630     }
00631     else
00632     {
00633         g_print(
00634             "\nIncorrect server address format. Format: <server>:<port>\n");
00635     }
00636     g_strfreev(cpaServerAddr);
00637 }
00638 
00639 
00640 gboolean clGUILevel::OnSofarExpose (GtkWidget *gwSender, 
00641     GdkEventExpose *geeEvent, gpointer gpData)
00642 {
00643     long lXCntr;
00644     long lResultIdx;
00645     gint iPointY;
00646     float fScaler;
00647 
00648     fScaler = gwSender->allocation.height / fabs(fDisplayHigh - fDisplayLow);
00649     for (lXCntr = geeEvent->area.x; 
00650         lXCntr < (geeEvent->area.x + geeEvent->area.width); 
00651         lXCntr++)
00652     {
00653         lResultIdx = lXCntr + lResultPos + 1;
00654         iPointY = (gint) (fabs(spResults[lResultIdx].fResult - fDisplayHigh) *
00655             fScaler + 0.5F);
00656         gdk_draw_line(gwSender->window, ggcSofarFG,
00657             lXCntr, iPointY,
00658             lXCntr, gwSender->allocation.height - 1);
00659     }
00660     return TRUE;
00661 }
00662 
00663 
00664 gboolean clGUILevel::OnSofarMotion (GtkWidget *gwSender,
00665     GdkEventMotion *gemEvent, gpointer gpData)
00666 {
00667     char *cpConvBuf;
00668     float fXPos;
00669     float fYPos;
00670 
00671     fXPos = (gwSender->allocation.width - gemEvent->x + 1) *
00672         spResults[lResultPos].fIntegrationTime;
00673     fYPos = -(fabs(fDisplayHigh - fDisplayLow) / gwSender->allocation.height *
00674         gemEvent->y - fDisplayHigh);
00675     gtk_statusbar_pop(GTK_STATUSBAR(gwStatusBar), guSbCtxt);
00676     cpConvBuf = g_strdup_printf("%g %g = %g", 
00677         fXPos, fYPos,
00678         (spResults[(long) gemEvent->x + lResultPos].fResult));
00679     gtk_statusbar_push(GTK_STATUSBAR(gwStatusBar), guSbCtxt, cpConvBuf);
00680     g_free(cpConvBuf);
00681     return TRUE;
00682 }
00683 
00684 
00685 gboolean clGUILevel::OnSofarConfigure (GtkWidget *gwSender,
00686     GdkEventConfigure *gecEvent, gpointer gpData)
00687 {
00688     G_LOCK(gmInputMutex);
00689     lResultCount = gecEvent->width;
00690     spResults = (stpLevelRes) 
00691         g_realloc(spResults, lResultCount * sizeof(stLevelRes) * 2);
00692     G_UNLOCK(gmInputMutex);
00693     return TRUE;
00694 }
00695 
00696 
00697 void clGUILevel::OnGdkInput (gpointer gpData, gint iSource,
00698     GdkInputCondition gicCondition)
00699 {
00700     if (!bRun) return;
00701     G_LOCK(gmInputMutex);
00702     while (SOp.ReadSelect(0))
00703     {
00704         if (SOp.ReadN(cpResultBuf, GLOBAL_HEADER_LEN) < GLOBAL_HEADER_LEN)
00705         {
00706             gdk_input_remove(iGdkInputTag);
00707             SOp.Close();
00708             bConnected = false;
00709             g_print(
00710                 "Error occurred while receiving data, dropped connection.\n");
00711             break;
00712         }
00713         lResultPos++;
00714         if (lResultPos >= lResultCount) lResultPos = 0L;
00715         Msg.GetResult(cpResultBuf, &spResults[lResultPos]);
00716         memcpy(&spResults[lResultPos + lResultCount], &spResults[lResultPos],
00717             sizeof(stLevelRes));
00718         if (bFirstResult)
00719         {
00720             InitializeDisplay();
00721             bFirstResult = false;
00722         }
00723         DisplayResults();
00724     }
00725     G_UNLOCK(gmInputMutex);
00726 }
00727 

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