Logo Search packages:      
Sourcecode: vat version File versions

main.cc

/*
 * Copyright (c) 1991-1994 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by the Computer Systems
 *    Engineering Group at Lawrence Berkeley Laboratory.
 * 4. Neither the name of the University nor of the Laboratory may be used
 *    to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
static const char rcsid[] =
    "@(#) $Header: main.cc,v 1.48 96/05/03 06:27:20 van Exp $ (LBL)";

#include "config.h"
#include <math.h>
#include <signal.h>
#include <ctype.h>
#ifdef WIN32
#include <process.h>
#else
#include <sys/param.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#endif
#include "sys-time.h"
#ifdef sgi
#include <getopt.h>
#endif
#ifdef _AIX
#include <sys/socket.h>
#endif

extern "C" {
#include <tk.h>
}

#ifndef WIN32
#include <netdb.h>
#endif

#include "inet.h"
#include "Tcl.h"

extern "C" int Tk_StripchartCmd(ClientData, Tcl_Interp*, int ac, const char** av);
#ifdef WIN32
extern "C" int WinPutsCmd(ClientData, Tcl_Interp*, int ac, char** av);
extern "C" int WinGetUserName(ClientData, Tcl_Interp*, int ac, char** av);
extern "C" int WinPutRegistry(ClientData, Tcl_Interp*, int ac, char** av);
extern "C" int WinGetRegistry(ClientData, Tcl_Interp*, int ac, char** av);
#endif

/*XXX*/
#define PROTOTYPES 1 
#include "global.h"
#include "md5.h"

#if defined(sun) && defined(__svr4__)
#include <sys/utsname.h>
#define gethostname(name, len) { \
      struct utsname _uts_; \
\
      if (uname(&_uts_) < 0) { \
            perror("uname"); \
            exit(1); \
      }\
\
      strcpy((name), _uts_.nodename); \
}
#endif
 
static void
usage()
{
      fprintf(stderr, "\
usage: vat [-aAcdEjJkLMnrRsSv] [-C conf] [-D dump] [-f format] [-F device]\n\
\t[-g geometry] [-d display] [-I chan] [-K key] [-N name] [-K key ]\n\
\t[-t ttl] [-u script] [-U socket] [-X res=val] dest/port[/fmt/ttl]\n"
      );
      exit(1);
}

static class UsageCommand : public TclObject {
public:
      UsageCommand() : TclObject("usage") {}
      int command(int argc, const char*const* argv) {
            usage();
            /*NOTREACHED*/
            return (0);
      }
} cmd_usage;

#ifndef SIGARGS
#define SIGARGS int signo
#endif

#ifdef SIGCHLD
static SIGRET ReapChild(SIGARGS)
{
      while (waitpid(-1, 0, WNOHANG) > 0)
            ;
}
#endif

extern void adios();

static SIGRET DoQuit(SIGARGS)
{
      adios();
}

void initcatchers()
{
      signal(SIGINT, &DoQuit);
#ifdef SIGHUP
      signal(SIGHUP, &DoQuit);
#endif
      signal(SIGTERM, &DoQuit);
#ifdef SIGCHLD
      signal(SIGCHLD, &ReapChild);
#endif
}

static class AdiosCommand : public TclObject {
public:
      AdiosCommand() : TclObject("adios") {}
      int command(int argc, const char*const* argv) {
            adios();
            /*NOTREACHED*/
            return (0);
      }
} cmd_adios;

static class HaveFontCommand : public TclObject {
public:
      HaveFontCommand() : TclObject("havefont") {}
      int command(int argc, const char*const* argv) {
            Tcl& t = Tcl::instance();
            if (argc != 2)
                  t.result("0");
            else {
                  Tk_Window tk = t.tkmain();
                  Tk_Uid uid = Tk_GetUid((char*)argv[1]);
                  Tk_Font p = Tk_GetFont(t.interp(), tk, uid);
                  t.result(p != 0 ? "1" : "0");
            }
            return (TCL_OK);
      }
} cmd_havefont;

