#ifndef lint
static char SccsId[] = "%W%  %G%";
#endif

/* Module:	maininit.c (Main Initialize)
 * Purpose:	Start of the saoimage package
 * Program:	main()
 * Subroutine:	crash_on_error()
 * Xlib calls:	XSetErrorHandler(), XCloseDisplay(), XGetErrorText()
 * UNIX calls:	setrlimit(), ieee_handler(), abrupt_underflow_()
 * Copyright:	1989-2003 Smithsonian Astrophysical Observatory
 *		You may do anything you like with this file except remove
 *		this copyright.  The Smithsonian Astrophysical Observatory
 *		makes no representations about the suitability of this
 *		software for any purpose.  It is provided "as is" without
 *		express or implied warranty.
 * Modified:	{see end of file}
 */

#include <stdio.h>		/* stderr, FILE, NULL, etc. */

#ifndef VMS
#ifdef SYSV
#include <string.h>		/* strlen, strcat, strcpy, strrchr */
#else
#include <strings.h>		/* strlen, etc. for unenlightened BSD's */
#endif
#else
#include <string.h>		/* strlen, strcat, strcpy, strrchr */
#endif

#include <sys/time.h>		/* struct timeval used in <sys/resource.h> */
#include <X11/Xlib.h>		/* X window stuff */
#include <X11/Xutil.h>		/* X window manager stuff */
#include "hfiles/constant.h"	/* define codes */
#include "hfiles/define.h"	/* YES, NO, MIN, MAX and more */
#include "hfiles/struct.h"	/* declare structure types */
#ifdef DEBUG
#ifdef SUN			/* DEBUG and SUN(OS4.xx) */
#include <floatingpoint.h>	/* SIGFPE_ABORT ieee exception switch */
#endif
#else
#ifndef VMS			/* NOT DEBUG AND NOT VMS */
#ifndef SYSV
#include <sys/resource.h>	/* rlimit, RLIMIT_CORE for setrlimit */
#endif
#endif
#endif

char *RevMsg = "SAOimage 1.35.1 1 December 2003, Doug Mink, dmink@cfa.harvard.edu";
int init_done = 0;

/* declare and initialize parameter structs */
#include "defs/control.def"
#include "defs/color.def"
#include "defs/image.def"
#include "defs/dispbox.def"
#include "defs/magnibox.def"
#include "defs/colorbox.def"
#include "defs/graphbox.def"
#include "defs/panbox.def"
#include "defs/btnbox.def"
#include "defs/desktop.def"
#include "defs/cursor.def"

/* declare uninitialized structs */
struct WorldCoor *wcs;		/* WCS data structure */
struct bufferRec buffer;
struct coordRec coord;
Display *display;		/* display connection */


/*
 * Program:	main
 * Purpose:	Get things started, then call event_loop
 * Xlib calls:	XSetErrorHandler()
 * UNIX calls:	setrlimit()
 */

static void init_params(), init_packages();

main(argc, argv)
  int argc;
  char **argv;
{
  void crash_on_error(), control_event_loop();
  void say_goodbye();
  
#ifdef DEBUG
  /* install special error handler to force crash so we can trace problem */
  XSetErrorHandler(crash_on_error);
#ifdef SUN
  /* Under SunOS4 we can force floating point exceptions to report errors */
  ieee_handler("set", "common", SIGFPE_ABORT);
  abrupt_underflow_();
#endif
#else
#ifndef VMS
#ifndef SYSV
  {
    struct rlimit rlp;	/* l: UNIX resourse limit structure */
    /* disable core dumping */
    rlp.rlim_cur = 0;
    rlp.rlim_max = 0;
    setrlimit(RLIMIT_CORE, &rlp);
  }
#endif
#endif
#endif

  /* set up, read, and check parameters */
  init_params(argc, argv);
  if( control.verbose ) {
    (void)printf("\n Smithsonian Astrophysical Observatory image utility\n");
    (void)printf(" %s\n\n", RevMsg);
  }
  init_packages(argc, argv);
  /* CALL MAIN EVENT LOOP (uses extern.h) */
  init_done = 1;
  control_event_loop();
  say_goodbye(0);
}

/*
 * Subroutine:	say_goodbye
 * Purpose:	Free server resources before exiting
 * Xlib calls:	XCloseDisplay()
 */
