prepare to upload
[debian/gcpegg] / eggui.c
1 /* PROGRAM:     eggsh
2  * FILE:        $Header: /home/egg/src/RCS/eggui.c,v 1.8 1999/02/28 20:02:54 ghn Exp $
3  * PURPOSE:     EGG site user interface
4  * AUTHOR:      Greg Nelson
5  * DATE:        98-06-28
6  *
7  * REVISED:
8  * $Log: eggui.c,v $
9  * Revision 1.8  1999/02/28 20:02:54  ghn
10  * Version 5.1: The user interface now leaves the cursor at the bottom of
11  * the screen and responds to ^L to redraw the entire screen.
12  *
13  * Revision 1.7  1999/01/01 23:58:56  ghn
14  * Take out "CPU_BOUND" conditionals; we won't run CPU_BOUND any more.
15  *
16  * Revision 1.6  1998/12/31 22:07:56  ghn
17  * Rev 5 code: includes multi-reg support, HTML, etc.
18  *
19  * Revision 1.5  1998/08/03 20:36:28  kelvin
20  * Show time of last data collection by basket.
21  *
22  * Revision 1.4  1998/08/01  21:33:28  ghn
23  * Added real implementation for ncursed() based UI for egg.
24  *
25  * Revision 1.3  1998/08/01 18:51:25  ghn
26  * Added John's byte-order-independence changes.
27  *
28  * Revision 1.2  1998/08/01 17:05:48  ghn
29  * Trivial additions of curses related code.
30  *
31  * Revision 1.1  1998/07/21 11:41:23  ghn
32  * Initial revision
33  *
34  * Copyright 1998 - Greg Nelson
35  */
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <curses.h>
40 #include <time.h>
41 #include <string.h>
42
43 /*  Curses takes it upon itself to define TRUE and FALSE,
44     incompatibly, as it happens, with the definitions in
45     global.h.  So, clear out the CURSES definitions.  */
46 #ifdef TRUE
47 #undef TRUE
48 #endif
49 #ifdef FALSE
50 #undef FALSE
51 #endif
52
53 #include "global.h"
54 #include "genlib.h"
55 #include "errnos.h"
56 #include "regs.h"
57 #include "version.h"
58
59 #ifndef NO_UI
60 static uint32 inittm = 0;
61 #endif
62
63 extern uint32 lastDataSent;
64 extern uint32 time_latency, time_housekeeping;
65
66 /* Initialize user interface, as needed. */
67 int32 UIInit(void) {
68 #ifndef NO_UI
69   initscr(); 
70   cbreak(); noecho(); 
71   nonl();
72   intrflush(stdscr, FALSE);
73   keypad(stdscr, TRUE);
74   timeout(0);
75   clear();
76   move(0, 0);
77   printw("Please wait, initializing...");
78   refresh();
79   inittm = 0;
80 #endif
81   return ERR_NONE;
82 }
83
84 /* Close down user interface */
85 int32 UIClose(void) {
86 #ifndef NO_UI
87   endwin();
88 #endif
89   return ERR_NONE;
90 }
91
92 /* Update user interface once on every data collection, receiving the
93    current collection result and CollectRecord. */
94 int32 UIUpdate(int32 cres, CollectRecord *coll) {
95 #ifndef NO_UI
96   char *tmstr;
97   double recavg;
98   static double grandavg = 0;
99   static int32 totsamp = 0;
100   int32 i, line, now;
101
102   if ((i = getch()) != ERR) {
103     if (i == 12) clear();
104   }
105
106   if (inittm == 0) {
107     inittm = getzulutime(NULL);
108     clear();
109   }
110
111   /* Show protocol. */
112
113   if (coll->sampct == 1) {
114     line = 11;
115     move(line++, 5); printw("Samples per record: %3d", coll->opts.samp_rec);
116     move(line++, 5); printw("Seconds per record: %3d", coll->opts.sec_rec);
117     move(line++, 5); printw("Records per packet: %3d", coll->opts.rec_pkt);
118     move(line++, 5); printw("Bits per trial:     %3d", coll->opts.trialsz);
119     refresh();
120   }
121
122   if (cres < 0) return ERR_NONE;
123
124   line = 0;
125   move(line++, 3);
126   printw("EGG %s ID %d REG %s %s", eggtable[0].name, eggtable[0].id,
127          configuredREG->reg_name, Version);
128
129   time_t inittm_val = inittm;
130   tmstr = ctime(&inittm_val); tmstr[strlen(tmstr)-1] = 0;
131   move(line++, 5);
132   printw("Up since       %25s", tmstr);
133
134   move(line++, 5);
135   now = getzulutime(NULL);
136   time_t now_val = now;
137   tmstr = ctime(&now_val); tmstr[strlen(tmstr)-1] = 0;
138   printw("Last sample at %25s", tmstr);
139
140   move(line++, 5);
141   time_t lastDataSent_val = lastDataSent;
142   tmstr = ctime(&lastDataSent_val);
143   tmstr[strlen(tmstr)-1] = 0;
144   printw("Last packet at %25s", lastDataSent == 0 ? "Never" : tmstr);
145
146   /* Note that for a non-CPU_BOUND built, UIUpdate is passed a
147      collection record filled with the last 10 samples collected.
148      Since missing samples do not figure in this record, there
149      is no need to test EGG_MISSING_DATA when computing the
150      mean below. */
151
152   /* Show mean since egg started and, each time 10 samples
153      are collected, the mean for the last 10 samples. */
154
155   line++;
156   grandavg *= totsamp;
157   grandavg += coll->data.trials[coll->sampct-1]; totsamp++;
158   grandavg /= totsamp;
159   move(line++, 5);
160   printw("Grand mean:       %6.2f", grandavg);
161
162   if (cres == 1) {
163     for (recavg = 0, i = 0; i < coll->opts.samp_rec; i++)
164       recavg += coll->data.trials[i];
165     recavg /= coll->opts.samp_rec;
166     move(line, 5); 
167     printw("Last record mean: %6.2f (%d seconds)", recavg, coll->opts.sec_rec);
168   }
169   line++;                             /* Advance whether we show record mean or not */
170
171   /* Show latency (lapse between start of second as measured by
172      the computer's clock and when collection of the sample
173      actually began) and time elapsed in housekeeping (saving
174      packets in local files, talking to the basket, updating
175      the user interface, etc.) following collection of the sample.
176      If housekeeping time frequently consumes a substantial portion
177      of the inter-sample interval, the probability of lost
178      samples increases.  Both times are shown in milliseconds. */
179
180   line++;
181   move(line++, 5);
182   printw("Sampling latency:   ");
183   clrtoeol();
184   printw("%.3f ms", time_latency / 1000.0);
185   move(line++, 5);
186   printw("Housekeeping time:  ");
187   clrtoeol();
188   printw("%.3f ms", time_housekeeping / 1000.0);
189
190   move(16, 0);
191
192   refresh();
193 #endif
194
195   return ERR_NONE;
196 }