static class GetHostNameCommand : public TclObject {
public:
      GetHostNameCommand() : TclObject("gethostname") {}
      int command(int argc, const char*const* argv) {
            Tcl& tcl = Tcl::instance();
            char* bp = tcl.buffer();
            tcl.result(bp);
            gethostname(bp, MAXHOSTNAMELEN);
            return (TCL_OK);
      }
} cmd_gethostname;

extern "C" char version[];

static class VersionCommand : public TclObject {
public:
      VersionCommand() : TclObject("version") {}
      int command(int argc, const char*const* argv) {
            Tcl::instance().result(version);
            return (TCL_OK);
      }
} cmd_version;

extern "C" char *optarg;
extern "C" int optind;
extern "C" int opterr;

int yesno(const char* s)
{
      if (s == 0)
            return (0);
      if (isdigit(*s))
            return (atoi(s));
      int ret;
      switch (*s) {
      case 't': case 'T':
      case 'y': case 'Y':
      case '1':
            ret = 1;
            break;
      case 'o': case 'O':
            ret = (s[1] == 'n' || s[1] == 'N');
            break;
      default:
            ret = 0;
            break;
      }
      return (ret);
}

#ifndef sgi
inline
#endif
static void
set_option(Tk_Window tk, const char* name, const char* value)
{
      char wrk[80];
      sprintf(wrk, "Vat.%s", name);
      Tk_AddOption(tk, wrk, (char*)value, TK_USER_DEFAULT_PRIO + 1);
}

static void
toggle_option(const char* name)
{
      Tcl& tcl = Tcl::instance();
      const char* value = tcl.attr(name);
      if (value != 0 && yesno(value))
            tcl.add_option(name, "0");
      else
            tcl.add_option(name, "1");
}

static int
is_whitespace(const char* s)
{
      int c;
      while ((c = *s++) != 0)
            if (!isspace(c))
                  return (0);
      return (1);
}

#if defined(__hpux) || defined(sco)
#ifdef sco
#define gethostid xgethostid
#else
#include <sys/socket.h>
#endif
gethostid()
{
      int id;
      char hostname[256];           /* 255 is max legal DNS name */
      size_t hostname_size = 256;
      struct hostent *hostp;
      struct in_addr addru;         /* union for conversion */

      (void) gethostname(hostname, hostname_size);
      hostname[hostname_size] = '\0'; /* make sure it is null-terminated */

      hostp = gethostbyname(hostname);
      if(hostp == NULL)
            /* our own name was not found!  punt. */
            id = 0;
      else {
            /* return first address of host */
            memcpy(&(addru.s_addr), hostp->h_addr_list[0], 4);
            id = addru.s_addr;
      }
  
      return id;
}
#endif

#ifdef __svr4__
#include <sys/systeminfo.h>
#define gethostid xgethostid
gethostid()
{
      char wrk[32];
      if (sysinfo(SI_HW_SERIAL, wrk, sizeof(wrk)) > 0)
            return (atoi(wrk));
      return (0);
}
#endif

/*
 * From the RTP spec.
 */
u_int32_t
heuristic_random()
{
      struct {
            struct  timeval tv;
            clock_t cpu;
            pid_t   pid;
            u_long  hid;
            uid_t   uid;
            gid_t   gid;
            struct  utsname name;
      } s;

      gettimeofday(&s.tv, 0);
      uname(&s.name);
      s.cpu  = clock();
      s.pid  = getpid();
      s.hid  = gethostid();
      s.uid  = getuid();
      s.gid  = getgid();

      MD5_CTX context;
      MD5Init(&context);
      MD5Update(&context, (u_char*)&s, sizeof(s));
      u_int32_t out[4];
      MD5Final((u_char *)out, &context);
      return (out[0] ^ out[1] ^ out[2] ^ out[3]);
}