void say_goodbye ( code )
     int code;		/* i: code to identify exit */
{
  void free_gc();

  if( desktop.display != NULL ) {
    free_gc();
    XCloseDisplay(desktop.display);
  }
  exit(code);
}

/*
 * Subroutine:	init_params
 * Purpose:	Initialize parameters in the records
 * Note:	Resource or default file not yet used
 */

static void init_server();

static void init_params ( argc, argv )
     int argc;
     char **argv;
{
  char *name;		/* l: both flag for init and return display name */
  int parse_stat;
  int parse_cmdline(), check_image();
  void say_goodbye(), init_connections();

  name = NULL;
  img.fsmin = 0;
  img.fsmax = 0;

  if( (parse_stat = parse_cmdline(argc, argv, &name)) < 0 )
    say_goodbye(1);
  /* check image parameters for consistency (uses extern.h) */
  if( check_image(&img, parse_stat) )
    img.file_type = SOP_Logo;
  /* connect to the display server */
  init_server(name, &desktop, &color);
  init_connections();
}

/*
 * Subroutine:	init_packages
 * Purpose:	Initialize all of the subroutine packages and windows
 */
static void init_packages ( argc, argv )
     int argc;
     char **argv;
{
  GC gc;
  int init_image();
  GC set_gc_with_background();
  void init_windows1(), init_windows2(), init_panbox_coords(), disp_dispbox();
  void disp_panbox(), init_imaging_buffers(), init_mousepointers(), init_gc();
  void init_display_buffers(), init_region_draw(), init_color(), new_display();
  void init_software_cursors(), init_buttonmenu(), init_buttonbox_settings();
  void init_magnifier(), set_magnifier(), redraw_magnifier(), init_colorbox();
  void say_goodbye(), mount_buttonmenu(), new_panimage(), init_cgraph_text();
  void move_pointer();

  /* get the image dimensions (need file name, type), exit if failure */
  if( init_image() == 0 ) {
    (void)fprintf(stderr, "No image given and no input device connected.\n");
    say_goodbye(1);
  }
  /* get the colors ready (need display) */
  init_color(&color, 1);
  /* map the desktop(need image dimensions, color) */
  init_windows1(argc, argv);
  /* set up the mouse pointer icons (need display, hardcolors) */
  init_mousepointers(desktop.display, desktop.display);
  /* initialize color bar and graph labeling text font and parameters */
  init_gc(desktop.display, desktop.ID);
  init_cgraph_text();
  /* set up the image buffer (need image) */
  init_imaging_buffers();
  /* get desktop dimensions and create windows (need colors, mouse cursors) */
  init_windows2();
  /* get the soft cursors ready(need colors, img coords) */
  init_software_cursors();
  /* set up color bar */
  init_colorbox();
  /* set up display buffers (need window dimensions) */
  init_display_buffers();
  /* set params and get image data (need colors, buffers, scope, imageinit) */
  init_panbox_coords();
  init_magnifier(control.magni_track, control.coord_track);
  new_display(0, 1, 1, 1);
  /* move image data into the panbox's buffer */
  new_panimage();
  /* set up the button menu */
  gc = set_gc_with_background(&color.gcset.menu, color.gcset.menu.background);
  init_buttonmenu(&btnbox, gc, color.visual,
		  (unsigned long)color.hard.std_black,
		  (unsigned long)color.hard.std_white);
  init_buttonbox_settings();
  /* set up region action flags and drawing stuff (draw and label on) */
  init_region_draw(1, 1);
  mount_buttonmenu();
}

#ifdef DEBUG
/*
 * Subroutine:	crash_on_error
 * Purpose:	Special error handler to force crash on error
 * Xlib calls:	XGetErrorText()
 */
