commit 875690e00d86dcecd99b6005cda889e50265960b Author: Kelvin Sherlock Date: Sun Apr 1 15:42:52 2018 -0400 1.0.0 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) +{ + "" +};