#include "bitmaps/speaker.xbm"
#include "bitmaps/headphone.xbm"
#include "bitmaps/lineout.xbm"
#include "bitmaps/lineout2.xbm"
#include "bitmaps/lineout3.xbm"
#include "bitmaps/mic.xbm"
#include "bitmaps/linein.xbm"
#include "bitmaps/linein2.xbm"
#include "bitmaps/linein3.xbm"
#include "bitmaps/square.xbm"
void
loadbitmaps(Tcl_Interp* tcl)
{
      Tk_DefineBitmap(tcl, Tk_GetUid("speaker"),
                  speaker_bits, speaker_width, speaker_height);
      Tk_DefineBitmap(tcl, Tk_GetUid("headphone"),
                  headphone_bits, headphone_width, headphone_height);
      Tk_DefineBitmap(tcl, Tk_GetUid("lineout"),
                  lineout_bits, lineout_width, lineout_height);
      Tk_DefineBitmap(tcl, Tk_GetUid("lineout2"),
                  lineout2_bits, lineout2_width, lineout2_height);
      Tk_DefineBitmap(tcl, Tk_GetUid("lineout3"),
                  lineout3_bits, lineout3_width, lineout3_height);
      Tk_DefineBitmap(tcl, Tk_GetUid("mike"),
                  mic_bits, mic_width, mic_height);
      Tk_DefineBitmap(tcl, Tk_GetUid("linein"),
                  linein_bits, linein_width, linein_height);
      Tk_DefineBitmap(tcl, Tk_GetUid("linein2"),
                  linein2_bits, linein2_width, linein2_height);
      Tk_DefineBitmap(tcl, Tk_GetUid("linein3"),
                  linein3_bits, linein3_width, linein3_height);
      Tk_DefineBitmap(tcl, Tk_GetUid("square"),
                  square_bits, square_width, square_height);
}

const char*
disparg(int argc, const char*const* argv, const char* optstr)
{
      const char* display = 0;
      int op;
      while ((op = getopt(argc, (char**)argv, (char*)optstr)) != -1) {
            if (op == 'd') {
                  display = optarg;
                  break;
            }
            else if (op == '?')
                  usage();
      }
#ifdef linux
      optind = 0;
#else
      optind = 1;
#endif
      return (display);
}

char*
parse_assignment(char* cp)
{
      cp = strchr(cp, '=');
      if (cp != 0) {
            *cp = 0;
            return (cp + 1);
      } else
            return ("true");
}

extern "C" {
int
TkPlatformInit(Tcl_Interp *interp)
{
      Tcl_SetVar(interp, "tk_library", ".", TCL_GLOBAL_ONLY);
#ifndef WIN32
      extern void TkCreateXEventSource(void);
      TkCreateXEventSource();
#endif
      return (TCL_OK);
}
}

