root/foundation-apps/grosview-maxx/xosview.cc

Revision 2, 11.2 KB (checked in by emasson, 3 years ago)

initial import for the community edition

Line 
1//
2//  Copyright (c) 1994, 1995, 2002, 2006 by Mike Romberg ( mike.romberg@noaa.gov )
3//
4//  This file may be distributed under terms of the GPL
5//
6//
7// $Id: xosview.cc,v 1.1.1.1 2008/05/04 15:53:48 emasson Exp $
8//
9#include <unistd.h>
10#include <stdlib.h>
11#include <sys/time.h>
12#include "general.h"
13#include "xosview.h"
14#include "meter.h"
15#include "MeterMaker.h"
16#if (defined(XOSVIEW_NETBSD) || defined(XOSVIEW_FREEBSD) || defined(XOSVIEW_OPENBSD))
17#include "kernel.h"
18#endif
19
20static const char * const versionString = "gr_osview version: " XOSVIEW_VERSION;
21
22static const char NAME[] = "gr_osview@";
23
24#if !defined(__GNUC__)
25
26#define MIN(x,y)                \
27(                               \
28    x < y ? x : y               \
29)
30
31#define MAX(x,y)                \
32(                               \
33    x > y ? x : y               \
34)
35
36#else
37
38#define MIN(x,y)                \
39({                              \
40    const typeof(x) _x = x;     \
41    const typeof(y) _y = y;     \
42                                \
43    (void) (&_x == &_y);        \
44                                \
45    _x < _y ? _x : _y;          \
46})
47
48#define MAX(x,y)                \
49({                              \
50    const typeof(x) _x = x;     \
51    const typeof(y) _y = y;     \
52                                \
53    (void) (&_x == &_y);        \
54                                \
55    _x > _y ? _x : _y;          \
56})
57
58#endif // sgi
59
60double MAX_SAMPLES_PER_SECOND = 10;
61
62CVSID("$Id: xosview.cc,v 1.1.1.1 2008/05/04 15:53:48 emasson Exp $");
63CVSID_DOT_H(XOSVIEW_H_CVSID);
64
65
66XOSView::XOSView( char * instName, int argc, char *argv[] ) : XWin(),
67                                                xrm(Xrm("xosview", instName)){
68  // Check for version arguments first.  This allows
69  // them to work without the need for a connection
70  // to the X server
71  checkVersion(argc, argv);
72
73  setDisplayName (xrm.getDisplayName( argc, argv));
74  openDisplay();  //  So that the Xrm class can contact the display for its
75                  //  default values.
76  //  The resources need to be initialized before calling XWinInit, because
77  //  XWinInit looks at the geometry resource for its geometry.  BCG
78  xrm.loadAndMergeResources (argc, argv, display_);
79  XWinInit (argc, argv, NULL, &xrm);
80#if 1   //  Don't enable this yet.
81  MAX_SAMPLES_PER_SECOND = atof(getResource("samplesPerSec"));
82  if (!MAX_SAMPLES_PER_SECOND)
83    MAX_SAMPLES_PER_SECOND = 10;
84#endif
85  usleeptime_ = (unsigned long) (1000000/MAX_SAMPLES_PER_SECOND);
86  if (usleeptime_ >= 1000000) {
87    /*  The syscall usleep() only takes times less than 1 sec, so
88     *  split into a sleep time and a usleep time if needed.  */
89    sleeptime_ = usleeptime_ / 1000000;
90    usleeptime_ = usleeptime_ % 1000000;
91  } else { sleeptime_ = 0; }
92#if (defined(XOSVIEW_NETBSD) || defined(XOSVIEW_FREEBSD) || defined(XOSVIEW_OPENBSD))
93  BSDInit();    /*  Needs to be done before processing of -N option.  */
94#endif
95
96  hmargin_  = atoi(getResource("horizontalMargin"));
97  vmargin_  = atoi(getResource("verticalMargin"));
98  vspacing_ = atoi(getResource("verticalSpacing"));
99  hmargin_  = MAX(0, hmargin_);
100  vmargin_  = MAX(0, vmargin_);
101  vspacing_ = MAX(0, vspacing_);
102
103  checkArgs (argc, argv);  //  Check for any other unhandled args.
104  xoff_ = hmargin_;
105  yoff_ = 0;
106  nummeters_ = 0;
107  meters_ = NULL;
108  name_ = "xosview";
109  _isvisible = false;
110  _ispartiallyvisible = false;
111  exposed_once_flag_ = 0;
112
113  expose_flag_ = 1;
114
115  //  set up the X events
116  addEvent( new Event( this, ConfigureNotify,
117                      (EventCallBack)&XOSView::resizeEvent ) );
118  addEvent( new Event( this, Expose,
119                      (EventCallBack)&XOSView::exposeEvent ) );
120  addEvent( new Event( this, KeyPress,
121                      (EventCallBack)&XOSView::keyPressEvent ) );
122  addEvent( new Event( this, VisibilityNotify,
123                      (EventCallBack)&XOSView::visibilityEvent ) );
124  addEvent( new Event( this, UnmapNotify,
125                      (EventCallBack)&XOSView::unmapEvent ) );
126
127  // add or change the Resources
128  MeterMaker mm(this);
129
130  // see if legends are to be used
131  checkOverallResources ();
132
133  // add in the meters
134  mm.makeMeters();
135  for (int i = 1 ; i <= mm.n() ; i++)
136    addmeter(mm[i]);
137
138  if (nummeters_ == 0)
139  {
140    fprintf (stderr, "No meters were enabled!  Exiting...\n");
141    exit (0);
142  }
143
144  //  Have the meters re-check the resources.
145  checkMeterResources();
146
147  // determine the width and height of the window then create it
148  figureSize();
149  init( argc, argv );
150  title( winname() );
151  iconname( winname() );
152  dolegends();
153  resize();
154}
155
156void XOSView::checkVersion(int argc, char *argv[]) const
157    {
158    for (int i = 0 ; i < argc ; i++)
159        if (!strncasecmp(argv[i], "-v", 2)
160          || !strncasecmp(argv[i], "--version", 10))
161            {
162            std::cerr << versionString << std::endl;
163            exit(0);
164            }
165    }
166
167void XOSView::figureSize ( void ) {
168  if ( legend_ ){
169    if ( !usedlabels_ )
170      xoff_ = textWidth( "XXXXX" );
171    else
172      xoff_ = textWidth( "XXXXXXXXX" );
173
174    yoff_ = caption_ ? textHeight() + textHeight() / 4 : 0;
175  }
176  static int firsttime = 1;
177  if (firsttime) {
178    firsttime = 0;
179    width_ = findx();
180    height_ = findy();
181  }
182  else
183  {
184  }
185}
186
187void XOSView::checkMeterResources( void ){
188  MeterNode *tmp = meters_;
189
190  while ( tmp != NULL ){
191    tmp->meter_->checkResources();
192    tmp = tmp->next_;
193  }
194}
195
196int XOSView::newypos( void ){
197  return 15 + 25 * nummeters_;
198}
199
200void XOSView::dolegends( void ){
201  MeterNode *tmp = meters_;
202  while ( tmp != NULL ){
203    tmp->meter_->docaptions( caption_ );
204    tmp->meter_->dolegends( legend_ );
205    tmp->meter_->dousedlegends( usedlabels_ );
206    tmp = tmp->next_;
207  }
208}
209
210void XOSView::addmeter( Meter *fm ){
211  MeterNode *tmp = meters_;
212
213  if ( meters_ == NULL )
214    meters_ = new MeterNode( fm );
215  else {
216    while ( tmp->next_ != NULL )
217      tmp = tmp->next_;
218    tmp->next_ = new MeterNode( fm );
219  }
220  nummeters_++;
221}
222
223int XOSView::findx( void ){
224  if ( legend_ ){
225    if ( !usedlabels_ )
226      return textWidth( "XXXXXXXXXXXXXXXXXXXXXXXX" );
227    else
228      return textWidth( "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX" );
229  }
230  return 80;
231}
232
233int XOSView::findy( void ){
234  if ( legend_ )
235    return 10 + textHeight() * nummeters_ * ( caption_ ? 2 : 1 );
236
237  return 15 * nummeters_;
238}
239
240void XOSView::checkOverallResources() {
241  //  Check various resource values.
242
243  //  Set 'off' value.  This is not necessarily a default value --
244  //    the value in the defaultXResourceString is the default value.
245  usedlabels_ = legend_ = caption_ = 0;
246
247  setFont();
248
249   // use captions
250  if ( isResourceTrue("captions") )
251      caption_ = 1;
252
253  // use labels
254  if ( isResourceTrue("labels") )
255      legend_ = 1;
256
257  // use "free" labels
258  if ( isResourceTrue("usedlabels") )
259      usedlabels_ = 1;
260}
261
262const char *XOSView::winname( void ){
263  char host[100];
264  gethostname( host, 99 );
265  static char name[101];        /*  We return a pointer to this,
266                                    so it can't be local.  */
267  snprintf( name, 100, "%s%s", NAME, host);
268  //  Allow overriding of this name through the -title option.
269  return getResourceOrUseDefault ("title", name);
270}
271
272
273void  XOSView::resize( void ){
274  int spacing = vspacing_+1;
275  int topmargin = vmargin_;
276  int rightmargin = hmargin_;
277  int newwidth = width_ - xoff_ - rightmargin;
278/*
279  int newheight = (height_ - (10 + 5 * (nummeters_ - 1) +
280                              nummeters_ * yoff_)) / nummeters_;
281*/
282  int newheight =
283        (height_ -
284         (topmargin + topmargin + (nummeters_-1)*spacing + nummeters_*yoff_)
285        ) / nummeters_;
286  newheight = (newheight >= 2) ? newheight : 2;
287
288
289  int counter = 1;
290  MeterNode *tmp = meters_;
291  while ( tmp != NULL ) {
292/*
293    tmp->meter_->resize( xoff_, 5 * counter + counter * yoff_ +
294                         (counter - 1) * newheight, newwidth, newheight );
295*/
296    tmp->meter_->resize( xoff_,
297                         topmargin + counter*yoff_ + (counter-1)*(newheight+spacing),
298                        newwidth, newheight );
299    tmp = tmp->next_;
300
301    counter++;
302  }
303}
304
305
306XOSView::~XOSView( void ){
307  MeterNode *tmp = meters_;
308  while ( tmp != NULL ){
309    MeterNode *save = tmp->next_;
310    delete tmp->meter_;
311    delete tmp;
312    tmp = save;
313  }
314}
315
316void XOSView::reallydraw( void ){
317  XOSDEBUG("Doing draw.\n");
318  clear();
319  MeterNode *tmp = meters_;
320
321  while ( tmp != NULL ){
322    tmp->meter_->draw();
323    tmp = tmp->next_;
324  }
325  flush();
326
327  expose_flag_ = 0;
328}
329
330void XOSView::draw ( void ) {
331  if (hasBeenExposedAtLeastOnce() && isAtLeastPartiallyVisible())
332    reallydraw();
333  else {
334    if (!hasBeenExposedAtLeastOnce()) {
335      XOSDEBUG("Skipping draw:  not yet exposed.\n");
336    } else if (!isAtLeastPartiallyVisible()) {
337      XOSDEBUG("Skipping draw:  not visible.\n");
338    }
339  }
340}
341void XOSView::keyrelease( char *ch ){
342/*  WARNING:  This code is not called by anything.  */
343(void) ch;  /*  To avoid gcc warnings.  */
344}
345
346void XOSView::run( void ){
347  int counter = 0;
348
349  while( !done_ ){
350    checkevent();
351
352    if (_isvisible){
353      MeterNode *tmp = meters_;
354      while ( tmp != NULL ){
355        if ( tmp->meter_->requestevent() )
356          tmp->meter_->checkevent();
357        tmp = tmp->next_;
358      }
359
360      flush();
361    }
362#ifdef HAVE_USLEEP
363    /*  First, sleep for the proper integral number of seconds --
364     *  usleep only deals with times less than 1 sec.  */
365    if (sleeptime_) sleep((unsigned int)sleeptime_);
366    if (usleeptime_) usleep( (unsigned int)usleeptime_);
367#else
368    usleep_via_select ( usleeptime_ );
369#endif
370    counter = (counter + 1) % 5;
371  }
372}
373
374void XOSView::usleep_via_select( unsigned long usec ){
375  struct timeval time;
376
377  time.tv_sec = (int)(usec / 1000000);
378  time.tv_usec = usec - time.tv_sec * 1000000;
379
380  select( 0, 0, 0, 0, &time );
381}
382
383void XOSView::keyPressEvent( XKeyEvent &event ){
384  char c = 0;
385  KeySym key;
386
387  XLookupString( &event, &c, 1, &key, NULL );
388
389  if ( (c == 'q') || (c == 'Q') )
390    done_ = 1;
391}
392
393void XOSView::checkArgs (int argc, char** argv) const
394{
395  //  The XWin constructor call in the XOSView constructor above
396  //  modifies argc and argv, so by this
397  //  point, all XResource arguments should be removed.  Since we currently
398  //  don't have any other command-line arguments, perform a check here
399  //  to make sure we don't get any more.
400  if (argc == 1) return//  No arguments besides X resources.
401
402  //  Skip to the first real argument.
403  argc--;
404  argv++;
405  while (argc > 0 && argv && *argv)
406  {
407    switch (argv[0][1]) {
408      case 'n': //  Check for -name option that was already parsed
409                //  and acted upon by main().
410                if (!strncasecmp(*argv, "-name", 6))
411                {
412                  argv++;       //  Skip arg to -name.
413                  argc--;
414                }
415                break;
416#if (defined(XOSVIEW_NETBSD) || defined(XOSVIEW_FREEBSD) || defined(XOSVIEW_OPENBSD))
417      case 'N': if (strlen(argv[0]) > 2)
418                  SetKernelName(argv[0]+2);
419                else
420                {
421                  SetKernelName(argv[1]);
422                  argc--;
423                  argv++;
424                }
425                break;
426#endif
427              /*  Fall through to default/error case.  */
428      default:
429                std::cerr << "Ignoring unknown option '" << argv[0] << "'.\n";
430                break;
431    }
432    argc--;
433    argv++;
434  }
435}
436
437void XOSView::exposeEvent( XExposeEvent &event ) {
438  _isvisible = true;
439  if ( event.count == 0 )
440  {
441    expose_flag_++;
442    draw();
443  }
444  XOSDEBUG("Got expose event.\n");
445  if (!exposed_once_flag_) { exposed_once_flag_ = 1; draw(); }
446}
447
448void XOSView::resizeEvent( XEvent & ) {
449  resize();
450  expose_flag_++;
451  draw();
452}
453
454
455void XOSView::visibilityEvent( XVisibilityEvent &event ){
456  _ispartiallyvisible = false;
457  if (event.state == VisibilityPartiallyObscured){
458    _ispartiallyvisible = true;
459  }
460
461  if (event.state == VisibilityFullyObscured){
462    _isvisible = false;
463  }
464  else {
465    _isvisible = true;
466  }
467  XOSDEBUG("Got visibility event; %d and %d\n",
468      _ispartiallyvisible, _isvisible);
469}
470
471void XOSView::unmapEvent( XUnmapEvent & ){
472  _isvisible = false;
473}
Note: See TracBrowser for help on using the browser.