00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00039 static const char *cpLServerTxt = "Server";
00040 static const char *cpaLChannelTxt[] = { "Channel", "Direction" };
00041 static const char *cpBConnectTxt = "Connect";
00042
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
00121 gtk_window_set_policy(GTK_WINDOW(gwWindow), TRUE, TRUE, FALSE);
00122
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
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
00147 gwTable1 = gtk_table_new(2, 3, FALSE);
00148
00149 gtk_box_pack_start(GTK_BOX(gwVBox), gwTable1, FALSE, FALSE, 0);
00150 gtk_widget_show(gwTable1);
00151
00152
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
00167
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
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
00190
00191 goAChannel = gtk_adjustment_new(0.0, -90.0, 90.0, 1.0, 1.0, 1.0);
00192
00193 gwSBChannel = gtk_spin_button_new(GTK_ADJUSTMENT(goAChannel), 1.0, 1);
00194 }
00195 else
00196 {
00197
00198
00199 goAChannel = gtk_adjustment_new(1.0, GUILEV_CH_LOWER, GUILEV_CH_UPPER,
00200 1.0, 1.0, 1.0);
00201
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
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
00228 gwTable2 = gtk_table_new(2, 6, FALSE);
00229
00230 gtk_box_pack_start(GTK_BOX(gwVBox), gwTable2, FALSE, FALSE, 0);
00231 gtk_widget_show(gwTable2);
00232
00233
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
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
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
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
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
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
00361 gwTableSofar = gtk_table_new(2, 2, FALSE);
00362
00363 gtk_box_pack_start(GTK_BOX(gwVBox), gwTableSofar, TRUE, TRUE, 0);
00364 gtk_widget_show(gwTableSofar);
00365
00366
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
00376 gtk_ruler_set_range(GTK_RULER(gwHRTime), -1.0, 0.0, 0.0, 1.0);
00377
00378
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
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
00498 long lResultIdx;
00499 gint iPointY;
00500 float fScaler;
00501
00502 fScaler = gwDASofar->allocation.height / fabs(fDisplayHigh - fDisplayLow);
00503
00504
00505
00506
00507
00508
00509
00510
00511
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