Logo Search packages:      
Sourcecode: jkmeter version File versions  Download package

mainwin.cc

// ------------------------------------------------------------------------
//
//  Copyright (C) 2008-2011 Fons Adriaensen <fons@linuxaudio.org>
//    
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ------------------------------------------------------------------------


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "styles.h"
#include "global.h"
#include "mainwin.h"
#include "kmeterdsp.h"



Mainwin::Mainwin (X_rootwin *parent, X_resman *xres, Jclient *jclient) :
    A_thread ("Main"),
    X_window (parent, 0, 0, 100, 100, XftColors [C_MAIN_BG]->pixel),
    _xres (xres),
    _stop (false),
    _vert (false),
    _jclient (jclient)
{
    int         r;
    const char  *p;

    _atom = XInternAtom (dpy (), "WM_DELETE_WINDOW", True);
    XSetWMProtocols (dpy (), win (), &_atom, 1);
    _atom = XInternAtom (dpy (), "WM_PROTOCOLS", True);
    makegui ();
    p = xres->get (".rate", "25");
    r = atoi (p);
    if (r < 10) r = 10;
    if (r > 80) r = 80;
    _time = 1000000 / r;
}

 
Mainwin::~Mainwin (void)
{
}

 
int Mainwin::process (void)
{
    int e;

    if (_stop) handle_stop ();
    e = get_event_timed ();
    switch (e)
    {
    case EV_TIME:
        handle_time ();
      break;
    }
    return e;
}


void Mainwin::handle_event (XEvent *E)
{
    switch (E->type)
    {
    case Expose:
      expose ((XExposeEvent *) E);
      break;  
 
    case ClientMessage:
        clmesg ((XClientMessageEvent *) E);
        break;
    }
}


void Mainwin::expose (XExposeEvent *E)
{
    if (E->count) return;
    redraw ();
}


void Mainwin::clmesg (XClientMessageEvent *E)
{
    if (E->message_type == _atom) _stop = true;
}


void Mainwin::handle_time (void)
{
    int i;

    for (i = 0; i < _chan; i++) update1 (i);
    update2 ();
    if (_corr) _cmeter->update (_jclient->scdsp ()-> read ());
    XFlush (dpy ());
    inc_time (_time);
}


void Mainwin::handle_stop (void)
{
    put_event (EV_EXIT, 1);
}


void Mainwin::handle_callb (int type, X_window *W, XEvent *E)
{
    switch (type)
    {
    case X_callback::BUTTON | X_button::PRESS:
      _pkbutt->set_text (0, 0);
      _pkbutt->set_stat (0);
      _pkbutt->redraw ();
      _peak1 = 1e-4f;
      _peak2 = 1e-4f;
      break;
    }
}


void Mainwin::update1 (int k)
{
    float r, p;

    _jclient->kmdsp (k)->read (&r, &p);
    _meters [k]->update (r, p);
    if (p > _peak1) _peak1 = p;
}


void Mainwin::update2 (void)
{
    float p;
    char  s [16];

    if (_peak1 > _peak2)
    {    
      _peak2 = _peak1;
      p = 20 * log10f (_peak2);
      sprintf (s, (p < -9.9f) ? "%3.0lf" : "%3.1lf", p);
      _pkbutt->set_text (s, 0);
      if      (p >=   0) _pkbutt->set_stat (3);
      else if (p >=  -6) _pkbutt->set_stat (2);
      else if (p >= -20) _pkbutt->set_stat (1);
      _pkbutt->redraw ();
    } 
    _peak1 = 1e-4f;
}


