/*
 * Copyright 1988, 1989, 1990, 1991 Massachusetts Institute of Technology
 */
#include"../../Glib/Glib.h"
#include"xpointer.h"
#include<stdio.h>
#include<signal.h>


Display *dpy;
Window root, *volume_windows, left_enable, right_enable, video_enable, 
  toggle_video, icon, shuttlebar, rjog, stop, fjog, play, index_win, 
  search, frame_win, exit_win, load_win, unload_win, audio_one, 
  audio_two, speed_win, speed_in_win, message_window;
  
#ifdef PLX
Window livevideo,save_query_win, filename_win, ok_win, cancel_win;
Pixmap grab_pix;
char save_filename[100];
int plx = 1;
int child_running = 0;
#ifdef SYSV
#ifndef SIGCHLD
#define SIGCHLD SIGCLD
#endif /* SIGCHLD */
#endif /* SYSV */
#endif

Colormap cmap;
Cursor lightcursor, leftcursor, rightcursor, playcursor, searchcursor,
  loadcursor, audiocursor, indexcursor, stopcursor;
GC gc, normtext, move_gc, brighttext, green_gc, red_gc, orange_gc, black_gc;
int screen, realheight, max_volumes = 0;
Visual *visual;
XColor background, foreground, nonhighlight, highlight, mousecolor, border,
  green, red, orange, black;
XContext button_context, expose_context, null_context, which_context, 
    enter_context, leave_context, string_context, key_context, width_context,
    msg_context;
XFontStruct *normfont;

Server *serv;
int cur_volume = 0, l_cur_volume = 0, v_cur_volume = 0, r_cur_volume = 0;
int cur_mask = ALL_CHAN, cur_speed = 0, frame = 0, event_mask;
char frameinput[1000], speedinput[1000], cur_speed_string[1000];

int child_pids[10];
char child_strings[10][100];

short DEBUG = 0;
short ISVIDEO = 0;

int *the_which_tree, border_width = -1;

char *back_string = NULL, *fore_string = NULL, *nonhigh_string = NULL,
  *high_string = NULL, *mouse_string = NULL, *border_string = NULL,
  *left_string = NULL, *right_string = NULL, *video_string = NULL,
  *fill_string = NULL, *font_string = NULL, *geom_string = NULL,
  *prog_string = "gctl";

typedef int (*PFI)();

