/* Communication subprocess for GNU Emacs acting as server.
   Copyright (C) 1992-1994 Eberhard Mattes

This file is part of GNU Emacs.

GNU Emacs 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, or (at your option)
any later version.

GNU Emacs 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 GNU Emacs; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include <stdio.h>
#include <stdlib.h>

#include <sys/process.h>

#define INCL_DOSQUEUES
#define INCL_DOSPROCESS
#define INCL_WINSWITCHLIST
#include <os2.h>

static void error (ULONG rc, const char *fun)
{
  fprintf (stderr, "%s failed, rc=%lu\n", fun, rc);
  exit (1);
}

#define ERROR(fun) if (rc != 0) error (rc, fun)

static void from_emacs (void *arg)
{
  ULONG rc, len;
  HQUEUE hq_server;
  REQUESTDATA request;
  BYTE priority;
  PVOID data;
  long emacs_pid;
  char *p;

  if ((p = getenv ("EMACS_PID")) != NULL)
    emacs_pid = strtol (p, NULL, 10);
  else
    emacs_pid = 0;
  
  rc = DosCreateQueue (&hq_server, QUE_FIFO | QUE_CONVERT_ADDRESS,
                       "/queues/emacs19/server");
  ERROR ("DosCreateQueue");
  for (;;)
    {
      rc = DosReadQueue (hq_server, &request, &len, &data, 0,
                         DCWW_WAIT, &priority, 0);
      ERROR ("DosReadQueue");
      printf ("Client: %d ", (int)request.pid);
      fputs (data, stdout);
      fflush (stdout);
      rc = DosFreeMem (data);
      ERROR ("DosFreeMem");
      if (emacs_pid != 0)
        WinSwitchToProgram (WinQuerySwitchHandle (0, emacs_pid));
    }
}


int main (void)
{
  HQUEUE hq_client;
  ULONG rc, len;
  PID owner_pid;
  PVOID data;
  char buffer[1024], name[512], *p;
  long client_pid;
  HSWITCH hSwitch;
  SWCNTRL swctl;

  hSwitch = WinQuerySwitchHandle (NULLHANDLE, getpid ());
#if 0
  if (WinQuerySwitchEntry (hSwitch, &swctl) == 0)
    {
      strcpy (swctl.szSwtitle, "Emacs server");
      WinChangeSwitchEntry (hSwitch, &swctl);
    }
#else
  WinRemoveSwitchEntry (hSwitch);
#endif

  _beginthread (from_emacs, NULL, 0x8000, NULL);
  for (;;)
    {
      if (fgets (buffer, sizeof (buffer), stdin) == 0)
        return (0);
      p = buffer;
      while (*p != 0 && !(*p >= '0' && *p <= '9'))
        ++p;
      client_pid = strtol (p, NULL, 10);
      sprintf (name, "/queues/emacs19/clients/%ld", client_pid);
      rc = DosOpenQueue (&owner_pid, &hq_client, name);
      if (rc == 0)
        {
          len = strlen (buffer) + 1;
          rc = DosAllocSharedMem (&data, 0, len,
                                  PAG_COMMIT | OBJ_GIVEABLE | PAG_READ
                                  | PAG_WRITE);
          ERROR ("DosAllocSharedMem");
          rc = DosGiveSharedMem (data, client_pid, PAG_READ);
          ERROR ("DosGiveSharedMem");
          memcpy (data, buffer, len);
          rc = DosWriteQueue (hq_client, 0, len, data, 0);
          ERROR ("DosWriteQueue");
          rc = DosFreeMem (data);
          ERROR ("DosFreeMem");
          rc = DosCloseQueue (hq_client);
          ERROR ("DosCloseQueue");
        }
    }
}
