/* This file is part of the Project Athena Zephyr Notification System.
 * It contains error handling functions for WindowGram
 *
 *	Created by:	Mark W. Eichin
 *
 *	$Source: /mit/zephyr/src/zwgc/RCS/wg_errors.c,v $
 *	$Author: jtkohl $
 *
 *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
 *	For copying and distribution information, see the file
 *	"mit-copyright.h". 
 */
#include <zephyr/mit-copyright.h>
#ifdef X11
#include <X11/Xlib.h>
#include <X11/Xproto.h>
#endif /* X11 */

#ifndef lint
static char rcsid_wg_errors_c[] = "$Header: wg_errors.c,v 2.7 89/07/20 10:06:16 jtkohl Exp $";
#endif lint


#include <signal.h>
#include <stdio.h>
/*
 * signal_logout
 *
 * signal handler for SIGHUP that sets a flag to be read when we fall
 * out of the select() loop above.
 *
 */
extern int logout_flag;
extern int ok_int_flag;
extern int reload_flag;
extern int debug_flag;

signal_logout()
{
  logout_flag=1;		/* set global logout flag */
}

#include <sys/wait.h>
signal_child()
{
  union wait wstat;
  int pid;
  pid = wait(&wstat);		/* make the fork happy... */
  ok_int_flag = 1;		/* shut off message for now... */
}

signal_reload()
{
  reload_flag = 1;
}

signal_debug()
{
  if(debug_flag)
    {
      printf("zwgc:wg_errors Debugging signal not reaching main loop, jumping anyway...\n");
      global_debug();
    }
  else
    {
      debug_flag = 1;
    }
}

/*
 * signal_initialize
 *
 * sets up all of the signal handling we need. For now, just trap
 * SIGHUP so we know when to quit. (and SIGINT/SIGQUIT for convenience.)
 *
 */
extern int xdebug;

signal_initialize()
{
  signal(SIGTERM,signal_logout);
  signal(SIGHUP,signal_logout);
  signal(SIGINT,signal_logout);
  signal(SIGQUIT,signal_logout);
  signal(SIGCHLD,signal_child);
/*  signal(SIGUSR1,signal_reload); */
  signal(SIGUSR2,signal_debug);
  if(xdebug) return;
  sigsetmask(sigmask(SIGINT)
	     | sigmask(SIGQUIT)
	     | sigmask(SIGTSTP));
}

#ifdef X11
int x_io_error_handler(dd)
     Display *dd;
{
  /* This usually means we lost it altogether... */
  perror("WindowGram exiting: XIO");
  exit_cleanly();
}

extern int x_recent_error;
int x_error_handler(dpy, rep)
     Display *dpy;
     XErrorEvent *rep;
{
  /* Well, we got an error... what now? this time, we ignore it... */
  char erf[1024], errn[32];
  extern void wmerror_stackunder();

  x_recent_error++;

  if((rep->error_code == 3) && (rep->request_code == X_DestroyWindow))
    {
      return(0);
    }
  
  if (rep->request_code == X_ConfigureWindow && rep->error_code == BadMatch) {
      /* got an error while restacking, use ICCCM method */
      wmerror_stackunder(rep->serial);
      return(0);
  }

  XGetErrorText(dpy, rep->error_code, erf, 1024);
  fprintf(stderr, "zwgc:X11 Error: %s\n", erf);
  sprintf(errn,"%d",rep->request_code);
  XGetErrorDatabaseText(dpy, "XRequest", errn, "Unknown Request", erf, 1024);
  fprintf(stderr, "         Request code: %d [%s]\n", rep->request_code, erf);
  fprintf(stderr, "         Request function: %d\n", rep->minor_code);
  fprintf(stderr, "         Request resourceid 0x%x\n", rep->resourceid);
  fprintf(stderr, "         Error Serial #%d\n", rep->serial);
  fflush(stderr);

  return(0);
}

x_handler_initialize()
{
  XSetIOErrorHandler(x_io_error_handler);
  XSetErrorHandler(x_error_handler);
  return(0);
}



error_handler_initialize()
{
  signal_initialize();
  x_handler_initialize();
}


#else
error_handler_initialize()
{
  signal_initialize();
}
#endif /* X11 */