void Mainwin::redraw (void)
{
    int     i, x, y;
    XImage  *I = _meters [0]->scale ();


    if (_vert)
    {
      x = 8;
      y = 24;
        XPutImage (dpy (), win (), dgc (), I, 4, 0, x, y, 24, I->height);
      x += 30;
      for (i = 1; i < _chan; i++)
      {
            XPutImage (dpy (), win (), dgc (), I, 0, 0, x, y, 4, I->height);
          x += Kmeter::LINEW + 4;
      }
      XPutImage (dpy (), win (), dgc (), I, 0, 0, x, y, 24, I->height);
      if (_corr)
      {
            I = _cmeter->scale ();
          x += 40;
            XPutImage (dpy (), win (), dgc (), I, 0, 0, x, y, 24, I->height);
      }
    }
    else
    {
      x = 12;
      y =  8;
        XPutImage (dpy (), win (), dgc (), I, 0, 4, x, y, I->width, 16);
      y += 22;
      for (i = 1; i < _chan; i++)
      {
            XPutImage (dpy (), win (), dgc (), I, 0, 0, x, y, I->width, 4);
          y += Kmeter::LINEW + 4;
      }
        XPutImage (dpy (), win (), dgc (), I, 0, 0, x, y, I->width, 16);
      if (_corr)
      {
            I = _cmeter->scale ();
          x = _xs - Cmeter::LENGTH - 38;
          y += 30;
            XPutImage (dpy (), win (), dgc (), I, 0, 0, x, y, I->width, 16);
      }
    }
}




void Mainwin::makegui (void)
{
    int         i, x, y, xp, yp;
    bool        H, V;
    X_hints     xh;
    char        s [1024];

    H = _xres->getb (".horizontal", 0);
    V = _xres->getb (".vertical", 0);
    if (! H && ! V) _vert = _xres->get (".orientation", "h")[0] == 'v';  
    else _vert = V;
    if (strcmp (_xres->get (".type", "k20"), "k14")) _kval = Kmeter::K20;
    else                                             _kval = Kmeter::K14;
    _chan = _xres->getb (".ambisonic", 0) ? 4 : 2;
    _corr = _xres->getb (".correlation", 0);

    Bst0.size.x = 30;
    Bst0.size.y = 14;
    if (_vert)
    {
      x = 32;
      y = 24;
      for (i = 0; i < _chan; i++)
      {
          _meters [i] = new Kmeter (this, x, y, Kmeter::VER, _kval);
          x += Kmeter::LINEW + 4;
      }
        _pkbutt = new X_tbutton (this, this, &Bst0, x / 2 - 1, y - 16, 0, 0, 0);
      x += 30;
      if (_corr)
      {
          _cmeter = new Cmeter (this, x, y, Cmeter::VER);
            _cmeter->x_map ();
          x += Cmeter::LINEW + 32;
      }
      y += 12 + _meters [0]->ys ();
    }
    else
    {
      x = 12;
      y = 24;
      for (i = 0; i < _chan; i++)
      {
            _meters [i] = new Kmeter (this, x, y, Kmeter::HOR, _kval);
          y += Kmeter::LINEW + 4;
      }
      x += _meters [0]->xs ();
        _pkbutt = new X_tbutton (this, this, &Bst0, x + 2, y / 2 + 3, 0, 0, 0);
      x += 38;
      y += 20;
      if (_corr)
      {
          _cmeter = new Cmeter (this, x - Cmeter::LENGTH - 38, y, Cmeter::HOR);
            _cmeter->x_map ();
          y += Cmeter::LINEW + 22;
      }
    }
    _xs = x;
    _ys = y;
    for (i = 0; i < _chan; i++)
    {
        _meters [i]->x_map ();
    }
    _pkbutt->x_map ();
    _peak1 = 1e-4f;
    _peak2 = 1e-4f;

    xp = yp = 100;
    x = _xs + 4;
    y = _ys + 30;
    _xres->geometry (".geometry", disp ()->xsize (), disp ()->ysize (), 1, xp, yp, x, y);
    x_moveresize (xp, yp, x, y);

    sprintf (s, "%s   %s-%s", _jclient->jname (), PROGNAME, VERSION);
    x_set_title (s);
    xh.position (xp, yp);
    xh.minsize (_xs, _ys);
    xh.maxsize (_xs, _ys);
    xh.rname (_xres->rname ());
    xh.rclas (_xres->rclas ());
    x_apply (&xh); 
    x_add_events (ExposureMask);
    XFlush (dpy ());
    set_time (0);
    inc_time (100000);
}


void Mainwin::addtext (X_window *W, X_textln_style *T, int xp, int yp, int xs, int ys, const char *text, int align)
{
    (new X_textln (W, T, xp, yp, xs, ys, text, align))->x_map ();
}



Generated by  Doxygen 1.6.0   Back to index