"Fossies" - the Fresh Open Source Software Archive

Member "xosview-1.23/xosview.cc" (11 Jul 2020, 11400 Bytes) of package /linux/misc/xosview-1.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "xosview.cc" see the Fossies "Dox" file reference documentation.

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