void crash_on_error ( dt_display, error )
     Display *dt_display;
     XErrorEvent *error;
{
  int *foo;
  char mrq[SZ_LINE], msg[SZ_LINE];

  (void)fprintf(stderr,"XError Reported: (code=%d) ",error->error_code);
  XGetErrorText(dt_display, (int)error->error_code, msg, SZ_LINE);
  (void)fprintf(stderr, "%s\n", msg);
  /* get additional info (SGK) */
  sprintf(mrq, "%d", error->request_code);
  XGetErrorDatabaseText(dt_display, "XRequest", mrq, "unknown", msg, SZ_LINE);
  /* print it out */
  (void)fprintf(stderr, 
                "  Major opcode of failed request: %d (%s), minor: %d\n",
                error->request_code, msg, error->minor_code);
  (void)fprintf(stderr,
                "  Serial number of failed request: %d\n", 
                error->serial);
  /* cause fatal core dump */
  foo = 0;
  *foo = 0;
  exit( 0 );
}
#endif

/*
 * Subroutine:	init_server
 * Purpose:	Open connection with chosen or default display server
 */
static void init_server ( displayname, desktop, color )
     char *displayname;
     struct windowRec *desktop;
     struct colorRec *color;
{
  Display *dt_display;
  int dt_screen;
  char errmsg[SZ_FNAME];
  void exit_errmsg();

