Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (07/07/90)
Submitted-by: sas.UUCP!walker%sas@rti.rti.org (Doug Walker) Posting-number: Volume 90, Issue 199 Archive-name: comm/dnet/netkeys-2.0/part01 [ uuencoded executables enclosed ...tad ] NETKEYS 2.0 is a DNET server that will let you use one mouse and keyboard to control two Amigas connected via a null modem. Version 2.0 features the ability to simply move the mouse off one edge of the screen and onto the other Amiga's screen. A Software Distillery project by Doug Walker. #!/bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 2)." # Contents: channel.h dnet.h dnetlib.c makefile mshow.c netkeys.doc # netkeys.h nkutil.c snetkeys.c snetkeys.uu # Wrapped by tadguy@xanth on Sat Jul 7 11:13:10 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'channel.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'channel.h'\" else echo shar: Extracting \"'channel.h'\" \(1724 characters\) sed "s/^X//" >'channel.h' <<'END_OF_FILE' X X/* X * CHANNEL.H X * X * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved. X * X * Channel structures for SCMD_* channel commands. X */ X X#ifndef DNET_H Xtypedef unsigned char ubyte; Xtypedef unsigned short uword; Xtypedef unsigned long ulong; Xtypedef struct MsgPort PORT; Xtypedef struct IOStdReq IOR; X#endif X X#define CSWITCH struct _CSWITCH X#define COPEN struct _COPEN X#define CCLOSE struct _CCLOSE X#define CACKCMD struct _CACKCMD X#define CEOFCMD struct _CEOFCMD X#define CIOCTL struct _CIOCTL X XCSWITCH { /* SWITCH current data channel */ X ubyte chanh; X ubyte chanl; X}; X XCOPEN { /* OPEN port on channel */ X ubyte chanh; X ubyte chanl; X ubyte porth; X ubyte portl; X ubyte error; /* error return 0=ok */ X ubyte pri; X}; X XCCLOSE { /* CLOSE a channel */ X ubyte chanh; X ubyte chanl; X}; X XCACKCMD { /* Acknowledge an open/close */ X ubyte chanh; X ubyte chanl; X ubyte error; /* ERETRY ENOPORT ECLOSE1 ECLOSE2 */ X ubyte filler; X}; X XCEOFCMD { /* Send [R/W] EOF */ X ubyte chanh; X ubyte chanl; X ubyte flags; X ubyte filler; X}; X XCIOCTL { X ubyte chanh; /* channel */ X ubyte chanl; X ubyte cmd; /* ioctl command */ X ubyte valh; /* ioctl value */ X ubyte vall; X ubyte valaux; /* auxillary field */ X}; X X#define CIO_SETROWS 1 /* PTY's only */ X#define CIO_SETCOLS 2 /* PTY's only */ X#define CIO_STOP 3 /* any channel, flow control */ X#define CIO_START 4 /* any channel, flow control */ X#define CIO_FLUSH 5 X X#define CHAN struct _CHAN X XCHAN { X PORT *port; X IOR *ior; X ubyte state; X ubyte flags; X char pri; /* transmit priority */ X}; X END_OF_FILE if test 1724 -ne `wc -c <'channel.h'`; then echo shar: \"'channel.h'\" unpacked with wrong size! fi # end of 'channel.h' fi if test -f 'dnet.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dnet.h'\" else echo shar: Extracting \"'dnet.h'\" \(6639 characters\) sed "s/^X//" >'dnet.h' <<'END_OF_FILE' X X/* X * DNET.H X * X * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved. X * X */ X X#define DNET_H X X#ifdef LATTICE X#include <exec/types.h> X#include <exec/nodes.h> X#include <exec/lists.h> X#include <exec/ports.h> X#include <exec/libraries.h> X#include <exec/devices.h> X#include <exec/io.h> X#include <exec/memory.h> X#include <exec/interrupts.h> X#include <intuition/intuition.h> X#include <devices/console.h> X#include <devices/timer.h> X#include <libraries/dos.h> X#include <libraries/dosextens.h> X#include <libraries/filehandler.h> X#include <string.h> X#include <stdlib.h> X#include <proto/exec.h> X#include <proto/dos.h> X X#define U_ARGS(a) a X X#else X X#define U_ARGS(a) () /* No support for prototypes - oh well */ X X#endif X X Xtypedef unsigned char ubyte; Xtypedef unsigned short uword; Xtypedef unsigned long ulong; X Xtypedef struct MsgPort PORT; Xtypedef struct timerequest IOT; Xtypedef struct IOStdReq IOR; Xtypedef struct List LIST; Xtypedef struct Node NODE; Xtypedef struct Process PROC; Xtypedef struct Message MSG; X X#include "channel.h" X X#ifndef MAX(a,b) X#define MAX(a,b) (((a)>(b))?(a):(b)) X#endif X X#define PKT struct _PKT X#define PNODE struct _PNODE X X#define BTOC(yow) ((ubyte *)((long)(yow) << 2)) X#define DNETPORTNAME "DNET.UNIT." X#define OFFSET(ptr,elem) ((long)((char *)&(ptr)->elem - (char *)(ptr))) X X#define EMPTY 0 /* empty (sent) */ X#define READY 1 /* data ready (not sent yet) */ X X#define MAXCHAN 128 /* Max # of channels supported */ X#define SYNC 0xFF /* SYNC character */ X#define MAXPKT 200 /* maximum packet size */ X#define MINPKT 32 /* minimum maximum packet size X (for priority scheme) */ X X#define OVERHEAD 7 /* for packets with data */ X XPNODE { X NODE node; X char name[32]; X ulong seg; X}; X XPKT { X uword iolength; /* send: length of packet, recv: length of data */ X ubyte state; /* EMPTY, READY */ X X ubyte sync; /* THE PACKET */ X ubyte ctl; X ubyte cchk; X ubyte lenh; X ubyte lenl; X ubyte data[MAXPKT+2]; X}; X X/* RECEIVER STATES */ X#define RS_SYNC 0 /* Waiting for sync */ X#define RS_CTL 1 /* Waiting for command */ X#define RS_CCHK 2 /* Waiting for check byte */ X#define RS_LEN1 3 /* Waiting for MSB length byte */ X#define RS_LEN2 4 /* Waiting for LSB length byte */ X#define RS_DATA 5 /* Waiting for data & checksum */ X X#define DNCMD_OPEN 32 /* Application open */ X#define DNCMD_SOPEN 33 /* Server open */ X#define DNCMD_CLOSE 34 /* Close a channel */ X#define DNCMD_EOF 35 /* Will no longer write to channel */ X X#define DNCMD_WRITE 36 /* Write data to a channel */ X#define DNCMD_QUIT 37 /* Kill the DNET server */ X#define DNCMD_IOCTL 38 X X/* REQUEST TYPES */ X#define RTO_REQ 1 /* Network read timeout */ X#define WTO_REQ 2 /* Network write-ack timeout */ X#define RNET_REQ 3 /* Network read data */ X#define WNET_REQ 4 /* Network write data sent */ X#define PKT_REQ 5 /* Returned packets from servers */ X#define OPEN_REQ 6 X#define IGWNET_REQ 7 X X/* PACKET CONTROL BYTE */ X#define PKF_SEQUENCE 0xE0 /* Sequence # */ X#define PKF_DATA 0x10 /* 1-65535 bytes */ X#define PKF_RESERVED 0x08 /* reserved bit */ X#define PKF_MASK 0x07 /* command mask */ X X#define PKCMD_WRITE 1 /* A DATA packet */ X#define PKCMD_CHECK 2 /* Request ACK or NAK for win */ X#define PKCMD_ACK 3 /* ACK a window */ X#define PKCMD_NAK 4 /* NAK a window */ X#define PKCMD_RESTART 5 /* Restart */ X#define PKCMD_ACKRSTART 6 /* Restart Acknowledge */ X#define PKCMD_RESERVE3 7 X/* CHANNEL COMMANDS */ X#define SCMD_SWITCH 0x00 /* switch active channel # */ X#define SCMD_OPEN 0x01 /* open a channel */ X#define SCMD_CLOSE 0x02 /* close a channel */ X#define SCMD_ACKCMD 0x03 /* ack an open/close request */ X#define SCMD_EOFCMD 0x04 /* Reof or Weof */ X#define SCMD_QUIT 0x05 /* crash dnet */ X#define SCMD_IOCTL 0x06 /* ioctl */ X X#define SCMD_DATA 0x08 /* stream command, DATA */ X X#define CHAN_FREE 0x01 /* free channel */ X#define CHAN_ROPEN 0x02 /* remote open, wait port msg */ X#define CHAN_LOPEN 0x03 /* local open, wait reply */ X#define CHAN_OPEN 0x04 X#define CHAN_CLOSE 0x05 /* see flags */ X#define CHANF_ROK 0x01 /* NOT read eof */ X#define CHANF_WOK 0x02 /* remote will accept data */ X#define CHANF_LCLOSE 0x04 X#define CHANF_RCLOSE 0x08 X Xstruct DChannel { X PORT port; /* receive data, replies */ X PORT *dnetport; /* dnet's master port */ X LIST rdylist; /* ready to be read */ X uword chan; /* channel # for open channels */ X ubyte eof; /* channel remotely closed/eof */ X ubyte filler; X int qlen; /* allowed write queue size */ X int queued; /* current # packets queued */ X}; X Xextern void *ArbitrateNext(); X X#ifndef NOEXT Xextern IOT Rto; /* Read-Timeout/reset */ Xextern IOT Wto; /* Write-Timeout/retry */ Xextern IOR *RNet; /* read-request */ Xextern IOR *WNet; /* write-request */ Xextern PKT Pkts[9]; Xextern PKT *Raux; /* next packet in */ Xextern PKT *RPak[4]; Xextern PKT *WPak[4]; Xextern PORT *DNetPort; /* Remote Command/Control in */ Xextern PORT *IOSink; /* Return port for ALL IO */ Xextern CHAN Chan[MAXCHAN]; Xextern LIST TxList; /* For pending DNCMD_WRITE reqs. */ Xextern LIST SvList; Xextern ubyte Rto_act; Xextern ubyte Wto_act; Xextern uword RChan; Xextern uword WChan; Xextern uword RPStart; Xextern uword WPStart; Xextern uword WPUsed; Xextern uword RState; Xextern ubyte DDebug; Xextern ubyte Restart; Xextern ubyte DeldQuit; Xextern ubyte AutoHangup; Xextern ulong NumCon; Xextern ulong WTimeoutVal; Xextern ulong RTimeoutVal; Xextern long Baud; Xextern char *HostName; /* The Amiga's HostName */ X Xextern ubyte RestartPkt[3]; Xextern ubyte AckPkt[8][3]; Xextern ubyte NakPkt[8][3]; Xextern ubyte CheckPkt[8][3]; X#endif X X#ifdef LATTICE X/* One #ifdef LATTICE is worth 1000 U_ARGS macros! */ XPORT *DListen(uword); Xvoid DUnListen(PORT *); XPORT *DAccept(PORT *); XDNAAccept(PORT *); Xvoid DPri(struct DChannel *, int); XPORT *DOpen(char * /*host*/, uword /*portnum*/, X char /*txpri*/, char /*rxpri*/); Xint DNRead(struct DChannel *, char *, int); Xint DRead(struct DChannel *, char *, int); Xvoid DQueue(struct DChannel *, int); XDWrite(struct DChannel *, char *, int); Xvoid DEof(struct DChannel *); Xvoid DIoctl(struct DChannel *, ubyte, uword, ubyte); Xint DQuit(char *); Xvoid DClose(struct DChannel *); Xvoid WaitMsg(IOR *); Xint WaitQueue(struct DChannel *, IOR *); X X#endif X END_OF_FILE if test 6639 -ne `wc -c <'dnet.h'`; then echo shar: \"'dnet.h'\" unpacked with wrong size! fi # end of 'dnet.h' fi if test -f 'dnetlib.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dnetlib.c'\" else echo shar: Extracting \"'dnetlib.c'\" \(10399 characters\) sed "s/^X//" >'dnetlib.c' <<'END_OF_FILE' X/* X * DNETLIB.C X * X * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved. X * X * Library Interface for DNET. X */ X X#include "dnet.h" X X#include <stdio.h> X X#ifndef BUG X#define BUG(a) X#define BUGGETC X#endif X Xstatic struct DChannel *MakeChannel U_ARGS((IOR *, char *)); Xstatic void DeleteChannel U_ARGS((struct DChannel *)); Xstatic void FixSignal U_ARGS((struct DChannel *)); X X#define NAMELEN sizeof("DNET.PORT.XXXXX") X#define NAMEPAT "DNET.PORT.%ld" X XPORT *DListen(portnum) Xuword portnum; X{ X PORT *port; X char *ptr; X X port = NULL; X ptr = AllocMem(NAMELEN, MEMF_PUBLIC); /* memory the the name */ X sprintf(ptr, NAMEPAT, portnum); X Forbid(); /* task-atomic operation */ X if (FindPort(ptr) || !(port = CreatePort(ptr,0))) X FreeMem(ptr, NAMELEN); X Permit(); X return(port); X} X Xvoid XDUnListen(lisport) XPORT *lisport; X{ X register char *ptr; X ptr = lisport->mp_Node.ln_Name; X X if (lisport) X { X Forbid(); /* task-atomic operation */ X while (DNAAccept(lisport)); /* remove all pending requests */ X DeletePort(lisport); /* gone! */ X Permit(); X FreeMem(ptr, NAMELEN); X } X} X X/* X * DAccept() X * X * Note: This call will work even if called by a task which does not X * own the listen port. X */ X XPORT * XDAccept(lisport) XPORT *lisport; X{ X register IOR *ior; X register struct DChannel * chan; X XBUG(("DAccept: Entry, port %lx\n", lisport)) X X chan = NULL; X while (!chan && (ior = (IOR *)GetMsg(lisport))) { X switch(ior->io_Command) { X case DNCMD_SOPEN: X BUG(("DAccept: SOPEN command\n")) X chan = MakeChannel(ior, NULL); X break; X default: X BUG(("DAccept: Unrecognized command '%d'\n", ior->io_Command)) X ior->io_Error = 1; X break; X } X BUG(("DAccept: Replying\n")) X ReplyMsg(&ior->io_Message); X } X BUG(("DAccept: After while loop\n")) X if (lisport->mp_MsgList.lh_Head != (NODE *)&lisport->mp_MsgList.lh_Tail) X SetSignal(1 << lisport->mp_SigBit, 1 << lisport->mp_SigBit); X X return(chan ? &chan->port : NULL); X} X X/* X * Refuse a connection X */ X XDNAAccept(lisport) XPORT *lisport; X{ X IOR *ior; X X if (ior = (IOR *)GetMsg(lisport)) { X ior->io_Error = 1; X ReplyMsg(&ior->io_Message); X } X if (lisport->mp_MsgList.lh_Head != (NODE *)&lisport->mp_MsgList.lh_Tail) X SetSignal(1 << lisport->mp_SigBit, 1 << lisport->mp_SigBit); X return(ior != NULL); X} X Xvoid DPri(chan, pri) Xstruct DChannel * chan; Xint pri; X{ X} X X XPORT * XDOpen(host, portnum, txpri, rxpri) Xchar *host; Xchar txpri, rxpri; Xuword portnum; X{ X IOR ior; X struct DChannel *chan; X X if (!host) X host = "0"; X chan = MakeChannel(&ior, host); X if (rxpri > 126) X rxpri = 126; X if (rxpri < -127) X rxpri = -127; X if (txpri > 126) X txpri = 126; X if (txpri < -127) X txpri = -127; X if (chan->dnetport) { X ior.io_Command = DNCMD_OPEN; X ior.io_Unit = (void *)portnum; X ior.io_Offset = (long)chan; X ior.io_Message.mn_ReplyPort = &chan->port; X ior.io_Message.mn_Node.ln_Pri = txpri; X ior.io_Message.mn_Node.ln_Name= (char *)rxpri; X X PutMsg(chan->dnetport, &ior.io_Message); X WaitMsg(&ior); X if (ior.io_Error == 0) { X chan->chan = (long)ior.io_Unit; X FixSignal(chan); X return(&chan->port); X } X } X DeleteChannel(chan); X return(NULL); X} X X XDNRead(chan, buf, bytes) Xstruct DChannel * chan; Xchar *buf; Xint bytes; X{ X register IOR *ior; X int len; X long n; X X len = 0; X if (chan->eof) X return(-1); X while (bytes && ((ior = (IOR *) X RemHead((struct List *)&chan->rdylist)) || X (ior = (IOR *)GetMsg(&chan->port)))) { X if (ior->io_Message.mn_Node.ln_Type == NT_REPLYMSG) X { X if (!chan->queued) X { X BUG(("DNRead: Software Error")); X } X else X --chan->queued; X if (ior->io_Length) X FreeMem((char *)ior->io_Data, (long)ior->io_Length); X FreeMem((char *)ior, (long)sizeof(IOR)); X continue; X } X switch(ior->io_Command) X { X case DNCMD_CLOSE: X case DNCMD_EOF: X chan->eof = 1; X ReplyMsg(&ior->io_Message); X break; X X case DNCMD_WRITE: X n = ior->io_Length - ior->io_Actual; X if (n <= bytes) X { X memcpy(buf, ((char *)ior->io_Data) + ior->io_Actual, n); X bytes -= n; X len += n; X buf += n; X ReplyMsg(&ior->io_Message); X } X else X { X memcpy(buf, (char *)ior->io_Data + ior->io_Actual, bytes); X len += bytes; X ior->io_Actual += bytes; X bytes = 0; X Forbid(); /* DNET device is a task, no need to Disable() */ X ior->io_Message.mn_Node.ln_Type = NT_MESSAGE; X AddHead(&chan->port.mp_MsgList, (struct Node *)ior); X Permit(); X } X break; X default: X ior->io_Error = 1; X ReplyMsg(&ior->io_Message); X } X } X FixSignal(chan); X if (chan->eof) X SetSignal(1 << chan->port.mp_SigBit, 1 << chan->port.mp_SigBit); X return(len); X} X Xint DRead(chan, buf, bytes) Xchar *buf; Xstruct DChannel * chan; Xint bytes; X{ X long len; X long n; X X len = 0; X if (chan->eof) X { X BUG(("****DNET EOF!!!\n")); X return(-1); X } X X while (bytes) X { X WaitPort(&chan->port); X n = DNRead(chan, buf, bytes); X len += n; X if (n < 0) break; X buf += n; X bytes -= n; X if (chan->eof) break; X } X return(len); X} X Xvoid DQueue(chan, n) Xstruct DChannel * chan; Xint n; X{ X chan->qlen = n; X} X XDWrite(chan, buf, bytes) Xstruct DChannel * chan; Xchar *buf; Xint bytes; X{ X IOR tmpior; X IOR *ior; X int error; X X error = bytes; X if (chan->qlen) X { X if (WaitQueue(chan, NULL) >= 0) X { X ior = (IOR *)AllocMem(sizeof(IOR), MEMF_CLEAR|MEMF_PUBLIC); X ior->io_Command = DNCMD_WRITE; X ior->io_Unit = (void *)chan->chan; X ior->io_Offset = (long)chan; X ior->io_Message.mn_ReplyPort = &chan->port; X ior->io_Data = (APTR)AllocMem(bytes, MEMF_PUBLIC); X ior->io_Length = bytes; X memcpy((char *)ior->io_Data, buf, (int)bytes); X PutMsg(chan->dnetport, &ior->io_Message); X ++chan->queued; X } X else X { X error = -1; X } X } X else X { X tmpior.io_Command = DNCMD_WRITE; X tmpior.io_Unit = (void *)chan->chan; X tmpior.io_Offset = (long)chan; X tmpior.io_Message.mn_ReplyPort = &chan->port; X tmpior.io_Data = (APTR)buf; X tmpior.io_Length = bytes; X PutMsg(chan->dnetport, &tmpior.io_Message); X WaitMsg(&tmpior); X if (tmpior.io_Error) X { X error = -1; X BUG(("*****DWrite: io_Error %d\n", tmpior.io_Error)); X BUGGETC X } X } X FixSignal(chan); X return(error); X} X Xvoid DEof(chan) Xstruct DChannel * chan; X{ X IOR ior; X X ior.io_Command = DNCMD_EOF; X ior.io_Unit = (void *)chan->chan; X ior.io_Offset = (long)chan; X ior.io_Message.mn_ReplyPort = &chan->port; X PutMsg(chan->dnetport, &ior.io_Message); X WaitMsg(&ior); X FixSignal(chan); X} X Xvoid DIoctl(chan, cmd, val, aux) Xstruct DChannel * chan; Xubyte cmd; Xuword val; Xubyte aux; X{ X IOR ior; X X ior.io_Command = DNCMD_IOCTL; X ior.io_Unit = (void *)chan->chan; X ior.io_Offset = (long)chan; X ior.io_Message.mn_ReplyPort = &chan->port; X ior.io_Data = (APTR)(long)((val<<16)|(aux<<8)|cmd); X PutMsg(chan->dnetport, &ior.io_Message); X WaitMsg(&ior); X FixSignal(chan); X} X Xint DQuit(host) Xchar *host; X{ X IOR ior; X char buf[sizeof(DNETPORTNAME)+32]; X PORT *replyport; X PORT *dnetport; X X if (!host) X host = "0"; X sprintf(buf, "%s%s", DNETPORTNAME, host); X if (dnetport = FindPort(buf)) { X replyport = CreatePort(NULL, 0); X ior.io_Command = DNCMD_QUIT; X ior.io_Unit = 0; X ior.io_Offset = 0; X ior.io_Message.mn_ReplyPort = replyport; X PutMsg(dnetport, &ior.io_Message); X WaitMsg(&ior); X DeletePort(replyport); X } X return(dnetport != NULL); X} X X Xvoid DClose(chan) Xstruct DChannel * chan; X{ X IOR ior; X IOR *io; X XBUG(("DClose: Enter\n")) X X ior.io_Command = DNCMD_CLOSE; X ior.io_Unit = (void *)chan->chan; X ior.io_Offset = (long)chan; X ior.io_Message.mn_ReplyPort = &chan->port; X PutMsg(chan->dnetport, &ior.io_Message); X ++chan->queued; X chan->qlen = 0; X WaitQueue(chan, &ior); X while ((io = (IOR *)RemHead((struct List *)&chan->rdylist)) || X (io = (IOR *)GetMsg(&chan->port))) { X io->io_Error = 1; X ReplyMsg(&io->io_Message); X } X DeleteChannel(chan); X} X Xvoid WaitMsg(ior) XIOR *ior; X{ X while (ior->io_Message.mn_Node.ln_Type != NT_REPLYMSG) X Wait(1 << ior->io_Message.mn_ReplyPort->mp_SigBit); X Forbid(); X Remove((struct Node *)ior); X Permit(); X} X Xint WaitQueue(chan, skipior) Xstruct DChannel * chan; XIOR *skipior; X{ X register IOR *io; X short error; X X error = 0; X while (chan->queued > chan->qlen) { /* until done */ X WaitPort(&chan->port); /* something */ X io = (IOR *)GetMsg(&chan->port); X if (io->io_Message.mn_Node.ln_Type == NT_REPLYMSG) { X if (error == 0) X error = io->io_Error; X if (io != skipior) { X if (io->io_Length) X FreeMem((char *)io->io_Data, io->io_Length); X FreeMem((char *)io, sizeof(IOR)); X } X --chan->queued; X } else { X AddTail(&chan->rdylist, (struct Node *)io); X } X } X return((int)error); X} X Xstatic struct DChannel *MakeChannel(ior, host) Xregister IOR *ior; Xchar *host; X{ X struct DChannel * chan; X char buf[sizeof(DNETPORTNAME)+32]; X XBUG(("MakeChannel: Entry\n")) X X chan = (struct DChannel *)AllocMem(sizeof(struct DChannel), X MEMF_PUBLIC|MEMF_CLEAR); X X /* Name, Pri */ X chan->port.mp_Node.ln_Type = NT_MSGPORT; X chan->port.mp_SigBit = AllocSignal(-1); X chan->port.mp_SigTask = FindTask(NULL); X NewList(&chan->port.mp_MsgList); X NewList(&chan->rdylist); X chan->chan = (long)ior->io_Unit; X ior->io_Offset = (long)chan; X if (host) { X sprintf(buf, "%s%s", DNETPORTNAME, host); X ior->io_Message.mn_ReplyPort = FindPort(buf); X } X chan->dnetport = ior->io_Message.mn_ReplyPort; X return(chan); X} X Xstatic void XDeleteChannel(chan) Xstruct DChannel * chan; X{ X FreeSignal(chan->port.mp_SigBit); X FreeMem((char *)chan, (long)sizeof(struct DChannel)); X} X Xstatic void XFixSignal(chan) Xregister struct DChannel * chan; X{ X if (chan->port.mp_MsgList.lh_Head != X (NODE *)&chan->port.mp_MsgList.lh_Tail || X chan->rdylist.lh_Head != (NODE *)&chan->rdylist.lh_Tail) X SetSignal(1 << chan->port.mp_SigBit, 1 << chan->port.mp_SigBit); X} X END_OF_FILE if test 10399 -ne `wc -c <'dnetlib.c'`; then echo shar: \"'dnetlib.c'\" unpacked with wrong size! fi # end of 'dnetlib.c' fi if test -f 'makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'makefile'\" else echo shar: Extracting \"'makefile'\" \(709 characters\) sed "s/^X//" >'makefile' <<'END_OF_FILE' X# X# X# For use with Lattice LMK. To compile, type 'LMK'. X# X# X XLIBS = lib:lc.lib lib:amiga.lib X XCFLAGS = -cwusf -v XLC2FLAGS = XCLIENTOBJS = netkeys.o nkutil.o dnetlib.o mshow.o XSERVEROBJS = snetkeys.o nkutil.o dnetlib.o mshow.o X Xall: netkeys snetkeys X Xnetkeys: $(CLIENTOBJS) X @echo >ram:tmp.with "from lib:cback.o $(CLIENTOBJS)" X @assign blinkwith: X blink with ram:tmp.with SC SD ND VERBOSE BATCH to $@ lib $(LIBS) X Xsnetkeys: $(SERVEROBJS) X @echo >ram:tmp.with "from $(SERVEROBJS)" X @assign blinkwith: X blink with ram:tmp.with SC SD ND VERBOSE BATCH to $@ lib $(LIBS) X Xnetkeys.o : netkeys.c netkeys.h dnet.h X lc $(CFLAGS) netkeys.c Xsnetkeys.o : snetkeys.c netkeys.h dnet.h Xnkutil.o : nkutil.c END_OF_FILE if test 709 -ne `wc -c <'makefile'`; then echo shar: \"'makefile'\" unpacked with wrong size! fi # end of 'makefile' fi if test -f 'mshow.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mshow.c'\" else echo shar: Extracting \"'mshow.c'\" \(1595 characters\) sed "s/^X//" >'mshow.c' <<'END_OF_FILE' X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ X/* |_o_o|\\ Copyright (c) 1990 The Software Distillery. All Rights Reserved.*/ X/* |. o.| || This program may not be distributed without the permission of */ X/* | . | || the authors. */ X/* | o | || */ X/* | . |// Written by Doug Walker */ X/* ====== BBS:(919)-471-6436 VOICE:(919)-467-4764 */ X/* BIX: djwalker USENET: ...!mcnc!rti!sas!walker */ X/* 405 B3 Gooseneck Dr, Cary, NC 27513, USA */ X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ X X/* This code shamelessly stolen from Matt Dillon's DMOUSE */ X X#include "netkeys.h" X Xvoid mshow(struct GfxBase *GfxBase, UWORD *NoSprData, int on) X{ X static UWORD *SprSavePtr = NULL; X struct copinit *ci = GfxBase->copinit; X X if(on) X { X if(SprSavePtr) X { X ci->sprstrtup[1] = (UWORD)(((ULONG)SprSavePtr) >> 16); X ci->sprstrtup[3] = (UWORD)(((ULONG)SprSavePtr) & 0xffff); X SprSavePtr = NULL; X } X } X else if(ci->sprstrtup[0] == 0x120 && ci->sprstrtup[2] == 0x122) X { X if(!SprSavePtr) X SprSavePtr = (UWORD *)(((ULONG)ci->sprstrtup[1] << 16) | X (ULONG)ci->sprstrtup[3]); X ci->sprstrtup[1] = (UWORD)(((ULONG)NoSprData) >> 16); X ci->sprstrtup[3] = (UWORD)(((ULONG)NoSprData) & 0xffff); X } X} END_OF_FILE if test 1595 -ne `wc -c <'mshow.c'`; then echo shar: \"'mshow.c'\" unpacked with wrong size! fi # end of 'mshow.c' fi if test -f 'netkeys.doc' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'netkeys.doc'\" else echo shar: Extracting \"'netkeys.doc'\" \(8411 characters\) sed "s/^X//" >'netkeys.doc' <<'END_OF_FILE' X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ X* |_o_o|\\ Copyright (c) 1989, 1990 The Software Distillery. * X* |. o.| || All Rights Reserved * X* | . | || Written by Doug Walker * X* | o | || The Software Distillery * X* | . |// 405 B3 Gooseneck Drive * X* ====== Cary, NC 27513 * X* BBS:(919)-382-8265 * X* * X* USENET: ...mcnc!rti!sas!walker PLINK: dwalker BIX: djwalker * X\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ X XNetKeys is Copyright (c) 1989, 1990 The Software Distillery. XPermission is granted to distribute programs and data in this distribution Xprovided the following conditions are met: X X 1. All files present in the distribution package must be redistributed X with the package, including this documentation file. If you X distribute on diskette, all files must be on a single diskette. X X 2. The distributor may charge a fee to recover distribution costs. X The fee for diskette distribution should not be more than the cost X to obtain the same diskette from Fred Fish or The Software Distillery, X whichever is greater. Current charge from The Software Distillery X is $6 per disk for US and Canadian distribution, $7 elsewhere, including X all postage and handling charges. X X 3. The distributor agrees to cease distributing the programs and data X involved if requested to do so by the author or any member of The X Software Distillery. X X------------------------------DISCLAIMER X XNeither The Software Distillery nor any of its members will be held liable for Xany damage arising from the failure of this program to perform as described, Xor any destruction of other programs or data residing on a system Xattempting to run the program. While we expect no damaging errors, the Xuser of this program uses it at his or her own risk. X X------------------------------ACKNOWLEDGEMENTS X Written in Lattice C V5.05. Thanks to Matt Dillon for DNET! X XContributions to continue development of this and other fine products for the XAmiga may be sent to the Software Distillery at the above address. X XOther Products produced by the Software Distillery are: X BLINK - the Turbo-charged Alink replacement X HACK - The Amiga port of the famous UNIX game X LARN - Another famous UNIX game X MEMWATCH - Protects your machine from random trashes X MEMLIB - A library of memory debugging routines X MAKE - A software development tool one shouldn't be without X KERMIT - The World renown file transfer protocol brought to the Amiga X ICONEXEC, SETALTERNATE, SETWINDOW - Icon manipulation tools X TSIZE - A short utility for determining directory sizes. X POPCLI - A hotkey utility and screen blanker. X PICKPACKET - A tutorial program for learning about the DOS packet interface X NET: - An Amiga-to-Amiga network file system running on either the X parallel or serial ports with no additional hardware. X FILEHANDLER- An example file system written entirely in C X X XAll of these are available on our BBS. X X-----------------------------THE GOOD STUFF X XNETKEYS solves a problem that I encountered when I bought my Amiga 2000. XNaturally, I kept my A1000 around; therefore, I became a two-Amiga Amigoid. XUnfortunately, I discovered it was a pain to switch keyboards and mice to Xget from one to the other Amiga. The solution to this is NETKEYS. NETKEYS Xinstalls itself in the input event chain (AHEAD of Intuition) and, on demand, Xintercepts all keystrokes and mouse events and ships them off to the other Xmachine. X XNETKEYS uses Matt Dillon's DNET networking package. DNET is freely redist- Xributable, available on Fred Fish #294 and on all the major nets. To use XNETKEYS effectively, you will have to have the two machines sitting next to Xeach other, so you should connect them with a simple null modem cable and use Xthe following command to start DNET on both machines: X XRUN DNET -s -X -h0 -Z0 -P0 -m0 X X(If you have the older version 1.x of DNET, just use RUN DNET -s). DNET will Xuse the baud rate you have set in preferences. If you find NETKEYS to be Xhanging up or acting strangely, try a lower baud rate; I find the fastest XI can use is 9600. After the DNET windows come up on both machines, you Xshould be able to type characters into one window and see them in the other. XSelect STARTDNET from one of the machines' menus. If the other machines' Xwindow does not disappear, use the QUITDNET command or the BREAK command to Xget the DNET window back and try it again. DNET uses the file XS:DNET.SERVERS to locate server programs; you will need to add a line like X X9494 sys:dnet/snetkeys ram: ;NETKEYS server X Xin order for DNET to find the NETKEYS server. Change the path to reflect Xthe actual path of the server, but don't modify the number 9494. X XOnce DNET has been set up properly, move to the machine whose keyboard Xyou would like to use. Type 'NETKEYS'. NetKeys detaches itself from the XCLI, so there is no need to use RUN or RUNBACK. Once NetKeys is installed, Xhitting Left-Amiga-R will toggle between the two machines. Also, moving the Xmouse cursor off the left edge of your machine will cause it to appear on Xthe right edge of the remote machine; and moving it off the right edge of Xyour screen will cause it to appear on the left edge. X XIf you would like to use a key other than Left-Amiga-R, you can pass a Xparameter of the form '0x##' where ## is the hexadecimal raw key code for the Xkey to be used. For example, NETKEYS 0x13 would use Left-Amiga-R, just like Xthe default; NETKEYS 0x14 would use Left-Amiga-T, and so forth. You can Xchange the key NetKeys uses after invoking it by reinvoking it with different Xparameters. X XIf you want to get rid of NETKEYS, just type NETKEYS QUIT. Other options are Xlisted below. X XHave fun! X X--Doug X X------------------------------SYNTAX GUIDE X XParms to NETKEYS are letters; each stands for a word. You can type the Xentire keyword if you like, but netkeys will only look at the first letter. X XNETKEYS [0xnn] [F|S] [L|R|W] [Q] X X 0xnn - Use the key with raw hexadecimal key code 0xnn as the hotkey X to swap displays. X X F|S - [F]ast (default) or [S]mooth. When the [F]ast option is X active, NETKEYS will combine multiple mouse movement events X into one in order to get faster results. When [S]mooth is X selected, it will not do this. [F]ast is the default. X X [L|R|W] - [L]eft, [R]ight or [W]rap. If [L]eft is active, the mouse X cursor will exit from the left edge of the main display and X appear on the right edge of the slave display. If [R]ight X is active, the mouse cursor will exit from the right edge of X the main display and appear on the left edge of the slave. If X [W]rap is active, both sides of the main display will cause X the cursor to appear on the slave. [W]rap is the default. X X [Q] [Q]uit. Terminates a running NETKEYS process. X XIf you enter a NETKEYS command and NETKEYS is already running, the parameters Xof the running NETKEYS command are modified. Thus, you can change from XFAST to SMOOTH on the fly by issuing X X NETKEYS FAST ; start up NETKEYS in FAST mode X NETKEYS SMOOTH ; change to SMOOTH mode X XRemember that NETKEYS only looks at the first character of your parameters. XTherefore, you have exactly the same effect as the above with X X NETKEYS FUTILE ; first character is 'F' = FAST X NETKEYS STUPID ; first character is 'S' = SMOOTH X X------------------------------DISTRIBUTION LIST X Xchannel.h 1724 Xdnet.h 6639 Xnkutil.c 2509 Xnetkeys.h 4109 Xsnetkeys.c 5856 Xnetkeys.c 15146 Xmakefile 709 Xnetkeys.doc 8409 Xsnetkeys 5840 Xnetkeys 9396 Xmshow.c 1595 Xdnetlib.c 10399 END_OF_FILE if test 8411 -ne `wc -c <'netkeys.doc'`; then echo shar: \"'netkeys.doc'\" unpacked with wrong size! fi # end of 'netkeys.doc' fi if test -f 'netkeys.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'netkeys.h'\" else echo shar: Extracting \"'netkeys.h'\" \(4109 characters\) sed "s/^X//" >'netkeys.h' <<'END_OF_FILE' X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ X/* |_o_o|\\ Copyright (c) 1990 The Software Distillery. All Rights Reserved.*/ X/* |. o.| || This program may not be distributed without the permission of */ X/* | . | || the authors. */ X/* | o | || */ X/* | . |// Written by Doug Walker */ X/* ====== BBS:(919)-471-6436 VOICE:(919)-467-4764 */ X/* BIX: djwalker USENET: ...!mcnc!rti!sas!walker */ X/* 405 B3 Gooseneck Dr, Cary, NC 27513, USA */ X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ X#include <exec/types.h> X#include <exec/nodes.h> X#include <exec/lists.h> X#include <exec/memory.h> X#include <exec/interrupts.h> X#include <exec/ports.h> X#include <exec/libraries.h> X#include <exec/io.h> X#include <exec/tasks.h> X#include <exec/execbase.h> X#include <exec/devices.h> X#include <devices/timer.h> X#include <devices/input.h> X#include <devices/inputevent.h> X#include <intuition/intuitionbase.h> X#include <libraries/dos.h> X/*#include <graphics/gfxmacros.h>*/ X#include <hardware/custom.h> X#include <hardware/dmabits.h> X#include <hardware/cia.h> X#include <resources/misc.h> X#include <proto/dos.h> X#include <proto/exec.h> X/*#include <proto/intuition.h>*/ X#include <graphics/copper.h> X#include <graphics/gfxbase.h> X#include <proto/graphics.h> X#include <string.h> X X#include "dnet.h" X X#define PORT_NETKEYS 9494 X X X X#define NKMPNAME "NetKeys 2.0" X#define BANNER "\x9B" "1m" NKMPNAME "\x9b" "0m by Doug Walker\n"\ X "Copyright \xA9 1990 The Software Distillery\n"\ X "235 Trillingham Ln, Cary NC 27513 USA\nBBS:(919)382-8265\n" X X#define INSTR "Use 'NetKeys QUIT' to remove\n"\ X "Installing, please wait...\n" X X#define DEFDOKEY 0x13 X#define MAXMSGS 100 X X#define MSG(fh,st) if(fh) Write(fh, st, strlen(st)) X X#define IESZ (sizeof(struct InputEvent)) X#define NKMSZ (sizeof(struct NETKEYMSG)) X X/* Magic class to tell other side information */ X#define IECLASS_NKCONTROL IECLASS_POINTERPOS X X/* Values for the 'Code' field of a IECLASS_NKCONTROL message */ X#define IECODE_NKHOTKEY 0x01 /* Hotkey transferred control to server */ X#define IECODE_NKHOTQUIT 0x02 /* Hotkey ending control by server */ X#define IECODE_NKLEFT 0x04 /* Mouse is exiting from left of handler screen */ X#define IECODE_NKRIGHT 0x08 /* Mouse is exiting from right of handler scrn */ X Xstruct NETKEYMSG X{ X struct Message m; X short msgtype; X struct InputEvent ie; X}; X X/* Defines for the msgtype field */ X#define NKM_NONE -1 X#define NKM_IEVENT 0 X#define NKM_QUIT 1 X#define NKM_CONTROL 2 X#define NKM_ACK 3 X#define NKM_HEREWEGO 4 X#define NKM_WEBEDONE 5 X Xtypedef struct X{ X struct Task *buddy; X short dokey; X short state; X short nmsgs; X struct MsgPort *nkmp; X struct MsgPort *rtnp; X struct IntuitionBase *ibase; X short swidth; X short exit; X int active; X struct DChannel *chan; X X} GLOBAL_DATA; X X/* Defines for the global.state field */ X#define EM_SANITY -3 /* Failed sanity check - prolly too many msgs outstanding */ X#define EM_NOMEM -2 /* Out of memory */ X#define EM_QUIT -1 /* Normal quit */ X#define EM_DOIT 0 /* Keep on truckin' */ X#define EM_LURK 1 /* Pass events through */ X#define EM_RELURK 2 /* Start lurking immediately */ X X#define NKM_HANDLER 2 /* Parms to InitDevice */ X#define NKM_SERVER 1 X Xstruct InputEvent * __regargs myhandler(struct InputEvent *ev, GLOBAL_DATA *gptr); X X/* * * * * * * * * * * EXTERNAL ROUTINES * * * * * * * * * */ Xstruct IOStdReq * CreateIOReq(struct MsgPort *, int); Xvoid DeleteIOReq(struct IOStdReq *); X Xvoid mshow(struct GfxBase *GfxBase, UWORD *NoSprData, int on); END_OF_FILE if test 4109 -ne `wc -c <'netkeys.h'`; then echo shar: \"'netkeys.h'\" unpacked with wrong size! fi # end of 'netkeys.h' fi if test -f 'nkutil.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'nkutil.c'\" else echo shar: Extracting \"'nkutil.c'\" \(2509 characters\) sed "s/^X//" >'nkutil.c' <<'END_OF_FILE' X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ X/* |_o_o|\\ Copyright (c) 1990 The Software Distillery. All Rights Reserved.*/ X/* |. o.| || This program may not be distributed without the permission of */ X/* | . | || the authors. */ X/* | o | || */ X/* | . |// Written by Doug Walker */ X/* ====== BBS:(919)-471-6436 VOICE:(919)-467-4764 */ X/* BIX: djwalker USENET: ...!mcnc!rti!sas!walker */ X/* 405 B3 Gooseneck Dr, Cary, NC 27513, USA */ X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ X#include <exec/types.h> X#include <exec/nodes.h> X#include <exec/lists.h> X#include <exec/memory.h> X#include <exec/ports.h> X#include <exec/io.h> X#include <proto/exec.h> X Xstruct IOStdReq * CreateIOReq(struct MsgPort *, int); Xvoid DeleteIOReq(struct IOStdReq *); X Xstruct MsgPort * CreatePort(name, pri) Xchar *name; Xint pri; X{ X UBYTE sigbit; X register struct MsgPort *port; X X if ((sigbit = AllocSignal(-1)) == -1) X return((struct MsgPort *)0); X X if ((port = (struct MsgPort *)AllocMem(sizeof(struct MsgPort), X MEMF_CLEAR|MEMF_PUBLIC)) == 0) X { X FreeSignal(sigbit); X return((struct MsgPort *) (0)); X } X port->mp_Node.ln_Name = name; X port->mp_Node.ln_Pri = pri; X port->mp_Node.ln_Type = NT_MSGPORT; X port->mp_Flags = PA_SIGNAL; X port->mp_SigBit = sigbit; X port->mp_SigTask = (struct Task *)FindTask(0); X AddPort(port); X return(port); X} X Xvoid DeletePort(port) Xstruct MsgPort *port; X{ XRemPort(port); XFreeSignal(port->mp_SigBit); XFreeMem((char *)port,sizeof(struct MsgPort)); X} X Xstruct IOStdReq * XCreateIOReq(port, size) Xstruct MsgPort *port; Xint size; X{ X struct IOStdReq *ioReq; X X if ((ioReq = (struct IOStdReq *) X AllocMem(size, MEMF_CLEAR | MEMF_PUBLIC)) != NULL) X { X ioReq->io_Message.mn_Node.ln_Type = NT_MESSAGE; X ioReq->io_Message.mn_Node.ln_Pri = 0; X ioReq->io_Message.mn_Length = size; X ioReq->io_Message.mn_ReplyPort = port; X } X return(ioReq); X} X Xvoid DeleteIOReq(ioReq) Xstruct IOStdReq *ioReq; X{ XioReq->io_Message.mn_Node.ln_Type = 0xff; XioReq->io_Device = (struct Device *) -1; XioReq->io_Unit = (struct Unit *) -1; X XFreeMem( (char *)ioReq, ioReq->io_Message.mn_Length); X} X END_OF_FILE if test 2509 -ne `wc -c <'nkutil.c'`; then echo shar: \"'nkutil.c'\" unpacked with wrong size! fi # end of 'nkutil.c' fi if test -f 'snetkeys.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'snetkeys.c'\" else echo shar: Extracting \"'snetkeys.c'\" \(5856 characters\) sed "s/^X//" >'snetkeys.c' <<'END_OF_FILE' X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ X/* |_o_o|\\ Copyright (c) 1990 The Software Distillery. All Rights Reserved.*/ X/* |. o.| || This program may not be distributed without the permission of */ X/* | . | || the authors. */ X/* | o | || */ X/* | . |// Written by Doug Walker */ X/* ====== BBS:(919)-471-6436 VOICE:(919)-467-4764 */ X/* BIX: djwalker USENET: ...!mcnc!rti!sas!walker */ X/* 405 B3 Gooseneck Dr, Cary, NC 27513, USA */ X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ X X/* * * * * * * * * INCLUDE FILES * * * * * * * * * * * */ X X#include "netkeys.h" X#include <proto/intuition.h> X Xstruct DChannel *chan; X Xstruct MsgPort *lisport; X Xint InitDevice(void); Xint TermDevice(void); X Xvoid _main(char *); X Xvoid _main(x) Xchar *x; X{ X short swidth; X short exit; X int state; X struct Screen wbdat; X struct MsgPort *inputDevPort = NULL; X struct IOStdReq *inputRequestBlock = NULL; X struct InputEvent ie; X struct IntuitionBase *IntuitionBase = NULL; X struct GfxBase *GfxBase = NULL; X UWORD *NoSprData = NULL; X ULONG rc; X X if ( X InitDevice() || X X ((inputDevPort = CreatePort(0,0)) == NULL) || X X ((inputRequestBlock = X CreateIOReq(inputDevPort, sizeof(struct IOStdReq))) == NULL) || X X !(IntuitionBase = (struct IntuitionBase *) X OpenLibrary("intuition.library", 0)) || X X !(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0)) || X X !(NoSprData = AllocMem(12, MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR)) || X X OpenDevice("input.device",0,(struct IORequest *)inputRequestBlock,0)) X { X goto abort; X } X X NoSprData[0] = 0xFE00; X NoSprData[1] = 0xFF00; X X X /* If we have an appropriate version of intuition, ask for info */ X /* about the workbench screen */ X if(IntuitionBase->LibNode.lib_Version < 33 X || !(GetScreenData((char *)&wbdat, sizeof(struct Screen), X WBENCHSCREEN, NULL))) X { X /* Either we're running on an old version of the system, or the */ X /* GetScreenData call failed for some reason. In either case, */ X /* simply assume a 640x200 screen and be done with it. */ X swidth = 639; X } X else X { X /* Use the wb width, and STDSCREENHEIGHT. */ X swidth = wbdat.Width-1; X } X X inputRequestBlock->io_Command = IND_WRITEEVENT; X inputRequestBlock->io_Flags = 0; X inputRequestBlock->io_Length = IESZ; X inputRequestBlock->io_Data = (APTR)&ie; X X state = 0; X mshow(GfxBase, NoSprData, 0); X while(1) X { X rc = Wait(SIGBREAKF_CTRL_C | (1 << chan->port.mp_SigBit)); X X if(rc & SIGBREAKF_CTRL_C) /* Received ctrl-c */ X goto abort; X X if(DRead(chan, (char *)&ie, IESZ) != IESZ) X goto abort; X X if(ie.ie_Class == IECLASS_NKCONTROL) /* Special 'control' record */ X { X exit = ie.ie_Code; X if(ie.ie_Code & IECODE_NKHOTQUIT) X { X mshow(GfxBase, NoSprData, 0); X state = 0; X continue; X } X X if(!(ie.ie_Code & IECODE_NKHOTKEY)) X { X IntuitionBase->MouseX = (ie.ie_X == 0 ? swidth-1 : 1); X IntuitionBase->MouseY = ie.ie_Y; X } X X state = 1; X mshow(GfxBase, NoSprData, 1); X continue; X } X else if(state == 0) X continue; X X if( X ie.ie_Class == IECLASS_RAWMOUSE && X (ie.ie_Qualifier & IEQUALIFIER_RELATIVEMOUSE) && X ie.ie_Code == IECODE_NOBUTTON && X ( X ( X (exit & IECODE_NKRIGHT) && X ie.ie_X < 0 && X IntuitionBase->MouseX == 0 X ) X || X ( X (exit & IECODE_NKLEFT) && X ie.ie_X > 0 && X IntuitionBase->MouseX == swidth X ) X ) X ) X { X mshow(GfxBase, NoSprData, 0); X ie.ie_X = IntuitionBase->MouseX; X ie.ie_Y = IntuitionBase->MouseY; X ie.ie_Class = IECLASS_NKCONTROL; X DWrite(chan, (char *)&ie, IESZ); X state = 0; X continue; X } X X ie.ie_NextEvent = NULL; X DoIO((struct IORequest *)inputRequestBlock); X } X Xabort: X if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase); X X if(GfxBase) X { X if(NoSprData) X { X mshow(GfxBase, NoSprData, 1); X FreeMem(NoSprData, 12); X } X CloseLibrary((struct Library *)GfxBase); X } X X TermDevice(); X X if (inputRequestBlock != NULL) X { X if (inputRequestBlock->io_Device != NULL) X CloseDevice((struct IORequest *)inputRequestBlock); X DeleteIOReq(inputRequestBlock); X } X X if (inputDevPort != NULL) DeletePort(inputDevPort); X} X Xint InitDevice(void) X{ X struct MsgPort *myport; X struct Message *msg; X X chan = NULL; X lisport = NULL; X X myport = &(((struct Process *)FindTask(0L))->pr_MsgPort); X lisport = DListen(PORT_NETKEYS); X do X { X WaitPort(myport); X } X while(!(msg=GetMsg(myport))); X X ReplyMsg(msg); X X if(!lisport) return(1); X X Wait(1<<lisport->mp_SigBit); X X if(!(chan = (struct DChannel *)DAccept(lisport))) X return(1); X X return(0); X} X Xint TermDevice(void) X{ X if(chan) X { X DClose(chan); X chan = NULL; X } X X if(lisport) X { X DUnListen(lisport); X lisport = NULL; X } X X return(0); X} X Xvoid MemCleanup(void); Xvoid MemCleanup(){} END_OF_FILE if test 5856 -ne `wc -c <'snetkeys.c'`; then echo shar: \"'snetkeys.c'\" unpacked with wrong size! fi # end of 'snetkeys.c' fi if test -f 'snetkeys.uu' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'snetkeys.uu'\" else echo shar: Extracting \"'snetkeys.uu'\" \(8214 characters\) sed "s/^X//" >'snetkeys.uu' <<'END_OF_FILE' Xbegin 666 snetkeys XM```#\P`````````"``````````$```5A````1@```^D```5A3E7^<$CG)P*1Q XMR"M(_G0K2/YX*TC^?"M(_I8K2/Z:80`#%DJ`9@`"4D*G0J=.N@/64$\K0/Z:H XM2H!G``(^2'@`,"\`3KH$6E!/*T#^EDJ`9P`"*$/Z`K!P`"QX``1.KOW8*T#^P XM?$J`9P`"$$/Z`JIP`$ZN_=@K0/YX2H!G``'\<`PB/``!``-.KO\Z*T#^=$J`R XM9P`!YD'Z`I)P`")M_I9R`$ZN_D1*@&8``=`@;?YT,+S^`#%\_P```B!M_GP,+ XM:``A`!1E&D'M_IX@/````5IR`9/)+&W^?$ZN_E9*@&8&/CP"?V`(,"W^JBX`; XM4T<@;?Z6,7P`"P`<0B@`'G`6(4``)$'M_H`B;?Z6(T@`*'H`0J<O+?YT+RW^/ XM>$ZZ#2)/[P`,<``@;`$($"@`#W(!)`'AH@!"$``@`BQX``1.KO["*T#^<`@`9 XM``QF``$P2'@`%DAM_H`O+`$(3KH'W$_O``QR%K"!9@`!%!`M_H19`&9F/"W^$ XMAC`M_H8(```!9Q9"IR\M_G0O+?YX3KH,M$_O``QZ`&".,"W^A@@```!F'C`MZ XM_HIF""`'2,!3@&`"<`$@;?Y\,4``1C%M_HP`1'H!2'@``2\M_G0O+?YX3KH,E XM<D_O``Q@`/].2H5G`/]($"W^A%4`9@``@C`M_H@(```/9W8P+?Z&#$``_V9LW XM"`8``V<0,"W^BFP*(&W^?$IH`$9G&`@&``)G4#`M_HIO2B!M_GPP*`!&L$=F( XM/D*G+RW^="\M_GA.N@P*(&W^?#MH`$;^BCMH`$3^C!M\``3^A$AX`!9(;?Z`T XM+RP!"$ZZ!T1/[P`8>@!@`/Z^0JW^@")M_I8L>``$3J[^.&``_JI*K?Y\9PPB; XM;?Y\+'@`!$ZN_F)*K?YX9S1*K?YT9R)(>``!+RW^="\M_GA.N@N83^\`#")M* XM_G1P#"QX``1.KO\N(FW^>"QX``1.KOYB80`!$$JM_I9G'B!M_I9*J``49PHB$ XM2"QX``1.KOX^+RW^EDZZ`?Q83TJM_IIG"B\M_II.N@%\6$],WT#D3EU.=6ENX XM='5I=&EO;BYL:6)R87)Y`&=R87!H:6-S+FQI8G)A<GD``&EN<'5T+F1E=FEC, XM90``3E7_^$CG(`*1R"E(`0@I2`$,(D@L>``$3J[^VB!`0^@`7$AX)18K2?_\8 XM3KH!LEA/*4`!#"!M__PL>``$3J[^@"!M__PL>``$3J[^C"M`__A*@&?@(FW_Y XM^"QX``1.KOZ&2JP!#&8$<`%@+G``(&P!#!`H``]R`20!X:(@`DZN_L(O+`$,] XM3KH"2EA/*4`!"$J`9@1P`6`"<`!,WT`$3EU.=4JL`0AG#B\L`0A.N@?T6$]"% XMK`$(2JP!#&<.+RP!#$ZZ`<Y83T*L`0QP`$YU3G5(YP,R)F\`&"XO`!QP_RQXA XM``1.KOZV+``,!@#_9@1P`&!(<"(B/``!``%.KO\Z)$`@"F8,<``0!DZN_K!PZ XM`&`J)4L`"B`'%4``"15\``0`"$(J``X51@`/D\E.KO[:)4``$")*3J[^GB`*= XM3-],P$YU2.<`$B9O``PB2RQX``1.KOZ8<``0*P`/3J[^L")+<").KO\N3-](" XM`$YU3E7__$CG`1(F;P`8+B\`'"`'(CP``0`!+'@`!$ZN_SHK0/_\2H!G%B!`Z XM$7P`!0`(0B@`"2(',4$`$B%+``Y,WTB`3EU.=4CG`!(F;P`,%WP`_P`(,'S_\ XM_R=(`!0G2``8<``P*P`2(DLL>``$3J[_+DS?2`!.=4Y5__A(YP$"/B\`&D*M< XM__QP$'(!+'@`!$ZN_SIR`#('+P%(>@!J+P`K0/_X3KH/,$_O``PL>``$3J[_7 XM?")M__A.KOYZ2H!F%$*G+RW_^$ZZ_J!03RM`__Q*@&8.(FW_^'`0+'@`!$ZN) XM_RXL>``$3J[_=B`M__Q,WT"`3EU.=41.150N4$]25"Y86%A86`!$3D54+E!/C XM4E0N)6QD`#``1$Y%5"Y53DE4+@``)7,E<P``2.<`,B9O`!`D:P`*(`MG+"QXQ XM``1.KO]\+PMA``"Z6$]*@&;T+PM.NOZ(6$\L>``$3J[_=B)*<!!.KO\N3-],O XM`$YU3E7_^$CG,#*5RB`*9CX@;0`(+'@`!$ZN_HPF0"!+(`AG*C`K`!P,0``A, XM9@Y"IR\+80`&[%!/)$!@!A=\``$`'R)++'@`!$ZN_H9@OB!M``C0_``8(FT`! XM"")I`!2SR&<@<``@;0`($"@`#W(!)`'AHG8`%@#GH2`"+'@`!$ZN_LX@"F<$+ XM($I@`I'((`A,WTP,3EU.=4Y5__Q(YS`2)F\`'"!++'@`!$ZN_HPK0/_\2H!GN XM#B!`$7P``0`?(D!.KOZ&0>L`&")K`!2SR&<8<``0*P`/<@$D`>&B=@`6`.>A% XM(`).KO[.2JW__%;`1`!(@$C`3-](#$Y=3G5.50``3EU.=4Y5_\Q(YP<2)F\`/ XM4#XO`%8<+P!;&B\`7R`+9@1'^OZ,+PM(;?_080`%]E!/*T#_S')^N@%C`BH!K XM#`4`@60">H&\`6,"+`$,!@"!9`)\@2!`2J@`(F=<.WP`(/_L<@`R!RM!_^@K: XM0/_\*T#_WAM&_]ER`!(%*T'_VB!H`")#[?_0+'@`!$ZN_I)(;?_080`$TEA/) XM$"W_[TH`9A@@+?_H(&W_S#%``#0O"&$`!D@@+?_,8`HO+?_,80`&%G``3.U(A XMX/^X3EU.=4Y5__1(YS<R)F\`-"XO`#Q\`$HK`#9G!G#_8``!1$J'9P`!$D'KT XM`"8L>``$3J[^_B1`($H@"&80($M.KOZ,)$`@2B`(9P``[G`'L"H`"&8N2JL`0 XM/&<$4ZL`/$JJ`"1G$")J`"@@*@`D+'@`!$ZN_RXB2G`P+'@`!$ZN_RY@H#`J: XM`!P,0``D9R(,0``C9P@,0``B9@``C!=\``$`-B)*+'@`!$ZN_H9@`/]V("H`0 XM("(J`"22@"H!NH=N*B!J`"C1P"`%(FT`#&`"$MA3@&3ZGH7<A=NM``PB2BQX. XM``1.KOZ&8`#_/"!J`"C1P"`'(FT`#&`"$MA3@&3ZW(??J@`@?@`L>``$3J[_. XM?!5\``4`"$'K`!0B2DZN_Q!.KO]V8`#_`!5\``$`'R)*+'@`!$ZN_H9@`/[LP XM+PMA``3T6$]**P`V9QQP`!`K``]R`20!X:)V`!8`YZ$@`BQX``1.KO[.(`9,5 XMWTSL3EU.=4CG!S(F;P`<)&\`("XO`"1\`$HK`#9G!'#_8#!*AV<J($LL>``$8 XM3J[^@"\'+PHO"V$`_F9/[P`,*@#<A4J%:PK5Q9Z%2BL`-F?2(`9,WTS@3G5(J XMYP$0)F\`#"XO`!`G1P`X3-\(@$YU3E7_R$CG`S(F;P!4)&\`6"XO`%PL!TJKE XM`#AG>D*G+PMA``+L4$]*@&MH<#`B/``!``$L>``$3J[_.B!`,7P`)``<<@`R5 XM*P`T(4$`&"%+`"PA2P`.*T#_S"`'<@%.KO\Z(&W_S"%``"@A1P`D(`<B2BQH$ XM`"A@`AS94X!D^B!K`"(B;?_,+'@`!$ZN_I)2JP`\8$9\_V!".WP`)/_L<``P- XM*P`T*T#_Z"M+__PK2__>*TK_^"M'__0@:P`B0^W_T"QX``1.KOZ22&W_T&$`+ XM`?Y83THM_^]G`GS_+PMA``.`(`9,[4S`_[1.74YU3E7_T$CG`!(F;P!`.WP`8 XM(__L<``P*P`T*T#_Z"M+__PK2__>(&L`(D/M_]`L>``$3J[^DDAM_]!A``&F/ XM+HMA``,R3.U(`/_(3EU.=4Y5_]!(YP<2)F\`3!XO`%,\+P!6&B\`6SM\`";_! XM['``,"L`-"M`_^@K2__\*TO_WG``,`9(0$)`<@`2!>&!@(%R`!('@($K0/_X+ XM(&L`(D/M_]`L>``$3J[^DDAM_]!A``$T+HMA``+`3.U(X/^\3EU.=4Y5_YQ(F XMYP`2)F\`="`+9@1'^OI:+PM(>OI62'KZ7DAM_Z5.N@D*3^\`$$/M_Z4L>``$0 XM3J[^>BM`_YQG0D*G0J=.NOA^.WP`)?_L0JW_Z$*M__PK0/_>*T#_H"!M_YQ#W XM[?_0+'@`!$ZN_I)(;?_080``LBZM_Z!.NOBX3^\`#$JM_YQ6P$0`2(!(P$S?J XM2`!.74YU3E7_S$CG`!(F;P!$.WP`(O_L<``P*P`T*T#_Z"M+__PK2__>(&L`B XM(D/M_]`L>``$3J[^DE*K`#Q"JP`X2&W_T"\+80``D%!/0>L`)BQX``1.KO[^S XM*T#_S$J`9@X@2TZN_HPK0/_,2H!G%B!M_\P1?``!`!\B2"QX``1.KOZ&8,@O0 XM"V$``7I,[4@`_\1.74YU2.<@$B9O`!!P![`K``AG'"!K``YP`!`H``]R`20!D XMX:(@`BQX``1.KO["8-PL>``$3J[_?")+3J[_!$ZN_W9,WT@$3G5.5?_Z2.<!' XM,B9O`!Y^`"`K`#RPJP`X;U8@2RQX``1.KOZ`($M.KOZ,)$!P![`J``AF,$I'D XM9@9^`!XJ`!^U[0`,9QI*J@`D9PPB:@`H("H`)$ZN_RXB2G`P3J[_+E.K`#Q@E XMK$'K`"8B2DZN_PI@H"`'2,!,WTR`3EU.=4Y5_]!(YP`R)F\`1"1O`$AP0"(\8 XM``$``2QX``1.KO\Z($`1?``$``@K0/_\</].KOZV(&W__!%```^3R4ZN_MH@5 XM;?_\(4``$$/H`!0O"4ZZ!_P@;?_\T/P`)BZ(3KH'[EA/("L`&"!M__PQ0``T_ XM)T@`+"`*9R8O"DAZ^!1(>O@<2&W_T4ZZ!LA/[P`00^W_T2QX``1.KOYZ)T``; XM#B!M__PA:P`.`"(@"$S?3`!.74YU2.<`$B9O``QP`!`K``\L>``$3J[^L")+Z XM<$!.KO\N3-](`$YU2.<P$B9O`!1!ZP`8(FL`%+/(9@Q!ZP`J(FL`)K/(9QQPR XM`!`K``]R`20!X:)V`!8`YZ$@`BQX``1.KO[.3-](#$YU``!.5?_\2.<A,"9O` XM`!PD;P`@+B\`)"MK`";__$J'9RQ*K```9VP@+```(@!"04A!(&W__#%!``HD6 XM/```___`@C%```Z3R2E)``!@1B!M__P,:`$@``AF.@QH`2(`#&8R2JP``&86A XM<``P*``*2$!"0'(`,B@`#H"!*4```"`*0D!(0#%```H@"@*```#__S%```Y,$ XMWPR$3EU.=4Y5_\1(YR<P)F\`7"1O`&!^`'P`>@!P`!M\`"#_^W(`*T'_]G3_( XM*T+_\D'M_]`;0/_Q&T#__"M!_^0K0?_H*TC_S$H39T)P`!`3<AA=06LXL'L0[ XM"&;V3OL0!``C8```(``@8```%@`K8```#``M8````GX!8`Y\`6`*>@%@!AM\L XM``'__%*+8+H0$W(PL`%F!E*+&T'_^W`JL!-F$"!20^@`!"2)*U#_]E*+8`Y(L XM;?_V+PM.N@2$4$_7P!`3<BZP`68F4HMP*K`39A`@4D/H``0DB2M0__)2BV`.7 XM2&W_\B\+3KH$5E!/U\`0$W)LL`%F"AM\``'_\5*+8`AR:+`!9@)2BQ`;<@`2F XM`!M`__!P,%U`:P`"5+)[``AF]$[[``0`8V```BH`<V```>@`6&```7X`>&``> XM`7@`<&```5X`;V```0P`=6```.(`9&````)*+?_Q9PP@4D/H``0DB2`08`H@C XM4D/H``0DB2`0*T#_[&P*<@%$K?_L*T'_Z$JM_^AG!'`M8`I*!F<$<"M@`G`@D XM&T#_T'``$`8B+?_H@H!P`!`%@H!G"%*M_\Q2K?_D+RW_["\M_\Q.N@+F4$\KR XM0/_(("W_\DJ`:@9R`2M!__(@+?_((BW_\I*`2.T``O_$;RX@;?_,(DC3P6`"$ XM$MA3@&3Z<``0+?_[(BW_Q"!M_\Q@`A#`4X%D^B`M__(K0/_(T:W_Y$'M_]`K) XM2/_,2@=G``%0&WP`(/_[8``!1DHM__%G#"!20^@`!"2)(!!@"B!20^@`!"2)$ XM(!`K0/_L8`#_8DHM__%G#"!20^@`!"2)(!!@"B!20^@`!"2)(!`K0/_L2BW_3 XM_&<2(&W_S!#\`#!R`2M!_^0K2/_,+P`O+?_,3KH"0%!/*T#_R&``_R@;?``P( XM__L@+?_R2H!J!G`(*T#_\DHM__%G#"!20^@`!"2)(!!@"B!20^@`!"2)(!`KQ XM0/_L2BW__&<6(&W_S!#\`#`0_`!X<@(K0?_D*TC_S"\`+RW_S$ZZ`AQ03RM`Y XM_\AP6+`M__!F`/Z^2&W_T$ZZ`5!83V``_K`@4D/H``0DB2)0*TG_S&8(0?H`W XMW"M(_\P@;?_,2AAF_%.(D>W_S"M(_^0@+?_R2H!K*K'`;R8K0/_D8"!P`2M`] XM_^0@4D/H``0DB2`0&T#_T$(M_]%@!G``8```C"`M_^0B+?_VLH!L"'0`*T+_& XM]F`$D:W_]DH'9S93K?_D;1AP`"!M_\P0&"\`*TC_S"!M`!!.D%A/8.)3K?_V9 XM;4AP`!`M__LO`"!M`!!.D%A/8.A3K?_V;1)P`!`M__LO`"!M`!!.D%A/8.A3\ XMK?_D;1AP`"!M_\P0&"\`*TC_S"!M`!!.D%A/8.(@"TS?#.1.74YU``!.5?_VB XM2.<!,"9O`!XD;P`B*VT`$/_V'AI*!V<T<"6^`&8BL!)F!%**8!HO"TAM__8OY XM"F$`^\Q/[P`,*T#_^F<$)$!@TG``$`<O`$Z36$]@QDS?#(!.74YU2.<@,"9O^ XM`!`D2TH29R1P`!`20>P`!0@P``$(`&<*<@`2`'0@DH)@!'(`$@`4@5**8-@@Y XM"TS?#`1.=0``````````<&$@+P`((&\`!$Y5__0B3W(*3KH!7`9!`#`2P4J`` XM9O`@"1#AO\EF^D(0D(].74YU```@+P`((&\`!$Y5__0B3R(``D$`!P9!`#`2= XMP>:(9O`@"1#AO\EF^D(0D(].74YU```P,3(S-#4V-S@Y86)C9&5F("\`""!ON XM``1#[P`$,@`"00`/$OL0W.B(9O(@"2(/6($0X;*)9OI"$)"!3G4@;P`$(DAR3 XM`'``+P(,$``K9P8,$``M9@)22!`8!```,&T2#```"6X,)`'E@=*"TH'2@&#F4 XM#!$`+68"1($D'R`(4X`@;P`(((&0B4YU+P<N+P`(4JP!%"`'(&P!$!#`*4@!] XM$"X?3G5.50``2.<`,"9O`!`D;P`40JP!%"E+`1!(;0`0+PI(>O_&3KK^/B!L+ XM`1!"$"`L`11,[0P`__A.74YU2H!J```>1(!*@6H```Q$@6$``"!$@4YU80``T XM&$2`1(%.=4J!:@``#$2!80``!D2`3G4O`DA!-`%F```B2$!(04A"-`!G```&+ XMA,$P`DA`-`"$P3`"2$(R`B0?3G4O`W80#$$`@&0```;AF5%##$$(`&0```;I3 XMF5E##$$@`&0```;EF55#2D%K```&XYE30S0`YJA(0D)"YJI(0X#!-@`P`C0#[ XM2$'$P9""9```"%-#T(%D_G(`,@-(0^>X2$#!028?)!].=2!O``0@B%B00J@`( XM!"%(``A.=0`````#\@```^H```!&```````@("`@("`@("`H*"@H*"`@("`@H XM("`@("`@("`@("`@($@0$!`0$!`0$!`0$!`0$!"$A(2$A(2$A(2$$!`0$!`0@ XM$(&!@8&!@0$!`0$!`0$!`0$!`0$!`0$!`0$!$!`0$!`0@H*"@H*"`@("`@("B XM`@("`@("`@("`@("`@(0$!`0("`@("`@("`@("@H*"@H("`@("`@("`@("`@D XM("`@("`@2!`0$!`0$!`0$!`0$!`0$(2$A(2$A(2$A(00$!`0$!`0@8&!@8&!6 XM`0$!`0$!`0$!`0$!`0$!`0$!`0$0$!`0$!""@H*"@H("`@("`@("`@("`@(": XC`@("`@("`A`0$!`@`````````````````````````````_("E X`` Xend Xsize 5840 END_OF_FILE if test 8214 -ne `wc -c <'snetkeys.uu'`; then echo shar: \"'snetkeys.uu'\" unpacked with wrong size! fi # end of 'snetkeys.uu' fi echo shar: End of archive 1 \(of 2\). cp /dev/null ark1isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mail submissions (sources or binaries) to <amiga@cs.odu.edu>. Mail comments to the moderator at <amiga-request@cs.odu.edu>. Post requests for sources, and general discussion to comp.sys.amiga.