From 875690e00d86dcecd99b6005cda889e50265960b Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 1 Apr 2018 15:42:52 -0400 Subject: [PATCH] 1.0.0 --- common.c | 182 ++++++++++++++ config.c | 216 ++++++++++++++++ macroman.c | 150 +++++++++++ macroman.h | 12 + makefile.mk | 23 ++ marinetti.c | 73 ++++++ marinetti.h | 7 + qserver.c | 709 ++++++++++++++++++++++++++++++++++++++++++++++++++++ qserver.h | 29 +++ qserver.rez | 396 +++++++++++++++++++++++++++++ 10 files changed, 1797 insertions(+) create mode 100644 common.c create mode 100644 config.c create mode 100644 macroman.c create mode 100644 macroman.h create mode 100644 makefile.mk create mode 100644 marinetti.c create mode 100644 marinetti.h create mode 100644 qserver.c create mode 100644 qserver.h create mode 100644 qserver.rez diff --git a/common.c b/common.c new file mode 100644 index 0000000..c1c42c9 --- /dev/null +++ b/common.c @@ -0,0 +1,182 @@ +#pragma noroot +#pragma lint -1 +#pragma optimize -1 + +#include +#include +#include +#include + +#include "macroman.h" + +#if 0 +void printint(char *str, int i) +{ +char tmp[6]; + if (str && *str) WriteCString(str); + + Int2Dec(i, tmp, 5, 0); + tmp[5] = (char)0; + WriteCString(tmp); + + WriteCString("\r\n"); +} +#endif + + +extern pascal Word Random(void) inline(0x8604,dispatcher); + +Handle LoadQuote(word mID, Word rFile) +{ +Word oFile; +Word oDepth; + +int rID; +Word rCount; + +Handle rHandle; +Handle h; + + + h = NULL; + + oFile = GetCurResourceFile(); + SetCurResourceFile(rFile); + oDepth = SetResourceFileDepth(1); + rCount = CountResources(rTextForLETextBox2); + + //printint("rCount: ", rCount); + + if (rCount) + { + WordDivRec wdr; + longword index; + + wdr = UDivide(Random(), (word)rCount); + + //printint("remainder: ", wdr.remainder); + + index = GetIndResource(rTextForLETextBox2, wdr.remainder + 1); + + // todo - repeat above until index out of range + //printint("index: ", index); + + + rHandle = LoadResource(rTextForLETextBox2, index); + //printint("loadres: ", _toolErr); + if (!_toolErr) + { + word oldLen; + word newLen; + char *newText; + char *oldText; + + word len; + word i; + + oldLen = (word)GetHandleSize(rHandle); + //printint("oldLen: ", oldLen); + + h = NewHandle(oldLen << 2 + 2, mID, 0, NULL); + if (!_toolErr) + { + HLock(h); + HLock(rHandle); + + oldText = *rHandle; + newText = *h; + newLen = 0; + + i = 0; + while (i < oldLen) + { + char c; + + c = *oldText++; + i++; + + if (c == '\r') + { + *((Word *)newText) = 0x0A0D; + newText += 2; + newLen += 2; + continue; + + //*newText++ = '\r'; + //*newText++ = '\n'; + //newLen += 2; + //continue; + } + if (c == 0x01) // formatting codes. + { + c = *oldText; + switch (c) + { + case 'F': // font + oldText += 5; + i += 5; + break; + + case 'S': // set style + oldText += 5; + i += 4; + break; + + case 'C': // fore color + case 'B': // back color + case 'J': // justify + case 'L': // left margin + case 'R': // right margin + case 'X': // extra space + oldText += 3; + i += 3; + break; + } + continue; + } + if (c & 0x80) // macroman encoding. + { + int j; + c &= 0x7f; + j = macroman[c].length; + + if (j == 0) continue; + + if (j > 1) + { + char *cp; + cp = macroman[c].cp; + + newLen += j; + do + { + *newText++ = *cp++; + } + while (--j); + + continue; + } + else c = (char)macroman[c].cp; + } + + newLen++; + *newText++ = c; + } + + //*newText++ = '\r'; + //*newText++ = '\n'; + *((Word *)newText) = 0x0A0D; + newLen += 2; + HUnlock(h); + SetHandleSize(newLen, h); + } + + HUnlock(rHandle); + ReleaseResource(0, rTextForLETextBox2, index); + } + } + SetCurResourceFile(oFile); + SetResourceFileDepth(oDepth); + + return h; +} diff --git a/config.c b/config.c new file mode 100644 index 0000000..7c5cfcc --- /dev/null +++ b/config.c @@ -0,0 +1,216 @@ +#pragma noroot +#pragma lint -1 +#pragma optimize -1 + +#include +#include +#include +#include +#include +#include +#include + + +#include + +#include "qserver.h" + + +extern Handle rPath; + +static Word fd; + +/* + * load default values. + * return 0 on failure, anything else on success. + */ +// +Word LoadConfig(Word MyID) +{ +Word t; +Word oFile; +Word oDepth; + +static GSString32 filePath = {28, "*:System:Preferences:QServer"}; +static GSString32 folderPath = {21, "*:System:Preferences:"}; + +static FileInfoRecGS InfoDCB = {12, (GSString255Ptr)&filePath}; +static CreateRecGS CreateDCB = {4, (GSString255Ptr)&folderPath, 0xe3, 0x0f, 0}; + + +// 1 - check if file exists +// 2 - if no, create the folder and file +// 3 - load up the data +// 4 - if data doesn't exist, store a default value. + + fd = 0; + + GetFileInfoGS(&InfoDCB); + t = _toolErr; + if (_toolErr == pathNotFound) + { + CreateGS(&CreateDCB); + if (!_toolErr) t = fileNotFound; + } + if (t == fileNotFound) // file doesn't exist, create + { + CreateResourceFile(0,0,0,(Pointer)&filePath); + if (_toolErr) return 0; + } + else if (t) return 0; + + fd = OpenResourceFile(readWriteEnable, NULL, (Pointer)&filePath); + if (_toolErr) return 0; + + // make sure we're the only resource file... + oFile = GetCurResourceFile(); + SetCurResourceFile(fd); + oDepth = SetResourceFileDepth(1); + + // load the quote path. + + rPath = LoadResource(rC1InputString, 1); + if (_toolErr) + { + static GSString255 defPath = { 34, "*/system/CDEVs/Twilight/QuotesFile"}; + + rPath = NewHandle(36, MyID, 0, NULL); + if (rPath) + { + PtrToHand((Pointer)defPath, rPath, 36); + AddResource(rPath, 0, rC1InputString, 1); + } + } + + // restore old resource file... + + SetCurResourceFile(oFile); + SetResourceFileDepth(oDepth); + + return 1; +} + +void UnloadConfig(void) +{ + if (fd) CloseResourceFile(fd); + fd = 0; +} + +/* + * callback from SFGetFile2. only allows if resource fork found. + */ +#pragma toolparms 1 +Word SFFilter(DirEntryRecGS *file) +{ + if (file->flags & 0x8000) return displaySelect; + return noSelect; +} +#pragma toolparms 0 + + +static void SetText(WindowPtr win, Word id, void *data) +{ +GSString255 * gstr = (GSString255 *)data; +CtlRecHndl CtrlHand; +Rect r; + + CtrlHand = GetCtlHandleFromID(win, id); + + SetCtlMoreFlags(0x1000, CtrlHand); + r = (**CtrlHand).ctlRect; + EraseRect(&r); + + SetCtlValue(gstr->length, CtrlHand); + SetCtlTitle(2 + (Pointer)gstr, (Handle)CtrlHand); +} + +void DoConfig(Word MyID) +{ +static EventRecord event; + +WindowPtr win; +Word control; +Word ok; +GrafPortPtr oldPort; +Handle newPath = NULL; + + oldPort = GetPort(); + + memzero(&event, sizeof(event)); + event.wmTaskMask = 0x001f0004; + + win = NewWindow2(NULL, NULL, NULL, NULL, + refIsResource, (long)rConfigWindow, rWindParam1); + + SetPort(win); + // set the current path text... + HLock(rPath); + SetText(win, CtrlPath, *rPath); + + for (ok = true; ok;) + { + control = (Word)DoModalWindow(&event, NULL, NULL, NULL, 0x0008); + + switch(control) + { + case CtrlCancel: + case CtrlOk: + ok = false; + break; + + case CtrlBrowse: + { + SFReplyRec2 myReply; + + myReply.nameRefDesc = refIsNewHandle; + myReply.pathRefDesc = refIsNewHandle; + + SFGetFile2( + 10, 35, + refIsPointer, + (Ref)"\pSelect quotation file.", + (WordProcPtr)SFFilter, /* filter proc */ + NULL, /* type list */ + &myReply); + if (myReply.good) + { + Handle h; + Word size; + + h = (Handle)myReply.pathRef; + HLock(h); + size = GetHandleSize(h) - 2; + BlockMove(*h + 2, *h, size); + ReAllocHandle(size, MyID, 0x8000, NULL, h); + + SetText(win, CtrlPath, *h); + + if (newPath) DisposeHandle(newPath); + newPath = h; + + DisposeHandle((Handle)myReply.nameRef); + } + } + break; + } + + } + if (control == CtrlOk) // update the config file. + { + if (newPath) + { + Word size = (Word)GetHandleSize(newPath); + + ReAllocHandle(size, MyID, 0, NULL, rPath); + HandToHand(newPath, rPath, size); + MarkResourceChange(true, rC1InputString, 1); + } + UpdateResourceFile(fd); + } + + CloseWindow(win); + SetPort(oldPort); + + HUnlock(rPath); + +} diff --git a/macroman.c b/macroman.c new file mode 100644 index 0000000..e2aa0a4 --- /dev/null +++ b/macroman.c @@ -0,0 +1,150 @@ +#pragma lint -1 +#pragma noroot + +#include "macroman.h" + +#define ONECHAR(x) { 1, (char *)x } + +#define MULTICHAR(x) { sizeof(x) -1, x } + +#define BLANK { 0, (char *)0 } + +struct charmap macroman[128] = +{ + ONECHAR('A'), // 0x80 + ONECHAR('A'), + ONECHAR('C'), + ONECHAR('E'), + ONECHAR('N'), + ONECHAR('O'), + ONECHAR('U'), + ONECHAR('a'), + ONECHAR('a'), + ONECHAR('a'), + ONECHAR('a'), + ONECHAR('a'), + ONECHAR('a'), + ONECHAR('c'), + ONECHAR('e'), + ONECHAR('e'), + + ONECHAR('e'), // 0x90 + ONECHAR('e'), + ONECHAR('i'), + ONECHAR('i'), + ONECHAR('i'), + ONECHAR('i'), + ONECHAR('n'), + ONECHAR('o'), + ONECHAR('o'), + ONECHAR('o'), + ONECHAR('o'), + ONECHAR('o'), + ONECHAR('u'), + ONECHAR('u'), + ONECHAR('u'), + ONECHAR('u'), + + BLANK, // 0xA0 + BLANK, + BLANK, + BLANK, + BLANK, + ONECHAR('*'), + BLANK, + BLANK, + MULTICHAR("(r)"), + MULTICHAR("(c)"), + MULTICHAR("tm"), + BLANK, + BLANK, + BLANK, + MULTICHAR("AE"), + ONECHAR('O'), + + BLANK, // 0xB0 + BLANK, + MULTICHAR("<="), + MULTICHAR(">="), + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + MULTICHAR("ae"), + ONECHAR('o'), + + ONECHAR('?'), // 0xC0 + ONECHAR('!'), + BLANK, + BLANK, + ONECHAR('f'), + BLANK, + BLANK, + MULTICHAR("<<"), + MULTICHAR(">>"), + MULTICHAR("..."), + ONECHAR(' '), + ONECHAR('A'), + ONECHAR('A'), + ONECHAR('O'), + MULTICHAR("OE"), + MULTICHAR("oe"), + + MULTICHAR("--"), // 0xD0 + MULTICHAR("---"), + ONECHAR('"'), + ONECHAR('"'), + ONECHAR('\''), + ONECHAR('\''), + BLANK, + BLANK, + ONECHAR('y'), + ONECHAR('Y'), + ONECHAR('/'), + BLANK, + BLANK, + BLANK, + MULTICHAR("fi"), + MULTICHAR("fl"), + + BLANK, // 0xE0 + BLANK, + BLANK, + BLANK, + BLANK, + ONECHAR('A'), + ONECHAR('E'), + ONECHAR('A'), + ONECHAR('E'), + ONECHAR('E'), + ONECHAR('I'), + ONECHAR('I'), + ONECHAR('I'), + ONECHAR('I'), + ONECHAR('O'), + ONECHAR('O'), + + ONECHAR('?'), // 0xF0 + ONECHAR('O'), + ONECHAR('U'), + ONECHAR('U'), + ONECHAR('U'), + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + BLANK, + +}; diff --git a/macroman.h b/macroman.h new file mode 100644 index 0000000..653aa5e --- /dev/null +++ b/macroman.h @@ -0,0 +1,12 @@ +#ifndef __MACROMAN_H__ +#define __MACROMAN_H__ + +struct charmap +{ + int length; + char *cp; +}; + +extern struct charmap macroman[128]; + +#endif diff --git a/makefile.mk b/makefile.mk new file mode 100644 index 0000000..fb56517 --- /dev/null +++ b/makefile.mk @@ -0,0 +1,23 @@ +#for use iwith dmake(1) +# for compiling + +CFLAGS += $(DEFINES) -v #-O +LDLIBS += -l /usr/local/lib/libk +OBJS = qserver.o macroman.o common.o marinetti.o config.o +CFLAGS += -I /usr/local/include/ + +qserver: $(OBJS) qserver.r + $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@ + chtyp -t nda $@ + copyfork qserver.r $@ -r + + +qserver.o: qserver.c qserver.h +qserver.r: qserver.rez qserver.h + + +clean: + $(RM) *.o *.root *.r + +clobber: clean + $(RM) -f qotdd diff --git a/marinetti.c b/marinetti.c new file mode 100644 index 0000000..baea902 --- /dev/null +++ b/marinetti.c @@ -0,0 +1,73 @@ +#pragma lint -1 +#pragma noroot +#pragma optimize -1 + +#include +#include + +#define FLAG_LOADED 1 +#define FLAG_STARTED 2 +#define FLAG_CONNECTED 4 +#define FLAG_ERROR 0xffff + +void stopMarinetti(int flag) +{ + if (flag == FLAG_ERROR) return; + if (flag == 0) return; + if (flag & FLAG_CONNECTED) + { + TCPIPDisconnect(0, 0); + if (_toolErr) return; + } + if (flag & FLAG_STARTED) TCPIPShutDown(); + if (flag & FLAG_LOADED) UnloadOneTool(0x36); +} + + + +/* + * do the various steps to start up marinetti. + */ +int startMarinetti(void) +{ +int flag = 0; + + TCPIPStatus(); + if (_toolErr) + { + LoadOneTool(0x36, 0x0200); //load Marinetti + if (_toolErr) return FLAG_ERROR; + flag |= FLAG_LOADED; + } + if (!TCPIPStatus()) + { + TCPIPStartUp(); + flag |= FLAG_STARTED; + } + if (!TCPIPGetConnectStatus()) + { + TCPIPConnect(0); + if (_toolErr) + { + stopMarinetti(flag); + return FLAG_ERROR; + } + flag |= FLAG_CONNECTED; + } + + return flag; +} + + + + + + + + + + + + + + diff --git a/marinetti.h b/marinetti.h new file mode 100644 index 0000000..1a9f675 --- /dev/null +++ b/marinetti.h @@ -0,0 +1,7 @@ +#ifndef __MARINETTI_H__ +#define __MARINETTI_H__ + +int startMarinetti(void); +void stopMarinetti(int); + +#endif diff --git a/qserver.c b/qserver.c new file mode 100644 index 0000000..01c5250 --- /dev/null +++ b/qserver.c @@ -0,0 +1,709 @@ +#pragma nda NDAOpen NDAClose NDAAction NDAInit 30 0xffff "--Quote Server\\H**" +#pragma lint -1 +#pragma optimize -1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "qserver.h" + +Handle LoadQuote(word mID, Word rfile); + +Word LoadConfig(Word MemID); +void UnloadConfig(void); +void DoConfig(Word MemID); + + +const char *ReqName = "\pTCP/IP~kelvin~qserver~"; + +/* + variables + */ + +WindowPtr MyWindow; +Boolean FlagTCP; +Boolean FlagQS; + +Boolean FlagQDAux; +Boolean FlagFM; +Boolean FlagTE; +Boolean FlagSF; + +Boolean FlagLoadTCP; + +Handle HandleFM; +Handle HandleTE; +Handle HandleSF; + +Word MyID; +Word MyRID; +Word Ipid; + + +word rFile; +Handle rPath; +word rCount; + +struct qentry +{ + Word ipid; + Word state; + Longword tick; +}; + +#define QSIZE 16 +struct qentry queue[QSIZE]; + +word total; +word current; + + +void fixstats(void) +{ +static char stats[16]; +Word i; + + i = ksprintf(stats + 1, "%d : %d", current, total); + stats[0] = i; // pascal string + + SetInfoRefCon((LongWord)stats, MyWindow); + DrawInfoBar(MyWindow); +} + + +void InsertString(word length, char *cp) +{ +Handle handle; +TERecord **temp; +longword oldStart, oldEnd; + + handle = (Handle)GetCtlHandleFromID(MyWindow, CtrlTE); + temp = (TERecord **)handle; + + (**temp).textFlags &= (~fReadOnly); + + TEGetSelection((pointer)&oldStart, (pointer)&oldEnd, handle); + + TESetSelection((Pointer)-1, (Pointer)-1, handle); + TEInsert(teDataIsTextBlock, (Ref)cp, length, + NULL, NULL, /* no style info */ + handle); + + (**temp).textFlags |= fReadOnly; + + TESetSelection((Pointer)oldStart, (Pointer)oldEnd, handle); + +} + + +enum +{ + STATE_NULL = 0, + STATE_ESTABLISH, // waiting to establish + STATE_QUOTE, // send the quote... + STATE_SEND // waiting for data to send +}; + +void QServer(void) +{ +static srBuff srBuffer; +word delta; +int i; + + delta = false; + + TCPIPPoll(); + for (i = 0; i < QSIZE; i++) + { + word ipid; + + ipid = queue[i].ipid; + if (!ipid) continue; + + TCPIPStatusTCP(ipid, &srBuffer); + + switch (queue[i].state) + { + case STATE_ESTABLISH: + if (srBuffer.srState != TCPSESTABLISHED) + break; + + queue[i].state = STATE_QUOTE; + // drop through and send the quote. + + case STATE_QUOTE: + { + Handle h; + h = LoadQuote(MyID, rFile); + if (h) + { + HLock(h); + TCPIPWriteTCP(ipid, *h, + GetHandleSize(h), false, false); + DisposeHandle(h); + } + else + { + TCPIPWriteTCP(ipid, "Your quote here!\r\n", + 18, false, false); + } + } + queue[i].state = STATE_SEND; + break; + + case STATE_SEND: + + if (srBuffer.srSndQueued == 0) + { + queue[i].ipid = 0; + queue[i].state = 0; + TCPIPCloseTCP(ipid); + current--; + delta = true; + } + break; + + } + } + + + // check for a new connection. + if (current < QSIZE) + { + word child; + int i; + child = TCPIPAcceptTCP(Ipid, 0); + + if (!_toolErr) for (i = 0; i < QSIZE; i++) + { + if (!queue[i].ipid) + { + static char buffer[16]; + static char line[32]; + int j; + + TCPIPStatusTCP(child, &srBuffer); + + queue[i].ipid = child; + + if (srBuffer.srState == TCPSESTABLISHED) + queue[i].state = STATE_SEND; + else + queue[i].state = STATE_ESTABLISH; + + queue[i].tick = GetTick(); + + current++; + total++; + delta = true; + + TCPIPConvertIPToASCII(srBuffer.srDestIP, + buffer, 0); + + j = ksprintf(line, "%p:%d\r", + buffer, srBuffer.srDestPort); + + InsertString(j, line); + + break; + } + } + } + if (delta) fixstats(); // statistics changed. +} + + +int StartServer(void) +{ +int i; +word oFile; +word oDepth; +static char err[256]; + + total = current = 0; + + if (!rPath) + { + InsertString(32, "Fatal: No quote file specified.\r"); + return false; + } + HLock(rPath); + + rFile = OpenResourceFile(readEnable, NULL, (pointer)*rPath); + if (_toolErr) + { + InsertString(ksprintf(err, "Fatal: Unable to open %g\r", *rPath), + err); + return false; + } + + oFile = GetCurResourceFile(); + SetCurResourceFile(rFile); + oDepth = SetResourceFileDepth(1); + rCount = CountResources(rTextForLETextBox2); + SetCurResourceFile(oFile); + SetResourceFileDepth(oDepth); + + if (!rCount) + { + InsertString(ksprintf(err, "Fatal: Invalid quote file %g\r", *rPath), + err); + + CloseResourceFile(rFile); + return false; + } + + SetRandSeed(GetTick()); + + + for (i = 0; i < QSIZE; i++) + { + queue[i].ipid = 0; + queue[i].state = 0; + } + + Ipid = TCPIPLogin(MyID, 0, 0, 0, 64); + + TCPIPSetSourcePort(Ipid, PORT_QOTD); + + TCPIPListenTCP(Ipid); + + FlagQS = true; + + HiliteCtlByID(inactiveHilite, MyWindow, CtrlStartQS); + HiliteCtlByID(noHilite, MyWindow, CtrlStopQS); + + fixstats(); + HUnlock(rPath); + return true; + +} + +int StopServer(void) +{ +int i; + + + // close any q entries + for (i = 0; i < QSIZE; i++) + { + int ipid; + ipid = queue[i].ipid; + if (ipid) + { + TCPIPCloseTCP(ipid); + queue[i].ipid = 0; + } + } + + TCPIPCloseTCP(Ipid); + TCPIPLogout(Ipid); + + FlagQS = false; + Ipid = 0; + + HiliteCtlByID(inactiveHilite, MyWindow, CtrlStopQS); + HiliteCtlByID(noHilite, MyWindow, CtrlStartQS); + + CloseResourceFile(rFile); + + + SetInfoRefCon((LongWord)"\pQuote Server stopped", MyWindow); + DrawInfoBar(MyWindow); + + return true; +} + + +// activate/inactivate controls based on Marinetti status +void UpdateStatus(Boolean redraw) +{ + if (FlagTCP) // TCP started + { + // deactivate + HiliteCtlByID(inactiveHilite, MyWindow, CtrlStartM); + HiliteCtlByID(inactiveHilite, MyWindow, CtrlStopQS); + + // activate + HiliteCtlByID(noHilite, MyWindow, CtrlStopM); + HiliteCtlByID(noHilite, MyWindow, CtrlStartQS); + + SetInfoRefCon((LongWord)"\pNetwork Connected", MyWindow); + } + else + { + // activate + HiliteCtlByID(noHilite, MyWindow, CtrlStartM); + + // deactivate + HiliteCtlByID(inactiveHilite, MyWindow, CtrlStopM); + HiliteCtlByID(inactiveHilite, MyWindow, CtrlStartQS); + HiliteCtlByID(inactiveHilite, MyWindow, CtrlStopQS); + + SetInfoRefCon((LongWord)"\pNetwork Disconnected", MyWindow); + } + if (redraw) + DrawInfoBar(MyWindow); + +} + + + + + +#pragma databank 1 + +/* + * watch for + */ +pascal word HandleRequest(word request, longword dataIn, longword dataOut) +{ +Word oldRApp; + + oldRApp = GetCurResourceApp(); + SetCurResourceApp(MyID); + + if (request == TCPIPSaysNetworkUp) + { + FlagTCP = true; + UpdateStatus(true); + } + + if (request == TCPIPSaysNetworkDown) + { + if (FlagQS) StopServer(); + + FlagTCP = false; + Ipid = 0; + UpdateStatus(true); + } + SetCurResourceApp(oldRApp); + +} + +pascal void MarinettiCallback(char *str) +{ + if (MyWindow) + { + SetInfoRefCon((LongWord)str, MyWindow); + DrawInfoBar(MyWindow); + } +} + +pascal void DrawInfo(void *rect, const char *str, GrafPortPtr w) +{ + if (str) + { + SetForeColor(0x00); + SetBackColor(0x0f); + MoveTo(8,22); + DrawString(str); + } +} + +void DrawWindow(void) +{ + DrawControls(GetPort()); +} + +// returns 1 on success, 0 on error. +Word LoadNDATools(void) +{ + if (!QDAuxStatus() || _toolErr) + { + LoadOneTool(0x12,0); + if (_toolErr) return 0; + QDAuxStartUp(); + FlagQDAux = true; + } + if (!FMStatus() || _toolErr) + { + Handle h; + LoadOneTool(0x1b, 0); + if (_toolErr) return 0; + HandleFM = NewHandle(MyID, 0x0100, 0xc005, 0); + if (_toolErr) return 0; + FMStartUp(MyID, (Word)*HandleFM); + FlagFM = true; + } + if (!TEStatus() || _toolErr) + { + LoadOneTool(0x22,0x0); + if (_toolErr) return 0; + HandleTE = NewHandle(MyID, 0x0100, 0xc005, 0); + if (_toolErr) return 0; + TEStartUp(MyID, (Word)*HandleTE); + FlagTE = true; + } + if (!SFStatus() || _toolErr) + { + LoadOneTool(0x17,0); + if (_toolErr) return 0; + HandleSF = NewHandle(MyID, 0x0100, 0xc005, 0); + if (_toolErr) return 0; + SFStartUp(MyID, (Word)*HandleSF); + FlagSF = true; + } + + + +} + +#pragma databank 0 + + +GrafPortPtr NDAOpen(void) +{ +Boolean ok = true; +const char *err = NULL; + + if (!LoadNDATools()) + { + AlertWindow(awCString, NULL, + (Ref)"24~Unable to load required tools.~^Too Bad"); + return NULL; + } + + LoadConfig(MyID); + + // Check if Marinetti Active. + if (!TCPIPStatus() || _toolErr) + FlagTCP = false; + else FlagTCP = TCPIPGetConnectStatus(); + + + if (ok) + { + Pointer myPath; + Word oldLevel; + Word oldPrefs; + Word oldRApp; + LevelRecGS levelDCB; + SysPrefsRecGS prefsDCB; + Handle H; + + // load our resource. -- see TN.iigs #71 + oldRApp = GetCurResourceApp(); + ResourceStartUp(MyID); + myPath = LGetPathname2(MyID, 1); + + levelDCB.pCount = 2; + GetLevelGS(&levelDCB); + oldLevel = levelDCB.level; + levelDCB.level = 0; + SetLevelGS(&levelDCB); + + prefsDCB.pCount = 1; + GetSysPrefsGS(&prefsDCB); + oldPrefs = prefsDCB.preferences; + prefsDCB.preferences = (prefsDCB.preferences & 0x1fff) | 0x8000; + SetSysPrefsGS(&prefsDCB); + + MyRID = OpenResourceFile(readEnable, NULL, myPath); + + // + MyWindow = NewWindow2(NULL, 0, DrawWindow, NULL, + refIsResource, rQSWindow, rWindParam1); + + SetInfoDraw(DrawInfo, MyWindow); + + UpdateStatus(false); + + AcceptRequests(ReqName, MyID, &HandleRequest); + + SetSysWindow(MyWindow); + ShowWindow(MyWindow); + SelectWindow(MyWindow); + + // + prefsDCB.preferences = oldPrefs; + SetSysPrefsGS(&prefsDCB); + + levelDCB.level = oldLevel; + SetLevelGS(&levelDCB); + + SetCurResourceApp(oldRApp); + + return MyWindow; + } + return NULL; + +} + +void NDAClose(void) +{ + // if running, shut down. + + if (FlagQS) StopServer(); + + CloseWindow(MyWindow); + MyWindow = NULL; + AcceptRequests(ReqName, MyID, NULL); + UnloadConfig(); + CloseResourceFile(MyRID); + ResourceShutDown(); +} + +void NDAInit(Word code) +{ + if (code) + { + MyWindow = NULL; + FlagTCP = false; + FlagQS = false; + FlagQDAux = false; + FlagFM = false; + FlagTE = false; + FlagSF = false; + HandleFM = NULL; + HandleTE = NULL; + HandleSF = NULL; + + FlagLoadTCP = false; + + MyID = MMStartUp(); + Ipid = 0; + MyRID = 0; + } + else + { + if (FlagLoadTCP && !TCPIPGetConnectStatus()) + { + TCPIPShutDown(); + UnloadOneTool(0x36); + } + if (FlagTE) + { + TEShutDown(); + UnloadOneTool(0x22); + DisposeHandle(HandleTE); + } + if (FlagFM) + { + FMShutDown(); + UnloadOneTool(0x1b); + DisposeHandle(HandleFM); + } + if (FlagQDAux) + { + QDAuxShutDown(); + UnloadOneTool(0x12); + } + if (FlagSF) + { + SFShutDown(); + UnloadOneTool(0x17); + DisposeHandle(HandleSF); + } + + } +} + +word NDAAction(void *param, int code) +{ +word eventCode; +static EventRecord event = { 0 }; +static word counter = 0; + + if (code == runAction) + { + if (FlagQS) QServer(); + return 1; + } + + else if (code == eventAction) + { + BlockMove((Pointer)param, (Pointer)&event, 16); + event.wmTaskMask = 0x001FFFFF; + eventCode = TaskMasterDA(0, &event); + switch(eventCode) + { + case updateEvt: + BeginUpdate(MyWindow); + DrawWindow(); + EndUpdate(MyWindow); + break; + + case wInControl: + switch (event.wmTaskData4) + { + /* start marinetti */ + case CtrlStartM: + // + // 1 load marinetti if need be. + if (!TCPIPStatus() || _toolErr) + { + LoadOneTool(0x36,0x0200); + TCPIPStartUp(); + FlagLoadTCP = true; + } + if (TCPIPGetConnectStatus()) + { + FlagTCP = true; + UpdateStatus(true); + } + else + { + TCPIPConnect(MarinettiCallback); + } + break; + + /* stop marinetti */ + case CtrlStopM: + if (!TCPIPGetConnectStatus()) + { + FlagTCP = false; + UpdateStatus(true); + } + else + { + if (FlagQS) StopServer(); + // if option key down, force a shutdown. + TCPIPDisconnect(event.modifiers & optionKey, MarinettiCallback); + } + break; + + /* start the server */ + case CtrlStartQS: + StartServer(); + break; + + /* stop the server */ + case CtrlStopQS: + StopServer(); + break; + + case CtrlConfig: + DoConfig(MyID); + break; + } + // todo - Command-A selects all. + } + } + else if (code == copyAction) + { + TECopy(NULL); + return 1; // yes we handled it. + } + + return 0; + +} diff --git a/qserver.h b/qserver.h new file mode 100644 index 0000000..f90a836 --- /dev/null +++ b/qserver.h @@ -0,0 +1,29 @@ +/* + * #defines for rez/controls + * + */ + +#define rQSWindow 0x1000 + +#define CtrlStartM 0x1001 +#define CtrlStopM 0x1002 +#define CtrlStartQS 0x1003 +#define CtrlStopQS 0x1004 +#define CtrlTE 0x1005 +#define CtrlLogo 0x1006 +#define CtrlConfig 0x1007 + +#define rConfigWindow 0x2000 +#define CtrlBrowse 0x2001 +//#define CtrlPortLE 0x2002 +//#define CtrlPathLE 0x2003 +//#define CtrlPortStat 0x2004 +#define CtrlPathStat 0x2005 +#define CtrlPath 0x2006 +#define CtrlCancel 0x2007 +#define CtrlOk 0x2008 + +#define PORT_QOTD 17 + +#define ConfigWindowWidth 300 +#define ConfigWindowHeight 52 diff --git a/qserver.rez b/qserver.rez new file mode 100644 index 0000000..33b52fb --- /dev/null +++ b/qserver.rez @@ -0,0 +1,396 @@ +#include "Types.rez" +#include "qserver.h" + + +//#define WaitCodeRID 0x00700000 +//read rCtlDefProc (WaitCodeRID, fixed, convert) "waitctrl"; + + +resource rControlList (rQSWindow) { + { + CtrlStartM, + CtrlStopM, + CtrlStartQS, + CtrlStopQS, + CtrlTE, + CtrlLogo, + CtrlConfig, + } +}; + + + +resource rControlTemplate (CtrlTE) { + CtrlTE, + {55, -2, 131, 281}, + editTextControl { + { /* optional Fields */ + 0x0, + 0x7400, + 0x0, + fSingleStyle + + fReadOnly + fTabSwitch + fSmartCutPaste + + fDrawBounds, //0x27A80000, + {-1, -1, -1, -1}, + 0xFFFFFFFF, + 0, + 0x0, + 0, + 0x0, + 0x15, + CtrlTE, + 0, + 0, + 0, + 0, + 0, + 0x0, + 0x0, + 0x0 + } + } +}; + +resource rControlTemplate (CtrlStartM) { + CtrlStartM, + {4, 10, 17, 100}, + SimpleButtonControl { + { /* optional Fields */ + SquareButton, + 0x1002, + 0x0, + CtrlStartM + } + } +}; + +resource rControlTemplate (CtrlStopM) { + CtrlStopM, + {4, 180, 17, 270}, + SimpleButtonControl { + { /* optional Fields */ + SquareButton, + 0x1002, + 0x0, + CtrlStopM + } + } +}; + +// + +resource rControlTemplate (CtrlStartQS) { + CtrlStartQS, + {21, 10, 34, 100}, + SimpleButtonControl { + { /* optional Fields */ + SquareButton, + 0x1002, + 0x0, + CtrlStartQS + } + } +}; + +resource rControlTemplate (CtrlStopQS) { + CtrlStopQS, + {21, 180, 34, 270}, + SimpleButtonControl { + { /* optional Fields */ + SquareButton, + 0x1002, + 0x0, + CtrlStopQS + } + } +}; + +resource rControlTemplate (CtrlConfig) { + CtrlConfig, + {38, 90, 51, 190}, + SimpleButtonControl { + { /* optional Fields */ + SquareButton, + 0x1002, + 0x0, + CtrlConfig + } + } +}; + + + +resource rControlTemplate (CtrlLogo, nocrossbank) +{ + CtrlLogo, + {14, 130, 24, 150 }, + IconButtonControl {{ + $000C, + $1020, + 0, + 1, // icon id # + 0, + 0, + 0, + { "", "", 0, 0} + }}; +}; + +resource rPString (CtrlStopM) { + "Disconnect" +}; + +resource rPString (CtrlStartM) { + "Connect" +}; + +resource rPString (CtrlStartQS) { + "Start" +}; + +resource rPString (CtrlStopQS) { + "Stop" +}; + +resource rPString (CtrlConfig) { + "Config" +}; + +resource rPString (rQSWindow) { + " Quote Server " +}; + + + +resource rWindParam1 (rQSWindow) { + fClose + fTitle + fMove + fInfo, //0xC0B0, + rQSWindow, + 0x0, + {0, 0, 0, 0}, + rQSWindow, // rWindColor + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + 0x0, + 13, + {50, 40, 180, 320}, + infront, + rQSWindow, // rControlList + 0xA09 +}; + +resource rWindColor (rQSWindow) { + 0x0, + 0xF01, + 0x21F, + 0xF0FF, + 0xF0 +}; + + +resource rText (CtrlTE) { + "" +}; + +resource rComment (1) { + "Quote Server NDA\n\n" + "Written by Kelvin W Sherlock\n" + "November/December 2004." +}; + +resource rVersion (1) { + { + 1, + 0, + 0, + release, + 0 + }, + verUS, + "Quote Server", + "(C) 2004 Kelvin Sherlock " + "kws@a2central.com" +}; + + + +resource rIcon (1) { + $8000, // iconType + $000A, // icon Height in pixels + $0014, // icon Width in pixels + + // Icon Image + $"FFF0FFCFFFFFF03F00FF" + $"FFC3FC0FFFFF000C00FF" + $"FF0FF03FFFFF000C003F" + $"FC3FF0FFFFFF000C003F" + $"F003C00FFFFF000C003F" + $"F000C003FFFFC00F003F" + $"F000C003FFFFFC3FF0FF" + $"F000C003FFFFF0FFC3FF" + $"FC00C003FFFFC0FF0FFF" + $"FC03F00FFFFFCFFC3FFF", + + // Icon Mask + $"000F00F000000FF0FF00" + $"00FF0FF00000FFFFFF00" + $"00F00FF00000FFFFFFF0" + $"0FF00F000000FFFFFFF0" + $"0FFFFFF00000FFFFFFF0" + $"0FFFFFFF0000FFF0FFF0" + $"0FFFFFFF00000FF00F00" + $"0FFFFFFF00000F00FF00" + $"0FFFFFFF0000FF00F000" + $"0FFF0FF00000F00FF000" +}; + + +// config window + + +resource rWindParam1 (rConfigWindow) { + 0x20A0, + 0x0, + 0x0, + {0, 0, 0, 0}, + 0x0, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + 0x0, + 0, + {70, 170, 70 + ConfigWindowHeight, 170 + ConfigWindowWidth}, + infront, + rConfigWindow, + 0x9 +}; + + +resource rControlList (rConfigWindow) { + { + CtrlPathStat, + CtrlPath, + CtrlBrowse, + CtrlCancel, + CtrlOk, + } +}; + +resource rControlTemplate (CtrlPathStat) { + CtrlPathStat, + {6, 10, 15, ConfigWindowWidth - 110}, + statTextControl { + { /* optional Fields */ + fBlastText, + FctlProcNotPtr + RefIsResource, + 0x0, + CtrlPathStat, + 0, + leftJust + } + } +}; + +resource rControlTemplate (CtrlBrowse) { + CtrlBrowse, + {4, ConfigWindowWidth - 100, 17, ConfigWindowWidth - 10}, + SimpleButtonControl { + { /* optional Fields */ + NormalButton, + FCtlWantEvents + FctlProcNotPtr + RefIsResource, + 0x0, + CtrlBrowse, + 0x0, + { + "B", + "b", + 0x0100, + 0x0100 + } + } + } +}; + + +resource rControlTemplate (CtrlPath) { + CtrlPath, + {19, 10, 28, ConfigWindowWidth - 10}, + statTextControl { + { /* optional Fields */ + fBlastText + fSquishText, + FctlProcNotPtr + RefIsResource, + 0x0, + CtrlPath, + 0, + leftJust + } + } +}; + + +resource rControlTemplate (CtrlCancel) { + CtrlCancel, + {35, 10, 48, 100}, + SimpleButtonControl { + { /* optional Fields */ + NormalButton, + FCtlWantEvents + FctlProcNotPtr + RefIsResource, + 0x0, + CtrlCancel, + 0x0, + { + "\0x1B", + "\0x1B", + 0x0, + 0x0 + } + } + } +}; + +resource rControlTemplate (CtrlOk) { + CtrlOk, + {35, ConfigWindowWidth - 100, 48, ConfigWindowWidth - 10}, + SimpleButtonControl { + { /* optional Fields */ + DefaultButton, + FCtlWantEvents + FctlProcNotPtr + RefIsResource, + 0x0, + CtrlOk, + 0x0, + { + "\n", + "\n", + 0x0, + 0x0 + } + } + } +}; + +resource rPString (CtrlBrowse) { + "Browse" +}; + +resource rPString (CtrlOk) { + "Ok" +}; + +resource rPString (CtrlCancel) { + "Cancel" +}; + + +resource rTextForLETextBox2(CtrlPathStat) +{ + "Quote File:" +}; + +resource rTextForLETextBox2(CtrlPath) +{ + "" +};