/*-----------------------------------------------------------------------------
  FmComms.c

  (c) Simon Marlow 1990-1993

  support for recieving instructions from other X processes
------------------------------------------------------------------------------*/

#include <X11/Intrinsic.h>

#include "Fm.h"
#include "Am.h"
#include "../xfmc/xfmc.h"

static Atom open_atom, update_atom;

/*-----------------------------------------------------------------------------
  The client message handler must be re-entrant (because error() can cause more
  events to be dispatched), and it must also handle sequences of events that 
  make up a complete message. Currently we just ignore any recursive calls to 
  the message handler.
-----------------------------------------------------------------------------*/
static void clientMessageHandler(Widget w, XtPointer closure, XEvent *e, 
				 Boolean *b)
{
  XClientMessageEvent *c = (XClientMessageEvent *) e;
  static char *mes = NULL;
  static Atom current = None;
  static int i = 0;
  static Boolean in_here = False;
  int j;

  if (in_here) {
    fprintf(stderr,"xfm: warning: ignoring subsequent message due to error\n");
    return;
  }
  in_here = True;

  if (e->type != ClientMessage)
    return;

  if (c->message_type != open_atom && c->message_type != update_atom) {
    error("Someone is trying to tell me something,",
	  "but I don't understand!");    
    return;
  }

  if (current && c->message_type != current) {
    error("Received an out-of sync message:","I'm ignoring it");
    return;
  }

  mes = XTREALLOC(mes,i+20);
  for (j = 0; j < 20 ;j++) {
    mes[i+j] = c->data.b[j];
    if (!c->data.b[j]) {
      if (c->message_type == open_atom)
        newFileWindow(mes,resources.default_display_type,False);
      else {
	markForUpdate(mes);
	intUpdate();
      }
      printf("%s\n",mes);
      XTFREE(mes);
      mes = NULL;
      current = None;
      i = 0;
      in_here = False;
      return;
    }
  }

  i += 20;
  current = c->message_type;
  in_here = False;
}

void initComms(void)
{
  /* Make up some new atoms */
  open_atom   = XInternAtom(XtDisplay(aw.shell), XFM_OPEN_WINDOW,   False);
  update_atom = XInternAtom(XtDisplay(aw.shell), XFM_UPDATE_WINDOW, False);

  if (open_atom == None || update_atom == None)
    abortXfm("Unable to create atoms");

  /* Make sure we get clientMessages. Not sure if this is the best way
     to do it, but it seems to work. */
  XtAddEventHandler(aw.shell, None, True, clientMessageHandler, NULL);
}
