home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1990
/
12
/
cheapcom.c
< prev
next >
Wrap
Text File
|
1990-07-09
|
40KB
|
1,498 lines
/*
By Don Gaspar
MOOSE, Inc. (Macintosh Object-Oriented Software Engineering)
10866 Northridge Square
Cupertino, CA 95014
(408)252-7576
Tuesday, April 10, 1990 Added MultiFinder support.
by Don T. Gaspar
Wednesday, April 11, 1990 Added scrollbars and DoGrowWindow
by Don T. Gaspar
Wednesday, April 25, 1990 Started adding the buffer, and invoking the basics
to add saving selections/sessions. This is not
completed yet.
by Don T. Gaspar
*/
/* These are the standard Mac includes for all managers */
#include <values.h>
#include <types.h>
#include <Resources.h>
#include <QuickDraw.h>
#include <fonts.h>
#include <events.h>
#include <windows.h>
#include <menus.h>
#include <textedit.h>
#include <dialogs.h>
#include <Controls.h>
#include <desk.h>
#include <toolutils.h>
#include <memory.h>
#include <Lists.h>
#include <SegLoad.h>
#include <Files.h>
#include <Packages.h>
#include <OSEvents.h>
#include <OSUtils.h>
#include <DiskInit.h>
#include <Traps.h>
#include <String.h>
#include <Strings.h>
#include <CRMIntf.h> // Communications Resource Manager stuff
#include <CMIntf.h> // Connection Manager stuff
#include <FTIntf.h> // File Transfer Manager stuff
#include <TMIntf.h> // Terminal Manager stuff
#include <CTBUtils.h> // Communications Toolbox Utility stuff
#include <Errors.h>
#include <Limits.h>
#include <Traps.h>
#include "CommTypes.h" // our communications types, etc.
#include "CheapComm.h" // our constants, forward declarations, etc.
/* Here's our global variables, dude! */
Boolean gHasWaitNextEvent; // does user machine have WaitNextEvent????
Boolean gInBackground; // are we in the background????
Boolean gStopped; // are we stopped????
TermHandle gTerm; // handle to terminal record
ConnHandle gConn; // handle to connection record
FTHandle gFT; // handle to file transfer record
Ptr gBuffer; // global connection buffer
long gFTSearchRefNum;
Boolean gStartFT; // are we doing a file transfer????
Boolean gWasFT; // was a file transfer in progress????
short gDummy;
Handle gCache; // buffer for the last terminal line recdeived/sent
TEHandle gTE; // buffer for terminal emulator
ControlHandle gScrollHHandle, gScrollVHandle; // our scroll bars in the terminal window
#pragma segment Initialize
/* Checks to see if a given trap is implemented */
Boolean TrapAvailable(tNumber,tType)
short tNumber;
TrapType tType;
{
short unImplemented;
if (tType == OSTrap)
unImplemented = _UnimplementedOSTrap;
else
unImplemented = _UnimplementedToolTrap;
return(NGetTrapAddress(tNumber,tType) != GetTrapAddress(unImplemented));
}
#pragma segment Main
/* Sends the data out via the choosen connection */
pascal long TermSendProc(thePtr, theSize, refCon, flags)
Ptr thePtr;
long theSize;
long refCon;
short flags;
{
CMErr theErr;
long termSendProc = 0L;
if (gConn != nil) {
theErr = CMWrite(gConn,thePtr,&theSize,cmData,false,nil,0,flags);
if (theErr == noErr)
termSendProc = theSize;
}
return(termSendProc);
}
#pragma segment Main
/* Gets the data from the connection tool and sends it to the terminal tool */
pascal void TermRecvProc()
{
CMErr theErr;
CMStatFlags status;
CMBufferSizes sizes;
short flags;
if (gConn != nil && gTerm != nil) {
theErr = CMStatus(gConn, sizes, &status);
if (theErr == noErr) {
if ((status & (cmStatusOpen+cmStatusDataAvail)) != 0 && sizes[cmDataIn] != 0) {
if (sizes[cmDataIn] > kBufferSize)
sizes[cmDataIn] = kBufferSize;
theErr = CMRead(gConn, gBuffer, &sizes[cmDataIn], cmData, false, nil, 0, &flags);
if (theErr == noErr) // give it to the terinal emulation buffer
sizes[cmDataIn] = TMStream(gTerm, gBuffer, sizes[cmDataIn], flags);
}
}
else
; // Connection Manager will handle this for us
}
}
#pragma segment Main
/* Gets the connection environments for the FT or Term tool */
pascal OSErr ToolGetConnEnvirons(refCon, theEnvirons)
long refCon;
ConnEnvironRec *theEnvirons;
{
OSErr toolGetConnEnvirons = envNotPresent;
if(gConn != nil)
toolGetConnEnvirons = CMGetConnEnvirons(gConn,theEnvirons);
return(toolGetConnEnvirons);
}
#pragma segment Main
/* Sends the data during a file transfer */
pascal long FTSendProc(thePtr, theSize, refCon, channel, flags)
Ptr thePtr;
long theSize;
long refCon;
CMChannel channel;
short flags;
{
CMErr theErr;
long ftSendProc = 0L;
if (gConn != nil) {
theErr = CMWrite(gConn, thePtr,& theSize, channel, false, nil, 0, flags);
if(theErr == noErr)
ftSendProc = theSize;
}
return(ftSendProc);
}
#pragma segment Main
/* Gets the data during a data transfer */
pascal long FTReceiveProc(thePtr, theSize, refCon, channel, flags)
Ptr thePtr;
long theSize;
long refCon;
CMChannel channel;
short *flags;
{
CMErr theErr;
long ftReceiveProc = 0L;
if (gConn != nil) {
theErr = CMRead(gConn, thePtr, &theSize, channel, false, nil, 0, flags);
if (theErr == noErr)
ftReceiveProc = theSize;
}
return(ftReceiveProc);
}
#pragma segment Main
/* Sets the file transfer flag if an autoreceive string was found */
pascal void AutoRecCallBack(theConn, data, refNum)
ConnHandle theConn;
Ptr data;
long refNum;
{
if (gFTSearchRefNum == refNum)
gStartFT = true;
}
#pragma segment Main
/* Checks to see if the file transfer has an autoreceive string, and then adds a
search to find it */
void AddFTSearch()
{
Str255 tempStr;
if (gFT != nil && gConn != nil) {
//tempStr = (*gFT)->autoRec;
if ((*gFT)->autoRec[0] != 0) {
gFTSearchRefNum = CMAddSearch(gConn,(*gFT)->autoRec, cmSearchSevenBit,
(ProcPtr)AutoRecCallBack);
if (gFTSearchRefNum == -1) {
AlertUser("Couldn't add stream search\0", false);
gFTSearchRefNum = 0;
}
}
}
}
#pragma segment Main
/* Initiates a file transfer send from the menu command */
void DoSend()
{
SFReply theReply;
Point where;
short numTypes;
SFTypeList typeList;
FTErr anyErr;
if(gFT != nil) {
SetPt(&where,100,100);
if(((**gFT).attributes & ftTextOnly) != 0) {
typeList[0] = 'TEXT';
numTypes = 1;
}
else
numTypes = -1;
sfgetfile(&where, "File to send", nil, numTypes, typeList, nil, &theReply);
if(theReply.good) {
anyErr = FTStart(gFT, ftTransmitting, &theReply);
if(anyErr != noErr)
; // file transfer tool will alert user
}
}
}
#pragma segment Main
/* Initiates a file transfer receive from the menu */
void DoReceive()
{
SFReply theReply;
OSErr anyErr;
if (gFT != nil) {
theReply.vRefNum = 0;
//theReply.fName = '';
gStartFT = false;
if (gConn != nil ) {
if ((**gFT).autoRec != "\0" && gFTSearchRefNum != 0) {
CMRemoveSearch(gConn, gFTSearchRefNum);
gFTSearchRefNum = 0;
}
}
anyErr = FTStart(gFT, ftReceiving, &theReply);
if(anyErr != noErr)
; // file transfer tool will alert the user
}
}
#pragma segment Main
/* checks to see if a window belongs to a DA */
Boolean IsDAWindow(window)
WindowPtr window;
{
if (window == nil)
return(false);
else
return (((WindowPeek) window)->windowKind < 0);
}
#pragma segment Main
/* Adjust the scroll bars if the window need it */
void AdjustScrollBars(OldRect,whichWindow)/* Resized this window */
Rect *OldRect; /* Rect area */
WindowPtr whichWindow; /* Window that was resized */
{
WindowPtr SavePort; /* Place to save the last port */
Rect temp2Rect,tempRect; /* temp rectangle */
short Index; /* temp integer */
GetPort(&SavePort); /* Save the current port */
SetPort(whichWindow); /* Set the port to my window */
if (gScrollHHandle != nil) /* Only do if the control is valid */
{
HLock((Handle)gScrollHHandle);/* Lock the handle while we use it */
tempRect.left = (*gScrollHHandle)->contrlRect.left;/* the area to update */
tempRect.top = (*gScrollHHandle)->contrlRect.top - 4;/* Widen the area to update */
tempRect.right = (*gScrollHHandle)->contrlRect.right + 16;/* Widen the area to update */
tempRect.bottom = (*gScrollHHandle)->contrlRect.bottom;/* the area to update */
InvalRect(&tempRect); /* Flag old position for update routine */
tempRect.top = (*gScrollHHandle)->contrlRect.top ;/* */
tempRect.right = (*gScrollHHandle)->contrlRect.right ;/* */
temp2Rect.left = whichWindow->portRect.left;/* Get window rectangle */
temp2Rect.top = whichWindow->portRect.top ;/* */
temp2Rect.right = whichWindow->portRect.right ;/* */
temp2Rect.bottom = whichWindow->portRect.bottom;/* */
Index = temp2Rect.right - temp2Rect.left - 13;/* Get the scroll area width */
tempRect.left = -1; /* Pin at left edge */
HideControl(gScrollHHandle);/* Hide it during size and move */
SizeControl(gScrollHHandle, Index,16);/* Make it 16 pixels high, std width */
MoveControl(gScrollHHandle, tempRect.left,temp2Rect.bottom - temp2Rect.top-15);/* Size it correctly */
ShowControl(gScrollHHandle);/* Safe to show it now */
HUnlock((Handle)gScrollHHandle);/* Let it float again */
} /* End for scroll handle not nil)*/
if (gScrollVHandle != nil) /* Only do if the control is valid */
{
HLock((Handle)gScrollVHandle);/* Lock the handle while we use it */
tempRect.left = (*gScrollVHandle)->contrlRect.left-4;/* the area to update */
tempRect.top = (*gScrollVHandle)->contrlRect.top;/* Widen the area to update */
tempRect.right = (*gScrollVHandle)->contrlRect.right;/* Widen the area to update */
tempRect.bottom = (*gScrollVHandle)->contrlRect.bottom+16;/* the area to update */
InvalRect(&tempRect); /* Flag old position for update routine */
tempRect.left = (*gScrollVHandle)->contrlRect.left;/* Get control rectangle */
tempRect.bottom = (*gScrollVHandle)->contrlRect.bottom;/* */
temp2Rect.left = whichWindow->portRect.left;/* Get window rectangle */
temp2Rect.top = whichWindow->portRect.top ;/* */
temp2Rect.right = whichWindow->portRect.right ;/* */
temp2Rect.bottom = whichWindow->portRect.bottom;/* */
Index = temp2Rect.bottom - temp2Rect.top - 13;/* Get the scroll area height */
tempRect.top = -1; /* Pin at top edge */
HideControl(gScrollVHandle);/* Hide it during size and move */
SizeControl(gScrollVHandle, 16,Index);/* Make it 16 pixels wide, std height */
MoveControl(gScrollVHandle, temp2Rect.right - temp2Rect.left-15,tempRect.top);/* Size it correctly */
ShowControl(gScrollVHandle);/* Safe to show it now */
HUnlock((Handle)gScrollVHandle);/* Let it float again */
} /* End for scroll handle not nil) */
SetPort(SavePort); /* Restore the old port */
} /* End of function */
#pragma segment Main
/* Checks to see if the window belongs to our application */
Boolean IsAppWindow(window)
WindowPtr window;
{
short windowKind;
long theRefCon;
if ( window == nil )
return false;
else { /* application windows have windowKinds >= userKind (8) or dialogKind (2) */
theRefCon = GetWRefCon(window);
windowKind = ((WindowPeek) window)->windowKind;
return ((windowKind >= userKind) || (windowKind == dialogKind)
& (gTerm != (TermHandle)theRefCon) & (gConn != (ConnHandle)theRefCon)
& (gFT != (FTHandle)theRefCon));
}
} /*IsAppWindow*/
#pragma segment Main
/* alerts the user of any errors that have occurred */
void AlertUser(msg, fatal)
char *msg;
Boolean fatal;
{
short itemHit;
SetCursor(&qd.arrow);
ParamText(c2pstr(msg),"","","");
itemHit = Alert(rUserAlert, nil);
if (fatal)
Terminate();
}
#pragma segment Main
/* Initiates a connection */
void OpenConnection()
{
CMErr theErr;
CMBufferSizes sizes;
CMStatFlags status;
if(gConn != nil) {
theErr = CMStatus(gConn, sizes, &status);
if(theErr == noErr)
if((status & (cmStatusOpen + cmStatusOpening)) == 0)
theErr =CMOpen(gConn, false, nil, -1);
if (theErr != noErr)
; // connection tool will tell the uer if there's an errror
}
}
#pragma segment Main
/* Nukes the connection */
void CloseConnection()
{
CMErr theErr;
CMBufferSizes sizes;
CMStatFlags status;
if (gConn != nil) {
theErr = CMStatus(gConn, sizes, &status);
if(theErr == noErr)
if ((status & (cmStatusOpen+cmStatusOpening)) != 0)
theErr = CMClose(gConn, false, nil ,0, true);
if (theErr != noErr)
; // connection tool will handle the error
}
}
#pragma segment Main
/* Closes our window */
Boolean DoCloseWindow(window)
WindowPtr window;
{
Boolean doCloseWindow = true;
if(IsDAWindow(window))
CloseDeskAcc(((WindowPeek) window)->windowKind);
else if (IsAppWindow(window)) {
CloseConnection();
if(gTerm != nil) {
HUnlock((Handle)gTerm);
TMDispose(gTerm);
}
if(gFT != nil) {
HUnlock((Handle)gFT);
FTDispose(gFT);
}
if(gConn != nil) {
HUnlock((Handle)gConn);
CMDispose(gConn);
}
if (gBuffer != nil)
DisposPtr(gBuffer);
if(gCache != nil)
DisposHandle(gCache);
if(gTE != nil)
TEDispose(gTE);
DisposeWindow(window);
}
return(doCloseWindow);
}
#pragma segment Main
/* tries to get the default tool proc ID, otherwise gets the first one it can find */
short FindToolID(toolClass)
OSType toolClass;
{
Str255 toolName;
OSErr anyErr;
short procID = -1;
if (toolClass == classTM) {
StuffHex(&toolName,kDefaultTermTool);
procID = TMGetProcID(toolName);
if(procID == -1) {
anyErr = CRMGetIndToolName(toolClass,1, toolName);
if (anyErr == noErr)
procID = TMGetProcID(toolName);
}
}
else if (toolClass == classCM) {
StuffHex(&toolName,kDefaultConnTool);
procID = CMGetProcID(toolName);
if(procID == -1) {
anyErr = CRMGetIndToolName(toolClass,1, toolName);
if (anyErr == noErr)
procID = CMGetProcID(toolName);
}
}
else if (toolClass == classFT) {
StuffHex(&toolName,kDefaultFTTool);
procID = FTGetProcID(toolName);
if(procID == -1) {
anyErr = CRMGetIndToolName(toolClass,1, toolName);
if (anyErr == noErr)
procID = FTGetProcID(toolName);
}
}
return(procID);
}
#pragma segment Main
/* this is the click loop for the terminal emulation to track */
pascal Boolean clikLoop(refcon)
long refcon;
{
return(true);
}
#pragma segment Initialize
/* this function just sets up the CommToolbox for what we need;
it should resemble most of the other Macinotosh toolbox calls */
void InitCommTB()
{
(void)InitCTBUtilities(); // Comm Toolbox Utilities
(void)InitCRM(); // Communications Resource Manager
// initialize the Terminal Manager
if (InitTM() == tmNoTools) // Did we fail
AlertUser("No terminal tools found, dude!\0", true);
// Initialize the Connection Manager
if(InitCM()== cmNoTools) // failure????
AlertUser("No connection tools found, dude!\0", true);
// Initialize the File Transfer Manager
if(InitFT() == ftNoTools) // failure????
AlertUser("No file transfer tools found, dude!\0",false);
gTerm = nil; // gotta initialize our globals
gConn = nil;
gFT = nil;
gCache = nil;
gFTSearchRefNum = 0;
}
#pragma segment Main
/* this will cache all the data coming in through the serial port */
pascal long cacheProc(refCon, theTermData)
long refCon;
TermDataBlock *theTermData;
{
long sizeCached;
TermEnvironRec theEnvirons;
theEnvirons.version = curTermEnvRecVers;
theEnvirons.termType = tmTextTerminal;
(void)TMGetTermEnvirons(gTerm, &theEnvirons);
if (theTermData->theData == nil)
return(-1);
if(gCache != nil) // is it valid????
DisposHandle(gCache); // nuke it, dude
HLock((Handle)theTermData->theData);
gCache = theTermData->theData;
if(HandToHand(&gCache)) {
DisposHandle(gCache);
sizeCached = -1;
}
else {
sizeCached = GetHandleSize(gCache);
}
HUnlock((Handle)theTermData->theData);
if(theTermData->flags == tmTextTerminal && sizeCached >0L) {
/*HandAndHand(gCache, (**gTE).hText);
(**gTE).teLength += 80;
(**gTE).nLines += 1;*/
((Ptr)*gCache,80L,gTE);
//(**gTE).viewRect.top -= (**gTE).lineHeight;
//(**gTE).destRect.top -= (**gTE).lineHeight;
//TECalText(gTE);
//TEScroll(0,-(**gTE).lineHeight,gTE);
}
return(tmNoErr);
}
#pragma segment Main
/* gets the window and create the session */
Boolean DoNewWindow()
{
WindowPtr window;
Rect theRect;
short procID;
CMBufferSizes sizes;
Rect tempRect;
short index;
Rect r;
window = GetNewWindow(rWindow, nil, (WindowPtr)-1);
SetPort(window);
/* Make a scroll bar, Scroll bar */
SetRect(&tempRect,-1,241,392,257);
tempRect.left = window->portRect.left;
tempRect.right = window->portRect.right;
tempRect.top = window->portRect.top;
tempRect.bottom = window->portRect.bottom;
gScrollHHandle = GetNewControl(cHScrollBar,window);
index = tempRect.right - tempRect.left - 13;
tempRect.left = 0;
SizeControl(gScrollHHandle, index,16);
MoveControl(gScrollHHandle, tempRect.left-1,tempRect.bottom - tempRect.top-15);
/* Make a scroll bar, Scroll bar */
SetRect(&tempRect,391,-1,407,242);
tempRect.left = window->portRect.left;
tempRect.right = window->portRect.right;
tempRect.top = window->portRect.top;
tempRect.bottom = window->portRect.bottom;
gScrollVHandle = GetNewControl(cVScrollBar,window);
index = tempRect.bottom - tempRect.top - 13;
tempRect.top = 0;
SizeControl(gScrollVHandle, 16,index);
MoveControl(gScrollVHandle, tempRect.right - tempRect.left-15,tempRect.top-1);
//SetCtlMax(gScrollVHandle,10000);
/* terminal tool */
procID = FindToolID(classTM);
if(procID == -1)
AlertUser("No terminal tools found, dude!\0", true);
theRect = window->portRect;
theRect.bottom -= 16;
theRect.right -= 16;
/* no cache, breakproc, or clikloop */
gTerm = TMNew(&theRect,&theRect, tmSaveBeforeClear + tmAutoScroll,
procID, window, (ProcPtr)TermSendProc,(ProcPtr)cacheProc,nil,
/*(ProcPtr)clikLoop*/nil, (ProcPtr)ToolGetConnEnvirons,0,0);
SetRect(&r,theRect.left,-theRect.bottom,theRect.right,theRect.top);
gTE = TENew(&r,&r);
(**gTE).txSize = 9;
(**gTE).txFont = monaco;
(**gTE).viewRect.bottom = (((**gTE).viewRect.bottom - (**gTE).viewRect.top)/
(**gTE).lineHeight)*(**gTE).lineHeight + (**gTE).viewRect.top;
TEAutoView(true,gTE);
/* custom configure with our personal settings -- store this as a file later */
(void)TMSetConfig(gTerm, "Scroll Smooth\0");
if(gTerm == nil)
AlertUser("Can't create a terminal tool, dude!\0", true);
HLock((Handle)gTerm);
/* connection tool */
procID = FindToolID(classCM);
if(procID == -1)
AlertUser("No connection tools found, dude!/0", true);
sizes[cmDataIn] = kBufferSize*10; // just the data channel; large incoming buffer
sizes[cmDataOut] = kBufferSize;
sizes[cmCntlIn] = 0;
sizes[cmCntlOut] = 0;
sizes[cmAttnIn] = 0;
sizes[cmAttnOut] = 0;
gConn = CMNew(procID, cmData, sizes, 0,0);
(void)CMSetConfig(gConn,"Baud 9600 DataBits 7 StopBits 1 Parity Even ModemType Other PhoneNumber \0429,1800-346-0145\042\0");
if(gConn == nil)
AlertUser("Can't create a connection tool, dude!/0", true);
HLock((Handle)gConn);
/* allocate space for reads/writes using the number returned by the connection tool */
gBuffer = NewPtrClear(sizes[cmDataIn]);
if(MemError() != noErr)
AlertUser("Out of memory, dude!\0", true);
/* file transfer tool */
procID = FindToolID(classFT);
if(procID == -1)
AlertUser("No file transfer tools found, dude!\0", false);
/* no read/write proc -- tool has its own */
gFT = FTNew(procID, 0 ,(ProcPtr)FTSendProc, (ProcPtr)FTReceiveProc,
nil, nil, (ProcPtr)ToolGetConnEnvirons, window, 0L,0L);
if(gFT == nil)
AlertUser("Can't create a file transfer tool, dude!\0", true);
HLock((Handle)gFT);
gWasFT = false;
gStartFT = false;
gFTSearchRefNum = 0;
AddFTSearch();
return(true);
}
#pragma segment Initialize
/* initialize our goodies and the toolbox */
void Initialize()
{
Handle menuBar;
WindowPtr window;
OSErr ignoreError;
long total,contig;
Boolean ignoreResult;
EventRecord event;
short count;
SysEnvRec TerraMac;
short err;
gHasWaitNextEvent = TrapAvailable(_WaitNextEvent, ToolTrap);
gInBackground = false;
InitGraf((Ptr) &qd.thePort);
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(nil);
InitCursor();
for(count=0;count<3;count++)
ignoreResult = GetNextEvent(everyEvent, &event);
if (!TrapAvailable(_CommToolboxTrap, OSTrap))
AlertUser("No commtoolbox, dude!\0", true);
ignoreError = SysEnvirons(kSysEnvironsVersion, &TerraMac);
if (TerraMac.systemVersion < 0x600 || TerraMac.machineType < 0)
AlertUser("You need System 6.0 or later, dude!\0", true);
PurgeSpace(&total, &contig);
if (total < kMinSpace)
AlertUser(true);
if ((long) GetApplLimit() - (long) ApplicZone() < kMinHeap)
AlertUser("Out of memory, dude!\0", true);
InitCommTB(); // initialize our comm toolbox things
menuBar = GetNewMBar(rMenuBar);
if(menuBar == nil)
AlertUser("Can't get the menubar, dude!\0", true);
SetMenuBar(menuBar);
DisposHandle(menuBar);
AddResMenu(GetMHandle(mApple), 'DRVR'); // desk accessories
DrawMenuBar(); // show the menus
if (!DoNewWindow()) // can we create our comm window????
AlertUser("Can't create a session, dude!\0", true);
gStopped = true;
}
#pragma segment Main
/* cleans up and gets the hell out of here */
void Terminate()
{
WindowPtr aWindow;
Boolean closed = true;
aWindow = FrontWindow();
do {
if (aWindow != nil)
if (IsAppWindow(aWindow))
closed = DoCloseWindow(aWindow);
if(aWindow != nil)
aWindow = (WindowPtr)(((WindowPeek)aWindow)->nextWindow);
} while(!(closed | aWindow ==nil));
if(closed)
ExitToShell();
}
#pragma segment Main
/* enables and disables items based on the applications current state */
void AdjustMenus()
{
WindowPtr window;
MenuHandle menu;
CMErr theErr;
CMBufferSizes sizes;
CMStatFlags status;
window = FrontWindow();
menu = GetMHandle(mFile);
if(menu == nil)
AlertUser("Can't get menu resource, dude!\0", true);
if (gConn != nil) {
theErr = CMStatus(gConn, sizes, &status);
if (theErr == noErr) {
if (!IsDAWindow(window)) {
setitem(menu, iOpen, "Open");
setitem(menu,iClose,"Close");
if((status & (cmStatusOpen+cmStatusOpening)) == 0) {
EnableItem(menu, iOpen);
DisableItem(menu, iClose);
}
else {
DisableItem(menu,iOpen);
EnableItem(menu,iClose);
}
DisableItem(menu, iSendFile);
DisableItem(menu,iReceiveFile);
if (gFT != nil ) {
if (((**gFT).attributes & ftSendDisable) == 0)
EnableItem(menu, iSendFile);
if (((**gFT).attributes & ftReceiveDisable) == 0)
EnableItem(menu, iReceiveFile);
}
}
else {
setitem(menu,iOpen, "Open");
setitem(menu, iClose, "Close");
DisableItem(menu, iOpen);
EnableItem(menu,iClose);
DisableItem(menu, iSendFile);
DisableItem(menu, iReceiveFile);
}
}
}
menu = GetMHandle(mEdit);
if (menu == nil)
AlertUser("Can't get the menu resource, dude!\0", true);
if (!IsDAWindow(window)) {
EnableItem(menu, iUndo);
EnableItem(menu, iCut);
EnableItem(menu,iCopy);
EnableItem(menu,iPaste);
EnableItem(menu,iClear);
EnableItem(menu,iSelectAll);
EnableItem(menu,iFind);
EnableItem(menu,iFindAgain);
EnableItem(menu,iRecallLast);
EnableItem(menu,iShowClip);
}
else {
DisableItem(menu,iUndo);
DisableItem(menu, iCut);
DisableItem(menu, iCopy);
DisableItem(menu, iPaste);
DisableItem(menu, iClear);
DisableItem(menu,iSelectAll);
DisableItem(menu,iFind);
DisableItem(menu,iFindAgain);
DisableItem(menu,iRecallLast);
DisableItem(menu,iShowClip);
}
menu = GetMHandle(mSettings);
if (menu == nil)
AlertUser("Can't get the menu resource, dude!\0", true);
if (!IsDAWindow(window)) {
EnableItem(menu, iConnection);
EnableItem(menu, iFileTransfer);
EnableItem(menu, iTerminal);
}
else {
DisableItem(menu, iConnection);
DisableItem(menu, iFileTransfer);
DisableItem(menu, iTerminal);
}
if (gConn != nil) {
theErr = CMStatus(gConn, sizes, &status);
}
menu = GetMHandle(mPhone);
if (menu == nil)
AlertUser("Can't get the menu resource, dude!\0", true);
if (gConn != nil) {
theErr = CMStatus(gConn, sizes, &status);
if (theErr == noErr) {
if (!IsDAWindow(window)) {
if(status & (cmStatusOpen+cmStatusOpening)) {
DisableItem(menu, iOpenConn);
EnableItem(menu, iHangUp);
EnableItem(menu, iBreak);
EnableItem(menu, iSendXON);
EnableItem(menu, iSendXOFF);
}
else {
EnableItem(menu, iOpenConn);
DisableItem(menu, iHangUp);
DisableItem(menu, iBreak);
DisableItem(menu, iSendXON);
DisableItem(menu, iSendXOFF);
}
}
else {
DisableItem(menu, iOpenConn);
DisableItem(menu, iHangUp);
DisableItem(menu, iBreak);
DisableItem(menu, iSendXON);
DisableItem(menu, iSendXOFF);
}
}
}
}
/* tries to give the menu to the tool */
#pragma segment Main
Boolean DoToolMenu(menuID, menuItem)
short menuID;
short menuItem;
{
if (gTerm != nil)
return(TMMenu(gTerm, menuID, menuItem) );
if (gConn != nil)
return(CMMenu(gConn, menuID, menuItem));
if(gFT != nil)
return(FTMenu(gFT, menuID, menuItem));
return(false);
}
#pragma segment Main
/* execute our application commands */
void DoMenuCommand(menuResult)
long menuResult;
{
short menuID;
short menuItem;
short itemHit;
Str255 DAName;
short DARefNum;
Boolean handledByDA;
Boolean ignore;
Point where;
short result;
Handle tempHand;
menuID = HiWrd(menuResult);
menuItem = LoWrd(menuResult);
if(!DoToolMenu(menuID,menuItem))
switch (menuID) {
case mApple:
switch(menuItem) {
case iAbout:
itemHit = Alert(rAboutAlert,nil);
break;
default:
GetItem(GetMHandle(mApple), menuItem, DAName);
DARefNum = OpenDeskAcc(DAName);
}
break;
case mFile:
switch(menuItem) {
case iOpen:
if (!IsDAWindow(FrontWindow()))
OpenConnection();
break;
case iClose:
if(IsDAWindow(FrontWindow()))
ignore = DoCloseWindow(FrontWindow());
else
CloseConnection();
break;
case iSendFile:
if(!IsDAWindow(FrontWindow()))
DoSend();
break;
case iReceiveFile:
if(!IsDAWindow(FrontWindow()))
DoReceive();
break;
case iRevert:
break;
case iOpenCapture:
break;
case iAppendCapture:
break;
case iPageSetup:
break;
case iPrint:
break;
case iQuit:
Terminate();
}
break;
case mEdit:
case iUndo:
case iCut:
case iCopy:
case iPaste:
case iClear:
case iSelectAll:
handledByDA = SystemEdit(menuItem-1);
break;
case iFind:
break;
case iFindAgain:
break;
case iRecallLast:
break;
case iShowClip:
break;
case mSettings:
switch (menuItem) {
case iConnection:
if (gConn != nil ) {
HUnlock((Handle)gConn);
SetPt(&where,10,40);
result = CMChoose(&gConn,where, nil);
switch (result) {
case chooseDisaster:
case chooseFailed:
AlertUser("Connection choose failed, dude!\0",(result = chooseDisaster));
break;
case chooseOKMajor:
AddFTSearch();
}
HLock((Handle)gConn);
}
break;
case iFileTransfer:
if(gFT != nil ) {
HUnlock((Handle)gFT);
SetPt(&where,10,40);
result = FTChoose(&gFT,where, nil);
switch (result) {
case chooseDisaster:
case chooseFailed:
AlertUser("File transfer choose failed, dude!\0", (result = chooseDisaster));
break;
case chooseOKMinor:
case chooseOKMajor:
if(gFTSearchRefNum != 0 && gConn != nil)
CMRemoveSearch(gConn,gFTSearchRefNum);
gFTSearchRefNum = 0;
AddFTSearch();
}
HLock((Handle)gFT);
}
break;
case iTerminal:
if(gTerm != nil) {
HUnlock((Handle)gTerm);
SetPt(&where,10,40);
result = TMChoose(&gTerm,where, nil);
if(result < 0)
AlertUser("Terminal choose failed, dude!\0", (result = chooseDisaster));
HLock((Handle)gTerm);
}
break;
}
case mPhone:
switch(menuItem) {
case iOpenConn:
if (!IsDAWindow(FrontWindow()))
OpenConnection();
break;
case iHangUp:
if(IsDAWindow(FrontWindow()))
ignore = DoCloseWindow(FrontWindow());
else
CloseConnection();
break;
case iBreak:
CMBreak(gConn,20L,true,nil); // break signal
AlertUser("Break completed, dude!\0", false);
break;
case iSendXON:
break;
case iSendXOFF:
break;
}
break;
}
HiliteMenu(0);
}
#pragma segment Main
/* Grows the window in response to the user resizing it */
void DoGrowWindow(theEvent, whichWindow)
EventRecord *theEvent;
WindowPtr whichWindow;
{
Point myPt;
Rect oldRect, tempRect;
long mResult;
SetPort(whichWindow);/* Point all activity to this window */
myPt = theEvent->where;/* Get mouse position */
GlobalToLocal(&myPt);/* Make it relative */
oldRect.left = whichWindow->portRect.left;/* Save the rect before resizing */
oldRect.right = whichWindow->portRect.right;/* */
oldRect.top = whichWindow->portRect.top;/* */
oldRect.bottom = whichWindow->portRect.bottom;/* */
SetRect(&tempRect,475,100,(qd.screenBits.bounds.right - qd.screenBits.bounds.left), (qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) - 20);/* l,t,r,b */
mResult = GrowWindow(whichWindow, theEvent->where, &tempRect);/* Grow it , globally relative*/
SizeWindow(whichWindow, LoWrd(mResult), HiWrd(mResult), true);/* Resize to result */
AdjustScrollBars(&oldRect, whichWindow);
SetPort(whichWindow);/* Point all activity to this window */
SetRect(&tempRect, 0, myPt.v - 15, myPt.h + 15, myPt.v + 15); /* Position for horz scrollbar area */
EraseRect(&tempRect);/* Erase old area */
InvalRect(&tempRect);/* Flag us to update it */
SetRect(&tempRect, myPt.h - 15, 0, myPt.h + 15, myPt.v + 15); /* Position for vert scrollbar area */
EraseRect(&tempRect);/* Erase old area */
InvalRect(&tempRect);/* Flag us to update it */
DrawGrowIcon(whichWindow);/* Draw the grow Icon again */
if (gTerm != nil) { //adjust the terminal emulation area
tempRect = whichWindow->portRect;
tempRect.bottom -= 16;
tempRect.right -= 16;
//TMResize(gTerm,&tempRect);
}
}
#pragma segment Main
/* Updates the window, dude! */
void DoUpdate(window)
WindowPtr window;
{
RgnHandle savedClip;
GrafPtr savedPort;
if (IsAppWindow(window)) {
GetPort(&savedPort);
SetPort(window);
/* clip to the window content */
savedClip = NewRgn();
GetClip(savedClip);
ClipRect(&window->portRect);
DrawControls(window);
DrawGrowIcon(window);
BeginUpdate(window);
if(gTerm != nil )
TMUpdate(gTerm, window->visRgn);
if(gTE != nil)
TEUpdate(&window->portRect,gTE);
EndUpdate(window);
SetClip(savedClip);
DisposeRgn(savedClip);
SetPort(savedPort);
}
}
#pragma segment Main
/* Suspends/Resumes the terminal window */
void DoResume(becomingActive)
Boolean becomingActive;
{
WindowPtr theWindow;
GrafPtr savedPort;
GetPort(&savedPort);
theWindow = FrontWindow();
while (theWindow!= nil) {
if (IsAppWindow(theWindow)) {
SetPort(theWindow);
if(gTerm != nil)
TMResume(gTerm, becomingActive);
if(gConn != nil)
CMResume(gConn, becomingActive);
if(gFT != nil)
FTResume(gFT, becomingActive);
}
theWindow = (WindowPtr)(((WindowPeek) theWindow)->nextWindow);
}
SetPort(savedPort);
}
#pragma segment Main
/* (De)Activates the window */
void DoActivate(window, becomingActive)
WindowPtr window;
Boolean becomingActive;
{
if (IsAppWindow(window)) { // does the window belong to us????
SetPort(window); // set current port
if(gConn != nil) // do we have a valid connection????
CMActivate(gConn, becomingActive);// activate it
if(gTerm != nil) // do we have a terminal????
TMActivate(gTerm, becomingActive); // activate it
if(gFT != nil) // do we have a vlaid file transfer????
FTActivate(gFT, becomingActive);// activate it
}
}
#pragma segment Main
/* updates mouse cursor depending on its cotton-pickin' location */
void AdjustCursor(mouse)
Point *mouse;
{
WindowPtr window;
Point bozoPt;
bozoPt = *mouse;
window = FrontWindow(); /* we only adjust the cursor when we are in front */
if ( ! gInBackground && IsAppWindow(window) ) {
GlobalToLocal(&bozoPt); // localize the coordinates
if (gTerm != nil) // if the terminal is valid
if(!PtInRect(bozoPt,&(**gTerm).viewRect))
InitCursor();
}
} /*AdjustCursor*/
#pragma segment Main
/* tries to pass the event to a tool if the window is a tool window;
handles event if appropriate */
Boolean DoToolEvent(event, window)
EventRecord *event;
WindowPtr window;
{
Boolean doToolEvent;
if (window != nil && !IsAppWindow(window)) { // is the window valid and not ours????
doToolEvent = true;
/* Evidently, copies of the commtb record are in the refCon field of
the window for changing the settings */
if(gFT != nil && gFT == (FTHandle)GetWRefCon(window))
FTEvent(gFT,event); // handle file transfer manager event
else if(gConn != nil && gConn == (ConnHandle)GetWRefCon(window))
CMEvent(gConn,event); // handle the connection manager event
else if(gTerm != nil && gTerm == (TermHandle)GetWRefCon(window))
TMEvent(gTerm,event); // handle the terminal manager event
else
doToolEvent = false;
}
else
doToolEvent = false;
return(doToolEvent);
}
#pragma segment Main
/* Controls handling all the events in the event queue in our application;
We could define scripting events if we wanted and intercept them here
as well. This should be straight forward and pretty much self-explanatory.*/
void DoEvent(event)
EventRecord *event;
{
short part;
short err;
WindowPtr window;
char key;
long result;
Boolean processed;
Point aPoint;
switch (event->what) { // what type of event did we have????
case mouseDown:
part = FindWindow(event->where,&window); // find where the mouse was clicked
switch(part) {
case inMenuBar:
AdjustMenus();
DoMenuCommand(MenuSelect(event->where));
break;
case inSysWindow:
SystemClick(event, window);
break;
case inContent: // within the window itself
if (!DoToolEvent(event, window)) { // tool event???? try to handle anyway
if (window != FrontWindow()) // not in front????
SelectWindow(window); // bring it to front
else if (gTerm != nil) // otherwise, it may be a terminal event
TMClick(gTerm, event);
}
break;
case inDrag: // user wants to move the window????
if (!DoToolEvent(event, window))
DragWindow(window,event->where,&qd.screenBits.bounds);
break;
case inGrow:
if(!DoToolEvent(event,window)) // user wants to change the window's size????
if(IsAppWindow(window))
DoGrowWindow(event, window);
break;
case inZoomIn:
case inZoomOut:
case inGoAway: // user wants to nuke the window????
if (DoToolEvent(event, window))
;
break;
}
break;
case keyDown: // user typed on the keyboard
case autoKey:
window = FrontWindow(); // need to get the front window
if (IsAppWindow(window)) { // is it our window????
key = event->message & charCodeMask;
processed = false;
if ( event->modifiers & cmdKey ) {
AdjustMenus(); /* enable/disable/check menu items properly */
result = MenuKey(key);
if(result != 0L) { // user selected a cmd-key combination
processed = true;
DoMenuCommand(result); // handle it like a menu
}
}
if(gTerm != nil && !processed) // key pressed was for the terminal
if(!DoToolEvent(event, window))
TMKey(gTerm, event); // let the terminal manager handle it
}
break;
case activateEvt:
window = (WindowPtr)event->message;
if(!DoToolEvent(event, window))
DoActivate(window, (event->modifiers & activeFlag) != 0);
break;
case updateEvt:
window = (WindowPtr)event->message;
if(!DoToolEvent(event, window))
DoUpdate(window);
break;
case diskEvt: // disk inserted events!
if (HiWrd(event->message) != noErr) {
SetPt(&aPoint, kDILeft, kDITop);
err = DIBadMount(aPoint, event->message);
}
break;
case kOSEvent:
switch (event->message >> 24) { /* high byte of message */
case kSuspendResumeMessage: /* suspend/resume is also an activate/deactivate */
if(!DoToolEvent(event, FrontWindow()))
; // do nothing
gInBackground = (event->message & kResumeMask) == 0;
DoResume(!gInBackground);
break;
}
break;
}
}
#pragma segment Main
/* idles all the communications tools; this was taken from the Surfer pascal
example provided from Apple -- you can get it from APDA.*/
void DoIdle()
{
WindowPtr theWindow;
Boolean doFT, doTM;
GrafPtr savedPort;
GetPort(&savedPort);
theWindow = FrontWindow();
while (theWindow != nil) {
if (IsAppWindow(theWindow)) {
SetPort(theWindow);
//TEIdle(gTE);
if(gConn != nil)
CMIdle(gConn);
doFT = false;
doTM = true;
if (gFT != nil ) {
if (((**gFT).flags & ftIsFTMode) != 0) {
doFT = true;
gWasFT = true;
if(((**gFT).attributes & ftSameCircuit) != 0)
doTM = false;
}
else {
if (gWasFT) {
gWasFT = false;
if(((**gFT).flags & ftSucc) == 0)
;
AddFTSearch();
}
if(gStartFT)
DoReceive();
}
if (doFT)
FTExec(gFT);
} /* if gFT != nil */
if(gTerm != nil) {
if (doTM) {
TMIdle(gTerm);
TermRecvProc();
}
}/* gTerm != nil */
}
theWindow = (WindowPtr)(((WindowPeek)theWindow)->nextWindow);
}
SetPort(savedPort);
}
#pragma segment Main
/* Main event loop, dude */
void EventLoop()
{
Boolean gotEvent;
EventRecord event;
do {
/* use WNE if it is available */
DoIdle(); //keep the term looking cool, dude!
if ( gHasWaitNextEvent )
gotEvent = WaitNextEvent(everyEvent, &event, 0, nil);
else {
SystemTask();
gotEvent = GetNextEvent(everyEvent, &event);
}
if ( gotEvent ) {
/* make sure we have the right cursor before handling the event */
AdjustCursor(&event.where);
DoEvent(&event);
}
/* change the cursor (and region) if necessary */
AdjustCursor(&event.where);
} while ( true ); /* loop forever; we quit via ExitToShell */
} /*EventLoop*/
#pragma segment Main
/* main */
main()
{
UnloadSeg((Ptr)_DataInit); // Give a hoot, don't pollute!
MaxApplZone(); // expand the heap
MoreMasters(); // allocate some blocks of master pointers
MoreMasters();
MoreMasters();
Initialize(); // set up everything -- let's get going!
UnloadSeg((Ptr)Initialize); // Give a hoot, don't pollute!
EventLoop();
}