/*
    Clif - A C-like Interpreter Framework
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997 T. Hruz, L. Koren

    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.

*/

/*
 * wind.c
 *
 * Graphical window opening.
 */
#include <X11/Xlib.h>
#include <string.h>

XGCValues value;



Window  root;

XWindowAttributes root_window_att;
XSetWindowAttributes mywin_att;

extern int errno;

int screen;
int width, height;
int x=0,y=0;
unsigned int width_w, height_w,border=3;
unsigned long bord=1L,back=0L;

int wind PROTO((void));

int
wind () 
{
  int cnt;
#ifdef FORK_YES
  char arg1[32],arg2[32];
#endif
#if 0
  printf(" starts \n");
#endif
  if ((disp = XOpenDisplay (NULL)) == NULL)
    {
      printf (" XOpen fails \n");
      return (-1);
    }

#if 0
  XSynchronize(disp,1);
#endif

  root = XDefaultRootWindow (disp);
  screen = XDefaultScreen (disp);
#if 0
  if (!XGetWindowAttributes (disp, root, &root_window_att))
    {
      printf("get window att failed \n");
      exit(0);
    }

  XSynchronize (disp, 1);
#endif

  width = XDisplayWidth (disp, screen);
#if 0
  XSynchronize (disp, 1);
#endif
  height = XDisplayHeight (disp, screen);
#if 0
  XSynchronize (disp, 1);
  printf ("w: %d, h: %d \n", width, height);
#endif

  default_gc = XDefaultGC (disp, screen);
#if 0
  XSynchronize (disp, 1);
#endif

  XSetState (disp, default_gc, 0L, 0L, GXcopy, 0xffffffffL);
#if 0
  XSynchronize (disp, 1);
  printf ("xsetstate\n");
#endif


  width_w = channel[channel_handle].w_resolution[0];
  height_w = channel[channel_handle].w_resolution[1];



   /* 
    * Window attributes.
    */
  mywin_att.background_pixmap = None;
  mywin_att.background_pixel = 0L;
  mywin_att.border_pixmap = CopyFromParent;
  mywin_att.border_pixel = 1L;
  mywin_att.bit_gravity = ForgetGravity;
  mywin_att.win_gravity = NorthWestGravity;
  mywin_att.backing_store = Always;
  mywin_att.backing_planes = 0xffffffffL;
  mywin_att.backing_pixel = 0L;
  mywin_att.save_under = True;
  mywin_att.event_mask = KeyPressMask|ExposureMask|ButtonPressMask|VisibilityChangeMask|SubstructureNotifyMask|StructureNotifyMask;
  mywin_att.do_not_propagate_mask = NoEventMask;
  mywin_att.override_redirect = False;
  mywin_att.colormap = CopyFromParent;
  mywin_att.cursor = None;

    /* 
     * Creates a window.
     */
  channel[channel_handle].mywin
    = XCreateWindow (disp, root, x, y, width_w, height_w, border,
		     CopyFromParent, InputOutput, CopyFromParent,
		     CWBackPixel|CWSaveUnder|CWBackingStore|CWEventMask|CWBackingPlanes|CWDontPropagate,
		     &mywin_att);

#ifdef FORK_YES
   /* 
    * Creates a pixmap.
    * It is used when the exposure event occurs.
    */
  channel[channel_handle].mypix
    = XCreatePixmap (disp, channel[channel_handle].mywin, width_w,
		     height_w, XDefaultDepth (disp, screen));
#endif
#if 0
  XSynchronize (disp, 1);
  printf ("xcreatewindow\n");
#endif

  value.background = 0L;
  value.graphics_exposures = True;

/*
 * Fills the structure.
 */
  for (cnt = 0; cnt < channel[channel_handle].fields; cnt++)
    {
      value.foreground = channel[channel_handle].member[cnt].style;

      channel[channel_handle].member[cnt].set_gc
	= XCreateGC (disp, channel[channel_handle].mywin,
		     GCForeground|GCBackground|GCGraphicsExposures,
		     &value);
      if (channel[channel_handle].d_time == 0)
	window (channel_handle, cnt,
		channel[channel_handle].start_time,
		channel[channel_handle].member[cnt].lower,
		channel[channel_handle].start_time +
		channel[channel_handle].duration_time,
		channel[channel_handle].member[cnt].upper);
      else
	window (channel_handle, cnt,
		channel[channel_handle].start_time,
		channel[channel_handle].member[cnt].lower,
		LINEAR_WINDOW_CONSTANT *
		(channel[channel_handle].start_time + pow
		 (channel[channel_handle].duration_time, 2.)),
		channel[channel_handle].member[cnt].upper);
    }
#if 0
  XSynchronize (disp, 1);
  printf ("xsetstate + window loop\n");
#endif


  XClearWindow (disp, channel[channel_handle].mywin);
#ifdef FORK_YES
  XFillRectangle (disp, channel[channel_handle].mypix, default_gc, 0,
		  0, channel[channel_handle].w_resolution[0],
		  channel[channel_handle].w_resolution[1]);
#endif
#if 0
  XSynchronize (disp, 1);
#endif

/*
 * Name of the window.
 */
  sprintf (window_name_tmp, "%d", channel_handle);
  strcat (window_name_cur, window_name_tmp);
  XStoreName (disp, channel[channel_handle].mywin, window_name_cur);
  strcpy (window_name_cur, window_name_init);
#if 0
  XSynchronize (disp, 1);
  printf ("xstorename\n");
#endif


  XMapWindow (disp, channel[channel_handle].mywin);
#if 0
  XSynchronize (disp, 1);
  printf ("xmapwindow\n");

  XSynchronize (disp, 1);
#endif

  XWindowEvent (disp, channel[channel_handle].mywin, ExposureMask, &event);

#if 0
  printf (" I am after \n");

  XSynchronize (disp, 1);
#endif


/*
 * Fork for managers that cannot manage exposure events.
 */
#ifdef FORK_YES
  if ((channel[channel_handle].ch_pid = fork ()) < 0)
    printf ("could not fork %d\n", errno);
  else if(channel[channel_handle].ch_pid  ==  0)         /* child */
    {
      sprintf (arg1, "%ld", channel[channel_handle].mywin);
      sprintf (arg2, "%ld", channel[channel_handle].mypix);
#if 0
      printf ("fork child\n");
#endif
      execl("rw", "rw", arg1, arg2, (char *)0);
      printf ("errno %d\n", errno);
      printf ("bad exec\n");
    }
  /* parent */
#endif /* FORK_YES */
  
  return (channel_handle);
}
