/*
 *               Copyright 1990 by Digital Equipment AB, Sweden
 * 
 *                                   and
 * 
 *                        Hakan Huss and Johan Ihren
 * 
 *                            All Rights Reserved
 * 
 *     Permission to use, copy, modify, and distribute this software and
 *     its documentation for any purpose and without fee is hereby
 *     granted, provided that the above copyright notice appear in all
 *     copies and that both that copyright notice and this permis-
 *     sion notice appear in supporting documentation, and that the
 *     names of the copyright holders not be used in advertising in
 *     publicity pertaining to distribution of the software without
 *     specific, written prior permission. The copyright holders make no
 *     representations about the suitability of this software for any
 *     purpose. It is provided "as is" without express or implied warranty.
 * 
 *     THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO
 *     THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
 *     ABILITY AND FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS
 *     BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 *     ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 *     PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 *     TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
 *     OR PERFORMANCE OF THIS SOFTWARE.
 * 
 *     Authors: Hakan Huss, KTH and Johan Ihren, KTH
 */

/*
 * $Header: /deneb/src0/johani/scix-0.96/src/RCS/rwsock.c,v 1.2 90/04/01 13:52:48 johani Exp $
 *
 * rwsock.c -- various lowlevel routines in SCIX that had to be written in C.
 *
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <sys/time.h>
#include <fcntl.h>
#include <signal.h>

#include <X11/Xlib.h>

int scix_connectdisplay(name)
char *name;
  {
  int fd, screenp, dpynump, familyp, saddrlenp;
  char fullnamep[256], saddrp[256];
  
  fullnamep[0] = saddrp[0] = '\0';

#ifdef DEBUG
  printf("scix_connectdisplay: arg = \"%s\"\n", name); 
#endif
  if (!(int)name)
    name = (char *)getenv("DISPLAY");
#ifdef DEBUG
  printf("scix_connectdisplay: displayname = \"%s\"\n", name); 
#endif  
  fd = _XConnectDisplay(name, fullnamep, &dpynump, &screenp, &familyp,
			&saddrlenp, saddrp);
#ifdef DEBUG
  printf("After _XConnectDisplay. fd is %d, full name = %s, dpy-num = %d\n",
	 fd, fullnamep, dpynump);
  printf("screenp = %d, familyp = %d, saddrlenp = %d, saddrp = %s",
	 screenp, familyp, saddrlenp, saddrp);
  fflush(stdout);
#endif
  return fd;
  }

int scix_closedisplay(descriptor)
int descriptor;
  {
  (void) close(descriptor);
  }

static char buf[16388];	/* Server messages larger than this are rare */

int writesock(sock, msg, nbytes)
int sock;
char *msg;
  {
  int result, i;
  struct sockaddr_un name;

  name.sun_family = AF_UNIX;
  if ((result = write(sock, msg, nbytes)) < 0)
    perror("writesock");
#ifdef DEBUG
  printf("\nwritesock: wrote %d bytes.\n", result);
/*  for (i = 0; i < nbytes; i++)
    printf(" byte %d = %d.", i, (int)msg[i]); */
  fflush(stdout);
#endif
  return result;
  }

char* readsock(sock)
int sock;
  {
  int result;

  bzero(buf, 16388);
  result = read(sock, &buf[4], 16384);
  *(int *)buf = result;
#ifdef DEBUG
  if (result > 0)
    {
    printf("\nreadsock: read %d bytes with data.\n", result);
    fflush(stdout);
    }
#endif
  return buf;
  }

char* getmoredata(sock, curpos, nbytesleft)
int sock, curpos, nbytesleft;
  {
  int result;

  bcopy(&buf[curpos], &buf[4], nbytesleft);
/*  for (i = 0; i < nbytesleft; i++)
    *buf[4+i] = *buf[curpos+i]; */
  if ((result = read(sock, &buf[4+nbytesleft], 16384 - nbytesleft)) > 0)
    *(int *)buf = result + nbytesleft;    /* Only update if anything read. */
#ifdef DEBUG
  if (result > 0)
    {
    printf("getmoredata: read %d bytes with data.\n", result);
    fflush(stdout);
    }
#endif
  return buf;
  }

/*
 * Xselect -- interfaces to select.
 */
int Xselect(nfds, fd_mask)
int nfds, fd_mask;
  {
  return select(nfds, &fd_mask, 0, &fd_mask, 0);
  }

/*
 * XblockingIO -- Sets up fd for blocking IO.
 */
int XblockingIO(fd)
int fd;
  {
  return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~FNDELAY);
  }

/*
 * XnonblockingIO -- Sets up fd for non-blocking IO.
 */
int XnonblockingIO(fd)
int fd;
  {
  return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | FNDELAY);
  }