  /* make contact with the display server */
  if( !(dt_display = XOpenDisplay(displayname)) ) {
    (void)strcpy(errmsg, "Could not connect to display: ");
    if( displayname != NULL )
      (void)strcat(errmsg, displayname);
    exit_errmsg(errmsg);
  }
  desktop->display = dt_display;
  color->display = dt_display;
  dt_screen = DefaultScreen(dt_display);
  desktop->screen = dt_screen;
  color->screen = dt_screen;
  display = dt_display;
}
/* May  9 1989	Michael VanHilst initial version
 *
 * Feb 19 1990	MVH BSDonly strings.h compatability
 *
 * Nov 10 1993	Doug Mink version 1.08: autoscale
 *
 * Oct 19 1994	DJM version 1.09: Add WCS tracking
 * Dec 22 1994	DJM version 1.10: Add CD to WCS
 *
 * Jan 20 1995	DJM version 1.11: Handle narrow files
 * Mar  1 1995	DJM version 1.12: Add DSS plate sol.
 * May  5 1995	DJM version 1.13: Fix bugs from STScI
 * May  5 1995	DJM version 1.13: Fix DSS plate sol.
 * Aug 16 1995	DJM version 1.14: Add coordinate conv.
 * Oct 18 1995	DJM version 1.15: Bug fixes
 * Nov  7 1995	DJM version 1.16: DSS WCS Bug fix
 * Dec 14 1995	DJM version 1.17: IRAF .imh WCS
 * Dec 22 1995	DJM version 1.17: SECPIX WCS
 *
 * Jan  2 1996	DJM version 1.17: Initial zoom factor
 * Feb  2 1996	DJM version 1.17: Fix pixel tracking
 * Feb  9 1996	DJM version 1.18: Fix IRAF header
 * Feb 26 1996	DJM version 1.18: Fix various bugs
 * Sep  6 1996	DJM version 1.19: Improved WCS
 
 * Jan 27 1997	DJM version 1.20: Improved WCS
 * Jun  6 1997	DJM version 1.20: Fixed scaling
 *
 * Jan  9 1998	DJM version 1.21: Fix precession bug
 * Jan 14 1998	DJM version 1.21: Read IRAF 2.11 im.
 * Jan 21 1998	DJM version 1.21: Fix WCS output set
 * Feb 18 1998	DJM version 1.22: Add Calabretta WCS
 * Mar 16 1998	DJM version 1.22: Add NOAO TNX WCS
 * Apr 13 1998	DJM version 1.22: Add plate polynom.
 * Apr 14 1998	DJM version 1.22: Add ecliptic coords
 * Apr 17 1998	DJM version 1.22: Add new IRAF types
 * May  4 1998	DJM version 1.22: Fix LINEAR WCS
 * May 15 1998	DJM version 1.22: Add image system
 * May 20 1998	DJM version 1.22: Fix WCS get bugs
 * Jun  2 1998	DJM version 1.23: Fix hput bug
 * Jun 25 1998	DJM version 1.23: Revised WCS subs
 * Jul  7 1998	DJM version 1.23: Handle 3-D WCS
 * Jul 13 1998	DJM version 1.23.1: Fix various bugs
 * Jul 16 1998	DJM version 1.23.2: Fix quad cube prj
 * Jul 17 1998	DJM version 1.23.3: Dropped global wcs
 * Jul 20 1998	DJM version 1.23.4: Fixed ifdef
 * Aug  6 1998	DJM version 1.24: Add COE projection
 * Aug 12 1998	DJM version 1.24: Add cursor centering
 * Aug 14 1998	DJM version 1.24: Add multiple command
 * Sep  4 1998	DJM version 1.24: Fix WCS image rotation
 * Sep 16 1998	DJM version 1.24.1: Add NPOL; fix WCS
 * Sep 30 1998	DJM version 1.25: Change WCSLIB headers
 * Oct 19 1998	DJM version 1.25: Add catalog plotting
 * Oct 29 1998	DJM version 1.25: Add key zoom + header
 * Nov  6 1998	DJM version 1.25: Improve key zoom
 * Nov 12 1998	DJM version 1.25: Fix mirrored images
 * Nov 18 1998	DJM version 1.25: Fix imh2 pixfiles
 * Nov 23 1998	DJM version 1.25: Add help and version options
 * Nov 30 1998	DJM version 1.25: Fix bug reading very large FITS headers
 * Nov 30 1998	DJM version 1.25: Fix a variety of bugs found by Paul Sydney
 * Aug 16 1999	DJM version 1.26: Fix number of decimal places in degree coords
 * Nov  5 1999	DJM version 1.26.8: Fix bugs; add mod date to imh files
 * Nov 17 1999	DJM version 1.26.9: Fix bug which disabled NCP projection
 * Dec 10 1999	DJM version 1.26.10: Fix bug with strings starting with d and e
 * Dec 11 1999	DJM version 1.26.11: Fix bugs in date conversion
 *
 * Jan 21 2000	DJM version 1.27.0: Upgrade to WCSLIB 2.5
 * Mar 27 2000	DJM version 1.27.2: Fix .imh bug which failed on long pathnames
 * Sep 29 2000	DJM version 1.28.5: Use CD matrix if any one CD keyword present
 * 
 * Feb 15 2001	DJM version 1.28.7: Upgrade to WCSLIB 2.6
 * Feb 28 2001	DJM version 1.29.1: Implement multiple WCS selection
 * Mar  8 2001	DJM version 1.29.2: Change multiple WCS separator from : to %
 * Mar 20 2001	DJM version 1.29.3: Fix possible problems in wcssubs
 * Sep 25 2001	DJM version 1.30.5: Upgrade to WCSLIB 2.7
 * Dec  4 2001	DJM version 1.30.6: Fix bug in readfits; modify linux makefile
 * Dec 20 2001  SGK version 1.30.7: Make SAOimage 24-bit display compliant
 *
 * Jan 16 2002	DJM version 1.30.7: Display 5 digits of pixel value
 * Feb 13 2002	DJM version 1.30.7: Fix bug in ecliptic coordinate conversion
 * Apr  8 2002	DJM version 1.31.0: Implement WCSLIB 2.9 and better multi-WCS
 * Apr 19 2002	DJM version 1.31.1: Fix bugs in TNX and EQUINOX implementations
 * Apr 23 2002	DJM version 1.31.1: Fix bugs in key command code
 * Aug 30 2002	DJM version 1.31.3: changes in WCS subroutines
 *
 * Jan  3 2003	DJM version 1.32.1: Fix ZPN bugs in wcsinit()
 * Mar 25 2003	DJM version 1.33.1: Fix minor bugs in FITS and date utilities
 * Apr  2 2003	DJM version 1.33.2: Add SIRTF distortion
 * May  8 2003	DJM version 1.33.4: Fix bug in reading ZPN PROJP0 coefficient
 * May 28 2003	DJM version 1.34.0: Fix bug initializing PROJPn coefficients
 * Sep  3 2003	DJM version 1.34.1: Improved printing and old FITS dates
 * Sep 24 2003	DJM version 1.35.0: Fix vector difference 'v' command
 * Oct 31 2003	DJM version 1.35.0: Ignore IRAF image beyond image columns
 * Nov 18 2003	DJM version 1.35.0: Drop malloc.h from wcssubs/lin.c
 * Dec  1 2003	DJM version 1.35.1: Fix bug setting projection parameters
 */


syntax highlighted by Code2HTML, v. 0.9.1