home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $VER: netinput.c 1.3 (22 Jul 1995)
- **
- ** AMIGA netinput client code
- **
- ** (C (14 Jul 1995) Copyright 1995 Marius Gröger
- ** All Rights Reserved
- **
- ** $HISTORY:
- **
- ** 22 Jul 1995 : 001.003 : QUIET option
- ** 14 Jul 1995 : 001.002 : some code cleanup
- ** 06 Mar 1995 : 001.001 : version id added
- ** 05 Mar 1995 : 001.000 : created
- */
-
- #define DEBUG 0
-
- /*F*/ /* includes */
- #include <NETINCLUDE:sys/types.h>
- #include <NETINCLUDE:sys/stat.h>
- #include <NETINCLUDE:stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <string.h>
- #include <clib/netlib_protos.h>
- #include <netdb.h>
-
- #include <clib/dos_protos.h>
- #include <pragmas/dos_pragmas.h>
-
- #include <clib/exec_protos.h>
- #include <pragmas/exec_sysbase_pragmas.h>
-
- #include <exec/memory.h>
- #include <exec/io.h>
- #include <exec/interrupts.h>
-
- #include <devices/input.h>
- #include <devices/inputevent.h>
-
- #include "netinput.h"
- #include "unixsem.h"
- #include "compiler.h"
- #include "debug.h"
-
- /*E*/
- /*F*/ /* global data */
- extern struct Library *SocketBase, *DOSBase;
-
- #define TEMPLATE "HOST/A,IMM=IGNOREMOUSEMOVES/K/N,QUIET/S"
- enum { ARG_HOST, ARG_IMM, ARG_QUIET, ARG_COUNT };
-
- #define MAX_IMM 900000
- #define MIN_IMM 0
- #define DEF_IMM 0
-
- /*
- ** we maintain an InputEvent-FIFO of FIFO_COUNT elements
- ** this value MUST be power of 2!
- */
- #define FIFO_COUNT 64
-
- typedef struct GlobalData
- {
- struct Library *gd_SysBase,
- *gd_UtilityBase,
- *gd_DOSBase;
- struct MsgPort *gd_IPort;
- struct IOStdReq *gd_IReq;
- struct Interrupt gd_InputHandler;
- UBYTE gd_ProgramName[100];
- UBYTE gd_HostName[64];
- ULONG gd_Flags;
- int gd_Socket;
- CountSemaphore gd_Full,
- gd_Empty;
- struct InputEvent gd_Event[FIFO_COUNT],
- gd_Intermediate;
- UWORD gd_Write, gd_Read;
- struct Task *gd_We;
- LONG gd_IgnoreMouseMoves;
- int gd_Quiet : 1;
- } *GD;
-
- #define FOGF_HANDLER_INSTALLED (1<<0)
-
- #ifdef __SASC
- /*
- ** redirect all shared library bases to our device base.
- */
- # define SysBase gd->gd_SysBase
- # define DOSBase gd->gd_DOSBase
- # define UtilityBase gd->gd_UtilityBase
- /*
- ** This macro declares a local variable which temporary gets
- ** SysBase directly from AbsExecBase.
- */
- # define LOCALSYSBASE struct { void *gd_SysBase; } *gd = (void*)0x4
- #else
- # error Please define library bases for your compiler
- #endif
-
-
- /*E*/
-
- /*F*/ /* revision */
- #define VERSION 37
- #define REVISION 1
- #define DATE "22.07.95"
- #define VERS "netinputd 37.1"
- #define VSTRING "netinputd 37.1 (22.07.95)"
- #define VERSTAG "\0$VER: netinputd 37.1 (22.07.95)"
- const STATIC UBYTE version[]=VERSTAG;
- /*E*/
-
- /*F*/ /* private symbols */
- static int init_client(char *hostname, char *servername, char *protocolname, char *yourname);
- static BOOL parseargs(GD gd);
- static VOID freeall(GD gd);
- static BOOL openall(GD gd);
- static GD creategd(VOID);
- static BOOL request(GD gd, ULONG type, ULONG flags);
- static ASM SAVEDS struct InputEvent *inputhandler(REG(a0) struct InputEvent *event, REG(a1) GD gd);
- static VOID removehandler(GD gd);
- static BOOL installhandler(GD gd);
- /*E*/
- /*F*/ /* exported symbols */
- extern VOID main(VOID);
- /*E*/
-
- /*F*/ static int init_client(char *hostname, char *servername, char *protocolname, char *yourname)
- {
- int sock = -1;
- struct servent *sp;
- struct hostent *hp;
- struct sockaddr_in server;
-
- sp = getservbyname(servername, protocolname);
- if (sp != NULL)
- {
- hp = gethostbyname(hostname);
- if (hp != NULL)
- {
- bzero((char *)&server, sizeof(server));
- server.sin_port = sp->s_port;
- bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
- server.sin_family = hp->h_addrtype;
-
- sock = socket(AF_INET, (LONG)(strcmp(protocolname,"tcp") ? SOCK_DGRAM : SOCK_STREAM), 0);
- if (sock >= 0)
- {
- if (connect((LONG)sock, (struct sockaddr *)&server, sizeof (server)) < 0)
- {
- close(sock);
- sock = -1;
- }
- }
- }
- }
-
- return sock;
- }
- /*E*/
-
- /*F*/ static BOOL parseargs(GD gd)
- {
- struct RDArgs *rda;
- BOOL rc = FALSE;
- LONG param[ARG_COUNT];
-
- memset(param, 0, sizeof(param));
-
- if (rda = ReadArgs(TEMPLATE, param, NULL))
- {
- strncpy(gd->gd_HostName, (char*)param[ARG_HOST], sizeof(gd->gd_HostName)-1);
-
- gd->gd_IgnoreMouseMoves = DEF_IMM;
- if (param[ARG_IMM])
- {
- gd->gd_IgnoreMouseMoves = *((LONG*)param[ARG_IMM]);
- if (gd->gd_IgnoreMouseMoves > MAX_IMM) gd->gd_IgnoreMouseMoves = MAX_IMM;
- else if (gd->gd_IgnoreMouseMoves < MIN_IMM) gd->gd_IgnoreMouseMoves = MIN_IMM;
- }
-
- d(("hostname %s, imm %ld\n",gd->gd_HostName, gd->gd_IgnoreMouseMoves));
-
- gd->gd_Quiet = (param[ARG_QUIET] != 0);
-
- rc = TRUE;
-
- FreeArgs(rda);
- }
- else PrintFault(IoErr(), gd->gd_ProgramName);
-
- return(rc);
- }
- /*E*/
-
- /*F*/ static VOID removehandler(GD gd)
- {
- if (gd->gd_Flags & FOGF_HANDLER_INSTALLED)
- {
- gd->gd_IReq->io_Command = IND_REMHANDLER;
- gd->gd_IReq->io_Data = (APTR)&gd->gd_InputHandler;
- gd->gd_IReq->io_Length = sizeof(struct Interrupt);
- if (!DoIO((struct IORequest*)gd->gd_IReq))
- gd->gd_Flags &= ~FOGF_HANDLER_INSTALLED;
- }
- }
- /*E*/
- /*F*/ static BOOL installhandler(GD gd)
- {
- BOOL rv = FALSE;
-
- gd->gd_InputHandler.is_Code = (void (*)())&inputhandler;
- gd->gd_InputHandler.is_Data = (APTR)gd;
- gd->gd_InputHandler.is_Node.ln_Pri = 127;
- gd->gd_InputHandler.is_Node.ln_Type = NT_UNKNOWN;
- gd->gd_InputHandler.is_Node.ln_Name = "« netinput »";
- gd->gd_IReq->io_Command = IND_ADDHANDLER;
- gd->gd_IReq->io_Data = (APTR)&gd->gd_InputHandler;
- gd->gd_IReq->io_Length = sizeof(struct Interrupt);
- if (!DoIO((struct IORequest*)gd->gd_IReq))
- {
- gd->gd_Flags |= FOGF_HANDLER_INSTALLED;
- rv = TRUE;
- }
-
- return rv;
- }
- /*E*/
-
- /*F*/ static VOID freeall(GD gd)
- {
- if (gd->gd_IReq)
- {
- if (gd->gd_IReq->io_Device) CloseDevice((struct IORequest*)gd->gd_IReq);
- DeleteIORequest(gd->gd_IReq);
- }
- if (gd->gd_IPort) DeleteMsgPort(gd->gd_IPort);
- if (DOSBase) CloseLibrary(DOSBase);
- if (UtilityBase) CloseLibrary(UtilityBase);
- FreeVec(gd);
- }
- /*E*/
- /*F*/ static BOOL openall(GD gd)
- {
- BOOL rv = FALSE;
-
- sinit(&gd->gd_Full,-1);
- sinit(&gd->gd_Empty,-1);
-
- sset(&gd->gd_Full, 0);
- sset(&gd->gd_Empty, FIFO_COUNT);
-
- gd->gd_Read = 0;
- gd->gd_Write = 0;
-
- gd->gd_We = FindTask(NULL);
-
- d(("opening dos.library\n"))
- if (DOSBase = OpenLibrary("dos.library", 37))
- {
- d(("opening utility.library\n"))
- if (UtilityBase = OpenLibrary("utility.library", 37))
- {
- d(("creating msg port\n"))
- if (gd->gd_IPort = CreateMsgPort())
- {
- d(("creating io request\n"))
- if (gd->gd_IReq = CreateIORequest(gd->gd_IPort, sizeof(struct IOStdReq)))
- {
- d(("opening input.device\n"))
- if (!OpenDevice("input.device",0,(struct IORequest*)gd->gd_IReq, 0))
- {
- rv = TRUE;
- }
- }
- }
- }
- }
-
- return rv;
- }
- /*E*/
- /*F*/ static GD creategd(VOID)
- {
- GD new;
- LOCALSYSBASE;
-
- new = AllocVec(sizeof(struct GlobalData), MEMF_ANY | MEMF_CLEAR);
- new->gd_SysBase = SysBase;
-
- return new;
- }
- /*E*/
-
- /*F*/ static VOID INLINE forwardevent(GD gd, struct InputEvent *event)
- {
- swait(&gd->gd_Empty);
- gd->gd_Event[gd->gd_Write] = *event;
- ssignal(&gd->gd_Full);
-
- gd->gd_Write = (gd->gd_Write+1) & (FIFO_COUNT-1);
- }
- /*E*/
- /*F*/ static ASM SAVEDS struct InputEvent *inputhandler(REG(a0) struct InputEvent *event, REG(a1) GD gd)
- {
- switch(event->ie_Class)
- {
- case IECLASS_RAWMOUSE:
- if ((event->ie_Code & 0xFF) != IECODE_NOBUTTON)
- {
- if (gd->gd_Intermediate.ie_Class != IECLASS_NULL)
- {
- d(("writing event 3\n"));
- forwardevent(gd, &gd->gd_Intermediate);
- gd->gd_Intermediate.ie_Class = IECLASS_NULL;
- }
- forwardevent(gd, event);
- }
- else if (gd->gd_IgnoreMouseMoves)
- {
- if (gd->gd_Intermediate.ie_Class != IECLASS_NULL)
- {
- d (("%ld/%ld - %ld/%ld\n",event->ie_TimeStamp.tv_secs,
- event->ie_TimeStamp.tv_micro,
- gd->gd_Intermediate.ie_TimeStamp.tv_secs,
- gd->gd_Intermediate.ie_TimeStamp.tv_micro));
-
- if ((event->ie_TimeStamp.tv_secs == gd->gd_Intermediate.ie_TimeStamp.tv_secs) &&
- ((event->ie_TimeStamp.tv_micro - gd->gd_Intermediate.ie_TimeStamp.tv_micro) <= gd->gd_IgnoreMouseMoves))
- {
- d(("storing event 1\n"));
- gd->gd_Intermediate = *event;
- }
- else
- {
- d(("writing event 1\n"));
- gd->gd_Intermediate.ie_Class = IECLASS_NULL;
- forwardevent(gd, event);
- }
- }
- else
- {
- d(("storing event 2\n"));
- gd->gd_Intermediate = *event;
- }
- }
- else
- {
- d(("writing event 2\n"));
- forwardevent(gd, event);
- }
- event = NULL;
- break;
-
- case IECLASS_RAWKEY:
- if (gd->gd_Intermediate.ie_Class != IECLASS_NULL)
- {
- forwardevent(gd, &gd->gd_Intermediate);
- gd->gd_Intermediate.ie_Class = IECLASS_NULL;
- }
- if (((event->ie_Code & ~IECODE_UP_PREFIX) == 0x45) && (event->ie_Qualifier & IEQUALIFIER_CONTROL))
- {
- if (event->ie_Code & IECODE_UP_PREFIX)
- Signal(gd->gd_We, SIGBREAKF_CTRL_C);
-
- event = NULL;
- break;
- }
- forwardevent(gd,event);
- event = NULL;
- break;
-
- default:
- if (gd->gd_Intermediate.ie_Class != IECLASS_NULL)
- {
- forwardevent(gd, &gd->gd_Intermediate);
- gd->gd_Intermediate.ie_Class = IECLASS_NULL;
- }
- break;
- }
- return event;
- }
- /*E*/
-
- /*F*/ static BOOL request(GD gd, ULONG type, ULONG flags)
- {
- int l;
- struct foPacket foc;
-
- foc.Type = type;
- foc.Flags = flags;
-
- l = send((LONG)gd->gd_Socket, (UBYTE*)&foc, sizeof(foc), 0);
-
- return (BOOL)(l == sizeof(foc));
- }
- /*E*/
-
- /*F*/ extern VOID main(VOID)
- {
- int rc = RETURN_FAIL;
- GD gd;
-
- if (gd = creategd())
- {
- d(("gd at %lx\n",gd))
-
- if (openall(gd))
- {
- GetProgramName(gd->gd_ProgramName, sizeof(gd->gd_ProgramName));
-
- if (parseargs(gd))
- {
- gd->gd_Socket = init_client(gd->gd_HostName, FO_SERVERNAME, FO_PROTOCOL, gd->gd_ProgramName);
- if (gd->gd_Socket >= 0)
- {
- if (installhandler(gd))
- {
- if (!gd->gd_Quiet)
- Printf( "Transparent mode on.\nEscape key is <Ctrl-Escape>.\n");
-
- while(!(SetSignal(0,0) & SIGBREAKF_CTRL_C))
- {
- swait(&gd->gd_Full);
- if (request(gd, FOPT_Event, 0))
- {
- send((LONG)gd->gd_Socket, (UBYTE*)&gd->gd_Event[gd->gd_Read], sizeof(struct InputEvent), 0);
- }
- ssignal(&gd->gd_Empty);
-
- gd->gd_Read = (gd->gd_Read+1) & (FIFO_COUNT-1);
-
- }
- if (!gd->gd_Quiet)
- Printf( "Transparent mode left.\n");
-
- removehandler(gd);
- rc = TRUE;
- }
-
- if (!request(gd, FOPT_Finish, 0))
- Printf( "%s: could not finish connection\n", gd->gd_ProgramName);
- else
- rc = RETURN_OK;
- }
- shutdown(gd->gd_Socket,2);
- close(gd->gd_Socket);
- }
- }
-
- freeall(gd);
- }
-
- exit(rc);
- }
- /*E*/
-
-