int
main(int argc, char **argv)
{
      srandom(heuristic_random());

      opterr = 0;
      const char* options = "aAB:cC:d:DEf:F:g:I:jJkK:lLMnN:p:P:rRsSt:U:u:X:";
      const char* display = disparg(argc, (const char*const*)argv, options);

      Tcl::init("vat");
      Tcl& tcl = Tcl::instance();
#ifdef WIN32
      if (display == NULL)
            display = "localhost:0";
#endif
#ifdef TCL_WINDOW_EVENTS
      tcl.evalf(display?
                "set argv \"-name vat -display %s\"" :
                "set argv \"-name vat\"",
              display);
      Tk_Window tk = 0;
      if (Tk_Init(tcl.interp()) == TCL_OK)
            tk = Tk_MainWindow(tcl.interp());
#else
      Tk_Window tk = Tk_CreateMainWindow(tcl.interp(),
                                 (char*)display, "vat", "Vat");
#endif
      if (tk == 0) {
            fprintf(stderr, "vat: %s\n", tcl.result());
            exit(1);
      }
      tcl.tkmain(tk);

      loadbitmaps(tcl.interp());
      tcl.CreateCommand("stripchart", Tk_StripchartCmd, (ClientData)tk);
#ifdef WIN32
      tcl.CreateCommand("puts", WinPutsCmd, (ClientData)tk);
      tcl.CreateCommand("getusername", WinGetUserName, (ClientData)tk);
      tcl.CreateCommand("putregistry", WinPutRegistry, (ClientData)tk);
      tcl.CreateCommand("getregistry", WinGetRegistry, (ClientData)tk);
#endif
      EmbeddedTcl::init();
      tcl.evalc("init_resources");

      int op;
      while ((op = getopt(argc, argv, (char*)options)) != -1) {
            switch (op) {

            default:
                  usage();
                  exit(1);

            case 'a':
                  toggle_option("speakerAGC");
                  break;
            case 'A':
                  toggle_option("mikeAGC");
                  break;
            case 'B':
                  tcl.add_option("maxbw", optarg);
                  break;
            case 'c':
                  tcl.add_option("lectureMode", "0");
                  break;
            case 'C':
                  tcl.add_option("conferenceName", optarg);
                  break;
            case 'd':
                  /* display (already processed) */
                  break;
            case 'D':
                  tcl.add_option("meterDisable", "1");
                  break;
            case 'E':
                  tcl.add_option("externalEchoCancel", "1");
                  break;
            case 'f':
                  tcl.add_option("audioFormat", optarg);
                  break;
            case 'F':
                  tcl.add_option("audioFileName", optarg);
                  break;
            case 'g':
                  tcl.add_option("geometry", optarg);
                  break;
            case 'I':
                  tcl.add_option("confBusChannel", optarg);
                  break;
            case 'j':
                  tcl.add_option("outputPort", "Jack");
                  break;
            case 'J':
                  toggle_option("speakerMute");
                  break;
            case 'k':
                  tcl.add_option("keepSites", "1");
                  break;
            case 'K':
                  /*XXX probably do not want this in X server*/
                  tcl.add_option("sessionKey", optarg);
                  break;
            case 'l':
                  tcl.add_option("lectureMode", "1");
                  break;
            case 'L':
                  tcl.add_option("keepSites", "0");
                  break;
            case 'M':
                  toggle_option("mikeMute");
                  break;
            case 'N':
                  tcl.add_option("rtpName", optarg);
                  break;
            case 'n':
                  tcl.add_option("sessionType", "vat");
                  break;
            case 'P':
                  tcl.add_option("defaultPriority", optarg);
                  break;
            case 'r':
                  tcl.add_option("sessionType", "rtp");
                  break;
            case 'R':
                  tcl.add_option("recvOnly", "true");
                  break;
            case 's':
                  tcl.add_option("outputPort", "Speaker");
                  break;
            case 'S':
                  tcl.add_option("muteNewSites", "1");
                  break;
            case 't':
                  tcl.add_option("defaultTTL", optarg);
                  break;
            case 'u':
                  tcl.add_option("startupScript", optarg);
                  break;
            case 'U':
                  if (optarg[0] >= '0' && optarg[0] <= '9') {
                        tcl.add_option("defaultDevice", "af");
                        tcl.add_option("useAF", "true");
                        tcl.add_option("afDevice", optarg);
                  } else
                        tcl.add_option("defaultDevice", optarg);
                  break;
            case 'X':
                  {
                        const char* value = parse_assignment(optarg);
                        tcl.add_option(optarg, value);
                  }
                  break;
            }
      }

      const char* dst;
      if (optind < argc && argc > 1) {
            dst = argv[optind];
            if (argc - optind > 1) {
                  fprintf(stderr,
                        "vat: extra arguments (starting with `%s')\n",
                        argv[optind + 1]);
                  exit(1);
            }
      } else if ((dst = tcl.attr("defaultHostSpec")) == 0) {
            fprintf(stderr, "vat: destination address required\n");
            exit(1);
      }
      tcl.add_option("defaultHostSpec", dst);

      tcl.evalc("vat_main");
      initcatchers();
      /* win32 needs the following to get the initial window painted */
      tcl.evalc("update idletasks");
      Tk_MainLoop();
      adios();

      /* NOTREACHED*/
      return (0);
}

Generated by  Doxygen 1.6.0   Back to index