main(argc, argv)
     int argc;
     char **argv;
{
  XEvent event;
  XContext context;
  int (*proc)(), i, maj, fev, fer;
  char temp[1024], *display_string, *getenv(), *server_string = NULL,
  *temp_str;
  long cur_time;
  extern int error_handler(), the_grim_reaper();
  char *data;

  prog_string = argv[0];

  display_string = getenv("DISPLAY");
  if (!display_string) {
    printf("Must set a DISPLAY variable.\n");
    exit(1);
  }

  for (i = 1 ; i < argc ; i++){
    if (strcmp(argv[i],"debug") == 0) DEBUG = 1;
    else if (strcmp(argv[i],"-debug") == 0) DEBUG = 1;
    else if (strcmp(argv[i],"-server") == 0) server_string = argv[++i];
    else if (strcmp(argv[i],"-display") == 0) display_string = argv[++i];
    else if (strcmp(argv[i],"-bg") == 0) back_string = argv[++i];
    else if (strcmp(argv[i],"-fg") == 0) fore_string = argv[++i];
    else if (strcmp(argv[i],"-mo") == 0) nonhigh_string = argv[++i];
    else if (strcmp(argv[i],"-hl") == 0) high_string = argv[++i];
    else if (strcmp(argv[i],"-ms") == 0) mouse_string = argv[++i];
    else if (strcmp(argv[i],"-bd") == 0) border_string = argv[++i];
    else if (strcmp(argv[i],"-bw") == 0) border_width = atoi(argv[++i]);
    else if (strcmp(argv[i],"-lc") == 0) left_string = argv[++i];
    else if (strcmp(argv[i],"-vc") == 0) video_string = argv[++i];
    else if (strcmp(argv[i],"-rc") == 0) right_string = argv[++i];
    else if (strcmp(argv[i],"-fl") == 0) fill_string = argv[++i];
    else if (strcmp(argv[i],"-fn") == 0) font_string = argv[++i];
    else if (strcmp(argv[i],"-g") == 0) geom_string = argv[++i];
#ifdef PLX
    else if (strcmp(argv[i],"-noplx") == 0) plx = 0;
#endif PLX
    else fprintf(stderr, "gctl: unable to parse unknown option %s", argv[i]);
  }

  if (!(dpy = XOpenDisplay(display_string))) {
    printf("Could not open X server on %s\n",display_string);
    exit(1);
  }
  screen = DefaultScreen(dpy);
#ifdef PLX
  if (!XQueryExtension( dpy, "ParallaxVideo", &maj, &fev, &fer)) plx = 0;
#endif PLX
  if (DEBUG) {
    printf("X Server is owned by %s and is revision %d.\n",
	   ServerVendor(dpy),VendorRelease(dpy));
    printf("X Server is version %d, protocol revision %d.\n",
	   ProtocolVersion(dpy),ProtocolRevision(dpy));
    printf("There are %d colormaps available.\n",
	   MaxCmapsOfScreen( &(dpy->screens[screen] )));
    fflush(stdout);
  }

  if (border_width == -1) {
    temp_str = XGetDefault(dpy, prog_string, "BorderWidth");
    if (temp_str)
      border_width = atoi(temp_str);
    else
      border_width = 0;
  }

  the_which_tree = (int *)malloc(256 * sizeof(int));
  for (i = 0; i < 256; i++)
    the_which_tree[i] = i;

  for (i = 0; i < 10; i++)
    child_pids[i] = -1;

  GSetState((int)DEBUG,NULL,SYNC_MODE);
  serv = GNewOpenServer(server_string);
  if (serv == NULL) {
    printf("Could not open Galatea server on %s\n", GOpenedHost());
    exit(2);
  }
  if (DEBUG) {
    cur_time = GGetServerTime(serv);
    printf("Current Galatea server time is %s", ctime(&cur_time));
  }
  strcpy(frameinput,"1");
  strcpy(cur_speed_string, "0");
  strcpy(speedinput, "30");
  GSetErrorHandler(error_handler);
  GSwitch(serv, GVolumeIndex(serv,0), ALL_CHAN);
  GRelease(serv);
  if (DEBUG) printf("Volumes available for video service:\n");
  for (i = 0; i < GNumberVolumes(serv); i++) {
    if (DEBUG) printf("%s\n",GVolumeName(serv,i));
  }

  setmap();
  create_cursor();
  setcontext();
  create_root();
  create_gcs();
  get_fonts();
  create_windows();
  event_mask = ButtonPressMask | ExposureMask | EnterWindowMask |
    LeaveWindowMask | KeyPressMask | ButtonReleaseMask | PointerMotionMask;
#ifdef PLX
  signal(SIGCHLD, the_grim_reaper);
#endif PLX
  set_cur_vol();
  while(1) {
    if (!XCheckMaskEvent( dpy, ButtonPressMask | KeyPressMask, &event))
/*      XMaskEvent( dpy, event_mask, &event);*/
      XNextEvent( dpy, &event);

    context = null_context;
    switch (event.type) {
    case ButtonPress:
      context = button_context;
      break;
    case EnterNotify:
      context = enter_context;
      break;
    case LeaveNotify:
      context = leave_context;
      break;
    case KeyPress:
      context = key_context;
      break;
    case ClientMessage:
      context = msg_context;
      break;
    case Expose: /* let's just redraw once per blocks of exposures */
      if (!event.xexpose.count) context = expose_context; /* a la Hal */
      break;
    }
 
    if (context != null_context) 
      if (!XFindContext( dpy, event.xany.window, context, (caddr_t *)&data))
	{
	  proc = (PFI) data;
	  (*proc)(event);
	}
    
  }
}
#ifdef PLX
int the_grim_reaper()
{
  int this_child, i;
  this_child = wait(0);
  if (this_child == -1) return(0);
  child_running = 0;
  for (i = 0; i < 10; i++) {
    if (this_child == child_pids[i]) {
      display_message(child_strings[i]);
      child_pids[i] = -1;
      break;
    }
  }
  return(0);
}
#endif PLX
