4D External Area Shell
Volume Number: | | 7
|
Issue Number: | | 2
|
Column Tag: | | C Workshop
|
4D External Area Shell
By Alexander Colwell, Redondo Beach, CA
Introduction
4th Dimension (4D) is an amazing database developed for the Macintosh. It allows rapid development of an applications database for specified requirements. One of the nice features in 4D is the ability to execute external procedures and areas. External procedure (EP) is similar to HyperCard external commands and functions. This gives the database developers additional controls required in their input and output layout designs.
The external area (EA) is a section of the layout to display some graphical object the 4D does not handle. 4D does handle almost every thing the database developer would normally require. However, there may be some cases where the standard data entry field types: text, radio button, check-box button, pop-up menus, etc would not handle the desire operation in user mac-friendly style. For example, Figure 1 shows an EA of a calendar. (Alex uses an alternate and configurable WDEF; he also uses an alternate CDEF for scrollbars.-ed)

Figure 1
The calendar EA would be more intuitive to the user determining how to input the specified days rather than text-base form or some other radio/check-box button combinations. For example: If using text-base form then the user should enter the data as: April 1990 18-20,26-27; Apr 1990 18,19,20,26,27; 18-20,26-27 APRIL 90; or other zillion combinations. Clearly, I believe, an EA would be ideal under these conditions.
This article will attempt to explain how to develop an EA. But wait! With simple EA as the calendar, it can be difficult to debug the EA with the 4D environment. So, this article will also cover a 4D debugger emulator similar to Think Cs cdev and DA debugging tools for developing an EA, specifically the Calendar EA. Hence, the database developer can perform the majority of the debugging phase using Think Cs symbolic debugger.
Writing EAs are not really difficult, but documentation is rather skimpy on more advanced EAs other than their simple examples. There is a section describing how to write an EA in 4D 1.X manuals, and it is completely missing in v2.X manuals!! I suppose, the people at ACIUS want to keep writing EA a mystery to most database developers.
The only other documentation available can be found in ACIUS Technical Note #35 and MacTutor September 1988 issue. Armed with these information, I was able to write rather interesting EAs.
I used Think Cs Object classes to emulate EA and EPs, which has given me the ability to use the symbolic debugger. The object classes hierarchy are similar to MacApp other than the different names for the object classes. This helped me to use the Think Cs objects quickly, but there is still a substantial learning curve associated with Think Cs objects as well as MacApps objects. So you have to put in your time to learn how to use the object libraries.
External Area Events
The EA can receive two classes of events: standard Mac Events and 4D Events. The standard Mac events are nullEvent, updateEvt, mouseDown, and keyDown. These events are generated as one expects. The nullEvent is sent to EA whenever there is nothing to do and perform standard idling operations. The updateEvt event is sent to EA to update the rectangular area within the layout. The mouseDown event is sent to EA whenever the mouse is clicked inside the EAs rectangular area. And, the keyDown event is sent to the EA whenever there are keyboard inputs. More about keyDown event in selectReq event.
The initEvt 4D event informs the EA to be initialized. Normally, the EA will save its data handle in the eaData variable. I will discuss about this later in the External Area Protocol with External Procedures topic. This is the first event the EA will receive other than the drawReq event when opening a layout containing the EA.
The deInitEvt event informs the EA to release its memory allocation via the eaData handle. This is the last event the EA will receive before the layout is closed.
The selectReq event asks the EA if it wants to receive keyDown, activeNote, and deActivNote events. If the EA wants these events then it must reset the eaEvent->message to 101 value. This event always occurs after the initEvt event. Otherwise, the EA will not receive these events.
The cursorEvt event informs the EA that the cursor is inside the rectangular area of the EA. The EA may want to change the cursor into something else other than arrow cursor.
The activNote event informs the EA that it has been selected and the previous standard 4D field or another EA has been deselected.
The deActivNote event informs the EA that it has been deselected and selected another field or EA. This is opposite of the activNote event.
The scrollEvt event informs the EA that the current rectangular area has been scrolled to new position. The eaRect will contain a new location of the EA. Note: The EA should not update the contents of the rectangular area, but wait for update event to occur.
The drawReq event is a special event to inform the EA to draw inside the specified rectangular area in Design mode while editing the layouts. If the EA wants to perform its own drawing rather allowing the 4D to fill the EA with 0101010101 then it should reset the eaEvent->message to 102 value and do its own drawing. Note: The C4th class in the 4th Class.c source file will call the initEvt, updateEvt, and deInitEvt events to emulate the normal EA updating protocol.
The Edits menu events are sent to EA to perform its equivalent Undo, Cut, Copy, Paste, Clear, and Select All events.
There are several other events generated by 4D which I do not use, since it appears to be redundant. I call these events afterActivEvt, afterDeactivEvt, and afterIdleEvt. The afterActivEvt always occurs after the activNote event and the afterDeactivEvt always occurs after the deActivNote event. The afterIdleEvt always occurs during the activNote phase with the nullEvent. Hence, every nullEvent will have its associated afterIdleEvt during EA selection. Of course, these events are generated only if the selectReq event return value 101 in the eaEvent->message variable.
I suspect there are other 4D events though I did not detect any.
External Area Protocol with External Procedures
The EA has four arguments used to communicate with the 4D procedures and its EPs. Think C calling convention defined as follows
/* 1 */
pascal void
main(eaEvent,eaRect,eaName,eaData)
EventRecord *eaEvent;
Rect *eaRect;
char *eaName;
Handle *eaData;
The eaEvent variable contains the standard Mac and 4D event information as discussed earlier. The message variable may be modified for selectReq and drawReq events to 101 and 102 value respectively. Otherwise, the EA should examine the values within the event record like a normal application.
The eaRect variable contain the rectangular area of the EA within the layout to be displayed. The EA should make very few assumptions how to use the rectangular area coordinates. Since during different events, the origin of the rectangle area can move around! I will discuss more about this in Things You Cant Do with External Areas topic when using the rectangular area for drawing, mouse-clicks, etc.
The eaName variable is the name of the EA defined in the layout which is used to be passed around to EP in the layouts procedure code.
The eaData variable is a pointer containing the data handle which typically contains a data structure required by the EA for its operations. The important point here is that the eaData variable does not have to be a handle. It could be used as simple long word, a Ptr, or in my case an object pointer called C4th.
The EPs are used by the layouts procedures to communicate with the EA. The layouts procedures use the equivalent eaName variable name to be passed as the actual value of the eaDatas pointer. Then the EP will examine the contents of the eaDatas data structure and modify the other arguments in the EP.
Refer to the layouts procedure Calendar for additional details. The SetCalendar and GetCalendar EPs use the theCalendar variable which is the same name as the EAs eaName variable and contains the value of the eaData variable. The theCalendar variable is the name of the EA defined in the layout editor as shown in Figure 2. This way the association is made between the layouts procedure and the actual EA.
The EPs would need to receive the eaData value used by the EA to perform the necessary operations required by the layouts procedures. Note: There is a limit of 10 number arguments you can pass to the EP. Refer to ACIUS Technical Note #30.

Figure 2
Things You Cant Do with External Areas
There are few considerations you should take into account when developing EA. They are window pointers retrieved by GetPort ROM call, using SetOrigin, ClipRgn ROM calls, and CDEF controls.
GetPort: You need to be careful how the EA accesses the window pointers internal data structures retrieved by GetPort ROM call. During the updateEvt event, the window data structure is inconsistent because the portBits is pointing to off-screen bit map and other parts of the data structure seem to be in funny state, too.
SetOrigin: In my first attempt, I wanted to use the SetOrigin ROM call to normalize the external rectangle areas left and top position to be (0,0). This would simplify drawing without resorting to keeping track of your (left,top) and (right,bottom) positions. Otherwise, the EA would be required to keep track of the width and height of the rectangle area. However, between updateEvt and mouseDown events tends to messes-up whenever the EA wants to draw into the rectangular area during mouseDown events. Also, it works OK in input layout but screws up in output layout. Nothing is perfect!
ClipRgn: This call will not work for drawReq event while it will work under all other events. In the Design mode, the layouts EA will be strangely missing while the layouts work OK in User mode. Again, I wanted to use the ClipRgn ROM call to suppress any slopping drawing outside of the EA, but I could not use this feature either.
CDEF controls: It sort-of works in input layouts. If the layout window want to scroll, it wont always re-position the controls properly during scrolling operations. I tried several convoluted schemes and none of them work consistently, but you can use the controls if the input layout does not have any scroll bars.
It wont work in the output layout at all! 4D somehow gets into an infinite procedure loop and causes the layouts procedure to terminate.
Installing External Area and Procedures
Creating an EA using Think C is quite easy. The configuration in Figure 3 shows the necessary settings. The important point that is not so obvious is that the File Type field must be APPL even though it is not a standard Mac application. This is required by 4D External Mover application to select file containing the EAs and EPs.
The resource Type must be CODE. And again, this is required by 4D External Mover application.
The Multi-Segment check-box must be checked even though it is a single-segment resource. For some reason, Think C wants this checked using objects extensions.

Figure 3
To install the EAs and EPs then use the 4D External Mover application. The application is similar to Font/DA Mover application. However, it is not very clear how to install your EAs and EPs for the first time.
I usually create a file called Proc.Ext used by the Calendar database. After creating a new file, select the Transfer... button and it will display a dialog as shown in Figure 4. Since I used ID = 2, I must enter same value 2 into the Segment Number field. Also, change the Procedure Offset to 0, since Think C code resources start at location 0. The dialog always default to 4 bytes offset from the beginning of the code resource containing the EA or EP.
After entering the necessary values in their respective fields, select the <<Left or Right>> buttons containing the direction of the file opened to be installed with the new EAs and EPs.

Figure 4
When installing the EAs, do not add any parameters as shown in Figure 5. However, the EPs needs the parameters entered as shown in Figure 6. In this case, the SetCalendar EP contains four arguments where the first argument is theCalendar variable that is mapped into the eaData variable as discussed earlier.

Figure 5

Figure 6
Source File Description
The Calendar layouts procedure is rather simple. It calls the SetCalendar EP during its Before phase, and the After phase will call the GetCalendar EP to extract the current calendar settings in the EA defined by the theCalendar variable. This is all there is to it in the layouts procedure. It cant get any simpler!
The 4D debugger emulation comprises of three files: 4thDefs.h, 4thDebugger.h, and 4thDebugger.c. The source file uses the Think Cs Objects to build simple application to simulate the 4D EA and controls the EPs communications to the EA.
The C4th class is defined in the 4th Class.h and 4th Class.c source files. New EAs can override this class to build new EAs namely the CCalendar class.
The CCalendar class overrides the C4th class to perform the necessary operations for the calendars EA. The Calendar.h, Calendar.c, SetCalendar.c, GetCalendar.c are sources files to the EA and EPs respectively.
Wrap Up
Using the 4thDebugger application to simulate the EA can substantially reduce debugging time developing EAs. I had been using this debugging technique since last year and it has made a major difference meeting tight dead-line schedules. I want to extend my thanks to the people at Hughes Aircraft Company insisting developing EAs and EPs to extend the 4D databases.
Procedure : Calendar
Author : Alexander S. Colwell
Copyright © 1990
Description : This procedure will display the
CalendarArea external area and use
SetCalendar and GetCalendar
external procedure to commnicate the
month, year, and days fields to the
external area.
Case of
: (Before)
If ([Calendar]month=0)
[Calendar]month:=Month of(Current date)
End if
If ([Calendar]year=0)
[Calendar]year:=Year of(Current date)
End if
theMonth:=[Calendar]month
theYear:=[Calendar]year
theDays:=[Calendar]days
SetCalendar(theCalendar;theMonth;theYear;theDays)
: (During)
: (After)
GetCalendar(theCalendar;theMonth;theYear;theDays)
[Calendar]month:=theMonth
[Calendar]year:=theYear
[Calendar]days:=theDays
End case
/*
* Include - 4thDefs.h
* Author - Alexander S. Colwell
* Copyright © 1990
* Description - This 4th Dimensions external area
* event constants.
*/
#ifndef _4thDefs_
#define _4thDefs_
/* 4th DB ext area events*/
#define initEvt 16 /* Init event */
#define deInitEvt 17 /* Close event */
#define cursorEvt 18 /* Cursor event */
#define selectReq 20 /* Selection request evt */
#define activNote 21 /* Activate note event */
#define deActivNote 22 /* Deactivate note event */
#define scrollEvt 25 /* Scroll event */
#define drawReq 26 /* Draw request event */
#define undoEvt 30 /* Edits Undo event */
#define cutEvt 31 /* Edits Cut event */
#define copyEvt 32 /* Edits Copy event */
#define pasteEvt 33 /* Edits Paste event */
#define clearEvt 34 /* Edits Clear event */
#define selectAllEvt 35 /* Edits Select All */
#define afterActivEvt 40 /* After ActivNote evt */
#define afterDeactivEvt 41 /* After DeactivNote */
#define activeIdleEvt 43 /* Selection idle event */
#endif
/*
* Source - 4th Debugger.h
* Author - Alexander S. Colwell
* Copyright © 1990
* Description - This 4th Dimensions external area
* debugger include file.
*/
#ifndef _4thDebugger_ /* Has been include yet? */
#define _4thDebugger_ /* Mark it been included */
#include <Global.h> /* Global variable defs */
#include <CApplication.h> /* Appl object defs */
#include <Commands.h> /* Command object defs */
#include <CBartender.h> /* Menu object defs */
#include <CDecorator.h> /* Wind display obj defs */
#include <CDesktop.h> /* Desktop layer obj defs*/
#include <CDocument.h> /* Document object defs */
#include <CEditText.h> /* Text edit object defs */
#include <CScrollPane.h> /* Scroll pane obj defs */
#include 4th Class.h /* 4th Ext Area obj defs */
/* Min/Max defs */
#define maxDbgChars 8000 /* Max # in debug window */
/* Window/Dialog ID defs */
#define eaWIND 500 /* External Area WIND */
#define dbgWIND 501 /* Debugger WIND template*/
#define atDLOG 500 /* About This... DLOG */
/* External area commands*/
#define eaOpen 1024 /* Open Ext Area cmd */
#define eaClose 1025 /* Close Ext Area cmd */
#define ep1 1026 /* Run Ext Proc #1 cmd */
#define ep2 1027 /* Run Ext Proc #2 cmd */
#define ep3 1028 /* Run Ext Proc #3 cmd */
#define ep4 1029 /* Run Ext Proc #4 cmd */
#define ep5 1030 /* Run Ext Proc #5 cmd */
#define ep6 1031 /* Run Ext Proc #6 cmd */
#define ep7 1032 /* Run Ext Proc #7 cmd */
#define ep8 1033 /* Run Ext Proc #8 cmd */
#define ep9 1034 /* Run Ext Proc #9 cmd */
#define eaSelectAll 1035 /* Edit Select All cmd */
#define eaDebugger 1036 /* Edit Hide/Show cmd */
struct CEAPane : CPanorama { /* Ext area pane object */
/* Variable instances */
Rect eaRect; /* External rect area */
Rect eaSRect; /* Scrolled ext rect area*/
C4th *eaObject; /* External 4th obj hdl */
Point lastWhere; /* Last mouse position */
/* Method instances */
void Dispose(void); /* Dispose ext area */
void UpdateMenus(void); /* Update menu items */
void AdjustToEnclosure(Rect *);/* Adjust to enclosure*/
void AdjustCursor(Point, RgnHandle);/* Adjust cursor */
void Dawdle(long *); /* Dawdle (Idle) */
void Draw(Rect *); /* Draw */
void Scroll(short,short,Boolean);/* Scroll */
void DoClick(Point,short,long);/* Mouse down */
void DoKeyDown(char,Byte,EventRecord *);/* Key-down */
void DoAutoKey(char,Byte,EventRecord *);/* Key-down */
void Activate(void); /* Activate pane */
void Deactivate(void); /* Deactivate pane */
void DoCommand(long); /* Command */
void DoSendEvent(short); /* Send event */
void DoExtEvent(EventRecord *);/* Execute ext event */
void DoExtProc(short); /* Execute ext procedure */
short DoGetModifiers(void); /* Get current modifiers */
};
struct CDbgDoc : CDocument { /* Debugger (bogus) obj */
/* Method instances */
Boolean Close(Boolean); /* Close */
};
struct CDbgPane : CEditText {/* Text edit pane object */
/* Variable instances */
short maxChars; /* Max # of characters */
/* Method instances */
void DoPrint(char *, ...); /* Do print output stream*/
};
/* 4th Debugger classes */
struct C4thDbgApp : CApplication {/* Application obj */
/* Variable instances */
CDocument *eaDoc; /* Ext Area window doc */
CDbgDoc *dbgDoc; /* Debugger window doc */
Str255 eaName; /* Ext area name */
Rect eaIRect; /* Ext initial rect area */
ProcPtr eaProc[10]; /* Ext procedure table */
/* Methods */
void IApplication(short,Size,Size);/* Initialization */
void InitExtArea(void); /* Init external area */
void InstallExtProc(short,ProcPtr);/* Install proc */
void SetExtArea(short,short,short,short);
void SetExtName(char *); /* Set external name */
void CreateDocument(void); /* Create debugger window*/
void CreateExtArea(void); /* Create ext area window*/
void DoCommand(long); /* Command */
void UpdateMenus(void); /* Update menu items */
void AboutThis(void); /* About this dialog */
};
/* Define external refs */
extern C4thDbgApp *gApplication;/* Application object*/
extern CDecorator *gDecorator;/* Window display obj */
extern CDesktop *gDesktop;/* Desktop view layer obj*/
extern CBartender *gBartender;/* Menu handler object */
#endif
/*
* Source - 4th Debugger.c
* Author - Alexander S. Colwell
* Copyright © 1990
* Description - This application will assist debugging
* 4th Dimensions external area and
* related external procedures.
*/
#define DbgExtArea /*Mark debugging ext area*/
#include 4th Debugger.h /* 4th Dim Debugger defs */
#include 4th Class.h /* 4th Ext Area obj defs */
#include <StdIO.h> /* Std I/O defs */
#include stdarg.h /* Std Variable Args defs*/
#include <string.h> /* String defs */
pascal void C4thMain(); /* Define ext procedures */
void main()
{
gApplication = new(C4thDbgApp);/* Create appl object*/
gApplication->IApplication(4,4096L,2048L);/* Init it*/
gApplication->Run(); /* Startup appl execution*/
gApplication->Exit(); /* Return to da Finder */
}
void C4thDbgApp::IApplication(short extraMasters,
Size aRainyDayFund,
Size aCreditLimit)
{
register short i; /* Working index */
eaDoc = NULL; /* Mark no ext area wind */
eaIRect.left = eaIRect.top =
eaIRect.right = eaIRect.bottom = 0;
for(i = 0; i < 10; i++) /* Init ext procedures */
eaProc[i] = NULL; /* Invalid ext proc ptr */
eaName[0] = 0; /* Null ext name string */
/* Continue init */
inherited::IApplication(extraMasters,
aRainyDayFund,aCreditLimit);
InitExtArea(); /* Init external area */
}
void C4thDbgApp::InstallExtProc(short epIdx,
ProcPtr epPtr)
{
short idx = epIdx - ep1; /* Working ext proc index*/
if (idx >= 0 && idx < 10) /* Check if index valid */
eaProc[idx] = epPtr; /* Install new proc ptr */
}
void C4thDbgApp::SetExtArea(short l, short t,
short r, short b)
{
eaIRect.left = l; /* Set external rect area*/
eaIRect.top = t;
eaIRect.right = r;
eaIRect.bottom = b;
}
void C4thDbgApp::SetExtName(char *name)
{
register long len; /* Working string length */
BlockMove(name,eaName, /* Copy da string */
len = min((unsigned char)(*name) + 1, sizeof(eaName)));
eaName[0] = len; /* Reset to max str len */
}
void C4thDbgApp::CreateDocument(void)
{
register CScrollPane *theScrollPane;
register CDbgPane *theMainPane;
Rect margin;/* Working margin area */
dbgDoc = new(CDbgDoc); /* Create new doc object */
dbgDoc->IDocument(this,TRUE);/* Do normal init */
dbgDoc->itsWindow = new(CWindow);/* Create wind obj */
dbgDoc->itsWindow->IWindow(dbgWIND,FALSE,
gDesktop,dbgDoc);
theScrollPane = new(CScrollPane);/* Make scroll obj */
theScrollPane->IScrollPane(dbgDoc->itsWindow,dbgDoc,
10,10,0,0,sizELASTIC,sizELASTIC,TRUE,TRUE,TRUE);
theScrollPane->FitToEnclFrame(TRUE,TRUE);
theMainPane = new(CDbgPane);
dbgDoc->itsMainPane = theMainPane;
dbgDoc->itsGopher = theMainPane;
theMainPane->IEditText(theScrollPane,dbgDoc,
1,1,0,0,sizELASTIC,sizELASTIC,432);
theMainPane->FitToEnclosure(TRUE,TRUE);
SetRect(&margin,2,2,-2,-2);
theMainPane->ChangeSize(&margin,FALSE);
theMainPane->SetFontNumber(monaco);
theMainPane->SetFontSize(9);
(*theMainPane->macTE)->crOnly = -1;
theMainPane->maxChars = maxDbgChars;
theScrollPane->InstallPanorama(theMainPane);
dbgDoc->itsWindow->Select();/* Select our window */
}
void C4thDbgApp::CreateExtArea(void)
{
register CScrollPane *theScrollPane;
register CEAPane *theMainPane;
Rect wRect;/* Working rect area */
EventRecord eaEvent;/* Working event hdlr */
eaDoc = new(CDocument); /* Make 4th ext area doc */
eaDoc->IDocument(this,TRUE);/* Do normal init */
eaDoc->itsWindow = new(CWindow);/* Create wind obj */
eaDoc->itsWindow->IWindow(eaWIND,FALSE, gDesktop,eaDoc);
/* Try and fit ext area within window*/
wRect = eaDoc->itsWindow->macPort->portRect;
wRect.right = min(max(wRect.right,
wRect.left+max(0,eaIRect.left)+
eaIRect.right - eaIRect.left + 32),
screenBits.bounds.right -
screenBits.bounds.left - 16 +
eaDoc->itsWindow->macPort->portBits.bounds.left);
wRect.bottom = min(max(wRect.bottom,
wRect.top + max(0,eaIRect.top)+
eaIRect.bottom-eaIRect.top+32),
screenBits.bounds.bottom -
screenBits.bounds.top - 16 +
eaDoc->itsWindow->macPort->portBits.bounds.top);
eaDoc->itsWindow->ChangeSize(wRect.right - wRect.left,
wRect.bottom-wRect.top);
theScrollPane = new(CScrollPane);/* Make scroll obj */
theScrollPane->IScrollPane(eaDoc->itsWindow,eaDoc,
10,10,0,0,sizELASTIC,sizELASTIC,TRUE,TRUE,TRUE);
theScrollPane->FitToEnclFrame(TRUE,TRUE);
theScrollPane->SetSteps(16,16);
theMainPane = new(CEAPane); /* Create pane object */
eaDoc->itsMainPane = theMainPane;
eaDoc->itsGopher = theMainPane;
wRect = eaIRect; /* Set ext rect area */
/* Init ext areas pane */
theMainPane->IPanorama(theScrollPane,eaDoc,
wRect.right - wRect.left + abs(wRect.left) + 16,
wRect.bottom - wRect.top + abs(wRect.top) + 16,
wRect.left,wRect.top,sizFIXEDSTICKY,sizFIXEDSTICKY);
theMainPane->FitToEnclosure(TRUE,TRUE);
theMainPane->SetWantsClicks(TRUE);
theScrollPane->InstallPanorama(theMainPane);
eaDoc->itsWindow->Select();/* Select our window */
theMainPane->eaRect = eaIRect;/* Set rect area */
theMainPane->eaSRect = eaIRect;
theMainPane->eaObject = NULL;/* Set no ext area obj */
eaEvent.what = initEvt; /* Initialize event rec */
eaEvent.message = (long)(theMainPane->macPort);
eaEvent.when = TickCount();
eaEvent.where.h = eaEvent.where.v = 0;
eaEvent.modifiers = 0;
theMainPane->DoExtEvent(&eaEvent);/* Do ext area evt*/
}
void C4thDbgApp::DoCommand(long theCommand)
{
switch(theCommand) { /* Process command */
case cmdAbout: /* About This dialog */
AboutThis(); break;
case eaOpen: /* Open external area */
CreateExtArea(); break;
case eaDebugger: /* Hide/Show Debugger */
dbgDoc->itsWindow->ShowOrHide
(!dbgDoc->itsWindow->IsVisible());
break;
default: /* Dont know this msg */
inherited::DoCommand(theCommand);/* Cont handler */
}
}
void C4thDbgApp::UpdateMenus(void)
{
Str255 wStr; /* Working string */
inherited::UpdateMenus(); /* Update other items */
if (!eaDoc) /* Check if ext not open */
gBartender->EnableCmd(eaOpen);/* Enable open ext */
gBartender->EnableCmd(eaDebugger);/*Enable Hide/Show*/
/* Setup Hide/Show item */
GetIndString(wStr,eaDebugger,
(dbgDoc->itsWindow->IsVisible()?1:2));
gBartender->SetCmdText(eaDebugger,wStr);
}
void C4thDbgApp::AboutThis(void)
{
DialogPtr dPtr; /* Working dialog pointer*/
Point wPt; /* Working mouse point */
/* DisplayAbout This... */
if (dPtr = GetNewDialog(atDLOG,(Ptr)(NULL),-1L)) {
SetPort(dPtr); /* Set to this dlg port */
DrawDialog(dPtr); /* Draw the items */
while(TRUE) /* Do until time to quit */
if (Button()) { /* Check if mouse is down*/
GetMouse(&wPt); /* Get cur mse position */
if (PtInRect(wPt,&dPtr->portRect))/*Inside wind? */
break; /* Lets break-out now!! */
}
DisposDialog(dPtr); /* Kill the dialog!!!! */
FlushEvents(mDownMask|mUpMask,0);/* Flush da events*/
}
}
void CEAPane::Dispose(void)
{
DoSendEvent(deInitEvt); /* Do external area event*/
gApplication->eaDoc = NULL;/* Mark no ext area wind */
inherited::Dispose(); /* Lets dispose it now */
}
void CEAPane::UpdateMenus(void)
{
inherited::UpdateMenus(); /* Update other items */
gBartender->EnableCmd(eaClose);/* Enable the items */
gBartender->EnableCmd(ep1);
gBartender->EnableCmd(ep2);
gBartender->EnableCmd(ep3);
gBartender->EnableCmd(ep4);
gBartender->EnableCmd(ep5);
gBartender->EnableCmd(ep6);
gBartender->EnableCmd(ep7);
gBartender->EnableCmd(ep8);
gBartender->EnableCmd(ep9);
gBartender->EnableCmd(cmdUndo);
gBartender->EnableCmd(cmdCut);
gBartender->EnableCmd(cmdCopy);
gBartender->EnableCmd(cmdPaste);
gBartender->EnableCmd(cmdClear);
gBartender->EnableCmd(eaSelectAll);
}
void CEAPane::AdjustToEnclosure(Rect *deltaEncl)
{
inherited::AdjustToEnclosure(deltaEncl);/* Adjust it*/
FitToEnclosure(TRUE,TRUE); /* Re-adjust to window */
}
void CEAPane::AdjustCursor(Point where,
RgnHandle mouseRgn)
{
EventRecord eaEvent; /* Working event handler */
if (!PtInRect(where,&eaSRect))/* Inside ext area? */
inherited::AdjustCursor(where,mouseRgn);/*Adjust it*/
else { /* Nope, its in ext area*/
eaEvent.what = cursorEvt; /* Initialize evt record */
eaEvent.message = (long)(macPort);
eaEvent.when = TickCount();
eaEvent.where = where;
eaEvent.modifiers = DoGetModifiers();
DoExtEvent(&eaEvent); /* Do external area event*/
}
}
void CEAPane::Dawdle(long *maxSleep)
{
inherited::Dawdle(maxSleep);/* Do any other stuff */
DoSendEvent(nullEvent); /* Do external area event*/
*maxSleep = 0L; /* Do it fast as possible*/
}
void CEAPane::Draw(Rect *area)
{
Rect wRect; /* Working rect area */
wRect = *area; /* Set clipping area */
FillRect(&wRect,ltGray); /* Draw into unused area */
DoSendEvent(updateEvt); /* Do external area event*/
}
void CEAPane::Scroll(short hDelta, short vDelta,
Boolean reDraw)
{
OffsetRect(&eaSRect,-hDelta,-vDelta);/* Offset it */
DoSendEvent(scrollEvt); /* Do external area event*/
inherited::Scroll(hDelta,vDelta,reDraw);/* Do it */
}
void CEAPane::DoClick(Point hitPt, short modifierKeys,
long when)
{
EventRecord eaEvent; /* Working event handler */
eaEvent.what = mouseDown; /* Initialize evt record */
eaEvent.message = (long)(macPort);
eaEvent.when = when;
eaEvent.where = hitPt;
eaEvent.modifiers = modifierKeys;
DoExtEvent(&eaEvent); /* Do external area event*/
}
void CEAPane::DoKeyDown(char theChar, Byte keyCode,
EventRecord *macEvent)
{
EventRecord eaEvent; /* Working event handler */
if (eaObject) { /* Check if has C4th obj */
if (eaObject->keyBoardEvents) {/* Wants key events?*/
eaEvent.what = keyDown; /* Initialize evt record */
eaEvent.message = theChar | (keyCode << 8);
eaEvent.when = macEvent->when;
eaEvent.where = lastWhere;
eaEvent.modifiers = macEvent->modifiers;
DoExtEvent(&eaEvent); /* Do ext area event */
}
}
}
void CEAPane::DoAutoKey(char theChar, Byte keyCode,
EventRecord *macEvent)
{
DoKeyDown(theChar,keyCode,macEvent);/* Pass it on! */
}
void CEAPane::Activate(void)
{
inherited::Activate(); /* Do other stuff first */
if (eaObject) /* Check if has C4th obj */
if (eaObject->keyBoardEvents)/* Want activate evts?*/
DoSendEvent(activNote); /* Send message */
}
void CEAPane::Deactivate(void)
{
if (gApplication->eaDoc) /* Check if not quitting */
if (eaObject) /* Check if has C4th obj */
if (eaObject->keyBoardEvents)/* Want deactive evts*/
DoSendEvent(deActivNote);/* Send message */
inherited::Deactivate(); /* Do other stuff first */
}
void CEAPane::DoCommand(long theCommand)
{
switch(theCommand) { /* Process command */
case cmdUndo: /* Edit Undo event */
DoSendEvent(undoEvt); break;
case cmdCut: /* Edit Cut event */
DoSendEvent(cutEvt); break;
case cmdCopy: /* Edit Copy event */
DoSendEvent(copyEvt); break;
case cmdPaste: /* Edit Paste event */
DoSendEvent(pasteEvt); break;
case cmdClear: /* Edit Clear event */
DoSendEvent(clearEvt); break;
case eaSelectAll: /* Edit Select All evt */
DoSendEvent(selectAllEvt); break;
case eaClose: /* Close External Area */
inherited::DoCommand(cmdClose); break;
case ep1: /* Execute Ext Proc # 1 */
case ep2: /* Execute Ext Proc # 2 */
case ep3: /* Execute Ext Proc # 3 */
case ep4: /* Execute Ext Proc # 4 */
case ep5: /* Execute Ext Proc # 5 */
case ep6: /* Execute Ext Proc # 6 */
case ep7: /* Execute Ext Proc # 7 */
case ep8: /* Execute Ext Proc # 8 */
case ep9: /* Execute Ext Proc # 9 */
DoExtProc(theCommand - ep1); break;
default: /* None of these, inherit*/
inherited::DoCommand(theCommand);/*Cont processing*/
}
}
void CEAPane::DoSendEvent(short theCommand)
{
EventRecord eaEvent; /* Working event handler */
WindowPtr wPtr = eaObject->wPtr;/* Working wind ptr */
if (printing) /* Check if printing */
GetPort(&wPtr); /* Get current print port*/
eaEvent.what = theCommand; /* Initialize evt record */
eaEvent.message = (long)(wPtr);
eaEvent.when = TickCount();
eaEvent.where = lastWhere;
eaEvent.modifiers = DoGetModifiers();
DoExtEvent(&eaEvent); /* Do external area event*/
}
void CEAPane::DoExtEvent(EventRecord *theEvent)
{
C4th *wObject; /* Working ext area obj */
Str255 wName; /* Working ext area name */
Rect wRect; /* Working ext rect area */
Prepare(); /* Prepare for drawing */
lastWhere = theEvent->where;/* Save last where pt */
wRect = eaRect; /* Set external rect area*/
wObject = eaObject; /* Set ext area obj hdl */
BlockMove(gApplication->eaName,wName,/* Copy name */
(long)(gApplication->eaName[0]));
C4thMain(theEvent,&wRect,wName,&wObject);/* Do it */
eaObject = wObject; /* Reset ext area obj hdl*/
}
void CEAPane::DoExtProc(short epIdx)
{
C4th *wObject; /* Working 4th object */
if (gApplication->eaProc[epIdx]) {/* Check if valid */
wObject = eaObject; /* Copy ext area object */
(*gApplication->eaProc[epIdx])(&wObject);/* Pass it*/
eaObject = wObject; /* Resave ext area object*/
}
}
short CEAPane::DoGetModifiers(void)
{
KeyMap keyMap; /* Working key map */
register short modifiers = 0;/* Working modifiers */
GetKeys(&keyMap); /* Get the key map status*/
if (keyMap.Key[1] & 0x00000001L)/* Check if shift */
modifiers |= shiftKey; /* Set shift modifier */
if (keyMap.Key[1] & 0x00000004L)/* Check if option*/
modifiers |= optionKey; /* Set option modifier */
if (keyMap.Key[1] & 0x00008000L)/* Check if cmd */
modifiers |= cmdKey; /* Set cmd modifier */
if (keyMap.Key[1] & 0x00000002L)/* Check if caps */
modifiers |= alphaLock; /* Set caps modifier */
if (!Button()) /* Check if mouse is up */
modifiers |= btnState; /* Set button state */
return(modifiers); /* Return keys modifiers*/
}
Boolean CDbgDoc::Close(Boolean quitting)
{
register Boolean status = FALSE;/* Closing status */
if (quitting) { /* Check if quitting */
itsWindow->ShowOrHide(TRUE);/* Show it before close*/
status = inherited::Close(quitting);/* Cont closing*/
}
else /* Nope, hiding da window*/
itsWindow->ShowOrHide(FALSE);/* Lets hide it only */
return(status); /* Return status flag */
}
void CDbgPane::DoPrint(fmt,args)
char *fmt;
va_list args;
{
register short i; /* Working index */
char buffer[512];/* Working output buffer */
register long bufferLen; /* Working output length */
vsprintf(buffer,fmt,&args);/* Copy into output buf */
bufferLen = strlen(buffer);/* Get output buffer len */
for(i = 0; i < bufferLen; i++)/* Cnvt special chars */
switch(buffer[i]) { /* Process this character*/
case \t: buffer[i] = ; break;
case \n: buffer[i] = \r; break;
}
Prepare(); /* Prepare for drawing */
/* Buffer too big? */
if ((*macTE)->teLength + bufferLen > maxChars)
for(i = 0; (*macTE)->nLines; i++)
if ((*macTE)->lineStarts[i] > bufferLen) {
TESetSelect(0L,(long)((*macTE)->lineStarts[i] - 1),
macTE);
TEDelete(macTE);
}
/* Reset to end-of-buffer*/
TESetSelect((long)((*macTE)->teLength),
(long)((*macTE)->teLength),macTE);
TEInsert(buffer,bufferLen,macTE);/* Insert buffer */
AdjustBounds(); /* Re-adjust boundaries */
ScrollToSelection(); /* Scroll to cursor */
}
/*
* Include - 4th Class.h
* Author - Alexander S. Colwell
* Copyright © 1990
*/
#ifndef _4thClass_ /* Has been include yet? */
#define _4thClass_ /* Mark it been included */
/* Compilation parameters*/
#define ExtArea /* Mark debug ext area */
#ifndef _4thDefs_ /* Has been include yet? */
#include 4thDefs.h /* Include 4th Dim defs */
#endif
#include <oops.h> /* OOPS defs */
#include <Color.h> /* Color defs */
#ifndef DbgExtArea /* Debugging ext area? */
#ifdef ExtArea /* Is real external area?*/
#include <SetupA4.h> /* Setup Register A4 defs*/
#define DbgPrint DummyProc /* Dummy procedure */
#else /* Nope, weve debugging */
#define main C4thMain /* Re-define main entry*/
#define RememberA4() DummyProc()
#define RememberA0() DummyProc()
#define SetUpA4() DummyProc()
#define RestoreA4() DummyProc()
#define DbgPrint ((CDbgPane *) \
(gApplication->dbgDoc->itsMainPane))->DoPrint
#endif
#endif
/* Trap definitions */
#define SysEnvironsTrap 0xa090/* System Env trap */
#define GetDeviceListTrap 0xaa29/* Graphics Dev trap */
#define UnknownTrap 0xa89f /* Unknown trap instr */
/* Mac ROM IDs */
#define macIIROM 0x0078 /* Mac II ROM ID */
#define macSEROM 0x0076 /* Mac SE ROM ID */
#define macPlusROM 0x0075 /* Mac Plus ROM ID */
#define macROM 0x0069 /* Original Mac ROM ID */
extern RGBColor HiliteRGB : 0xda0;/* Hilite RGB color */
#ifndef NULL /* NULL is not defined?*/
#define NULL (0L) /* Define NULL constant*/
#endif
/* Macro functions */
#define abs(a) (a<0?-a:a) /* Absolute value */
#define min(a,b) (a<b?a:b) /* Minimum value */
#define max(a,b) (a<b?b:a) /* Maximum value */
struct C4th : indirect { /* 4th obj data structure*/
/* Variable instances */
WindowPtr wPtr; /* Ext Area window ptr */
short layout; /* Layout flag indicator */
short dirty; /* Dirty flag indicator */
short active; /* Active flag indicator */
short keyBoardEvents; /* Using keyboard events */
char *name; /* Ext area name str ptr */
EventRecord *event; /* Ext area event pointer*/
Rect drawArea; /* Ext drawing area */
Rect prevArea; /* Prevs ext drawing area*/
short width; /* Ext area width */
short height; /* Ext area height */
/* System variable defs */
SysEnvRec sysEnv; /* System configuration */
short originalMac; /* Using 128K/512K Macs */
short hasGraphicDevices;/* Using graphic devices */
/* Working variable defs */
PenState savePenState; /* Save cur pen states */
short saveFont; /* Save cur fonts ID */
short saveSize; /* Save cur fonts size */
Style saveStyle; /* Save cur fonts style */
short saveMode; /* Save cur fonts mode */
RgnHandle tmpRgn; /* Temporary region */
/* Method instances */
void Message(void); /* Dispatch message */
void IExtArea(short); /* Initialization message*/
void Close(void); /* Close message */
void Idle(void); /* Idle message */
void Cursor(Point); /* Cursor message */
void Select(void); /* Activate message */
void Deselect(void); /* Deactivate message */
void Scroll(void); /* Scroll message */
void Draw(void); /* Draw message */
void DoClick(Point,short,long);/* Mouse message */
void DoKeyDown(char,Byte);/* Key message */
void DoUndo(void); /* Edit Undo message */
void DoCut(void); /* Edit Cut message */
void DoCopy(void); /* Edit Copy message */
void DoPaste(void); /* Edit Paste message */
void DoClear(void); /* Edit Clear message */
void DoSelectAll(void); /* Edit Select All msg */
void SaveStates(void); /* Save state for drawing*/
void RestoreStates(void); /* Restore drawing */
short TrackMouse(Point,RgnHandle);/* Track da mouse */
short UsingColor(void); /* Check if using color */
};
#endif
/*
* Source - 4th Class.c
* Author - Alexander S. Colwell
* Copyright © 1990
* Description - This 4th Dimensions External Area
* class.
*/
#include 4th Class.h /* 4th Ext Area defs */
C4th *New(void); /* New func proto-type */
pascal void main(eaEvent, eaRect, eaName, eaObject)
EventRecord *eaEvent; /* Ext Area event ptr */
Rect *eaRect; /* Ext Rect area pointer */
char *eaName; /* Ext Area name pointer */
C4th **eaObject; /* Ext Area object */
{
WindowPtr curWPtr; /* Working cur window ptr*/
C4th *fake; /* Working fake ext area */
RememberA0(); /* Save reg A0 for A4 */
SetUpA4(); /* Setup register A4 */
if (eaEvent->what == drawReq) {/* Layout draw? */
eaEvent->message = 102; /* Lets draw ext area */
fake = New(); /* Create fake objec */
GetPort(&curWPtr); /* Get cur window pointer*/
fake->layout = TRUE; /* Set layou stat */
fake->wPtr = curWPtr; /* Save window pointe */
fake->name = eaName; /* Save ext area name */
fake->event = eaEvent; /* Save event record ptr */
fake->drawArea = *eaRect; /* Setup drawing area */
fake->prevArea = *eaRect; /* Setup previous area */
fake->width = eaRect->right - eaRect->left;
fake->height = eaRect->bottom - eaRect->top;
fake->tmpRgn = NULL; /* Invalidate region */
eaEvent->what = initEvt; /* Fake init event */
fake->Message(); /* Handle message */
eaEvent->what = updateEvt;/* Fake update event */
fake->Message(); /* Handle message */
eaEvent->what = deInitEvt;/* Fake deinit event */
fake->Message(); /* Handle message */
SetPort(curWPtr); /* Restore prev wind port*/
}
else { /* Do real-thing */
/* Check if initialized */
if (eaEvent->what == initEvt) {
*eaObject = New(); /* Create new object */
(*eaObject)->layout = FALSE;/* Not layout area */
(*eaObject)->tmpRgn = NULL;/* Invalidate region*/
(*eaObject)->wPtr = NULL;/* Invalid window ptr */
(*eaObject)->prevArea = *eaRect;/* Set prev rec*/
}
if (*eaObject) { /* Check if got object */
GetPort(&curWPtr); /* Get current window ptr*/
(*eaObject)->wPtr = curWPtr;/* Save window ptr */
(*eaObject)->name = eaName;/* Save ext name */
(*eaObject)->event = eaEvent;/* Save event ptr */
(*eaObject)->drawArea = *eaRect;/*Set draw area*/
(*eaObject)->width = eaRect->right-eaRect->left;
(*eaObject)->height = eaRect->bottom-eaRect->top;
(*eaObject)->Message();/* Handle message */
SetPort(curWPtr); /* Restore prevs window port */
}
}
RestoreA4(); /* Restore register A4 */
}
void C4th::Message(void)
{
register short what; /* Working event type */
Rect wRect; /* Working rect area */
SaveStates(); /* Save state for drawing*/
switch(what = event->what) {/* Process event message*/
case nullEvent: /* Null event handler */
Idle(); break;
case initEvt: /* Init event */
IExtArea(FALSE); break;
case deInitEvt: /* Close event */
Close(); break;
case cursorEvt: /* Cursor event */
Cursor(event->where); break;
case selectReq: /* Selection request evt */
if (keyBoardEvents) /*Wnt keyboard selection?*/
event->message = 101; /* Set keyboard request */
break;
case activNote: /* Activate select evt */
Select(); break;
case deActivNote: /* Deactivate select evt */
Deselect(); break;
case scrollEvt: /* Scroll event */
Scroll(); break;
case undoEvt: /* Edits Undo event */
DoUndo(); break;
case cutEvt: /* Edits Cut event */
DoCut(); break;
case copyEvt: /* Edits Copy event */
DoCopy(); break;
case pasteEvt: /* Edits Paste event */
DoPaste(); break;
case clearEvt: /* Edits Clear event */
DoClear(); break;
case selectAllEvt: /*Edits Select All evt*/
DoSelectAll(); break;
case afterActivEvt: /* After ActivNote evt */
break;
case afterDeactivEvt: /*After DeactivNote evt*/
break;
case activeIdleEvt: /* Selection idle event */
break;
case updateEvt: /* Update external area */
wRect = drawArea; /* Set area to erase */
EraseRect(&wRect); /* Clear it now */
Draw(); /* Do Draw method */
break;
case mouseDown: /* Mouse down in ext area*/
DoClick(event->where,event->modifiers,event->when);
break;
case keyDown: /* Key down event */
case autoKey: /* Auto-key down event */
DoKeyDown(event->message & charCodeMask,
(event->message & keyCodeMask) >> 8);
break;
default: /* Dont know this event */
break;
}
if (what != deInitEvt) /* Check if not closing */
RestoreStates(); /* Restore drawing stuff */
}
void C4th::IExtArea(short getKeyBoard)
{
short rom; /* Working ROM id */
short machine; /* Working Mac id */
register short canDoIt; /* Working can do it flag*/
SysEnvRec wSysEnv; /* Working system config */
dirty = FALSE; /* Mark ext not dirty */
active = FALSE; /* Mark ext not active */
keyBoardEvents = getKeyBoard;/* Get keyboard events */
tmpRgn = NewRgn(); /* Temporary region */
originalMac = FALSE; /* Not using 128K/512K */
hasGraphicDevices = FALSE; /* Has no graphic devices*/
sysEnv.environsVersion = 0;/* Bogus system config n */
sysEnv.machineType = 0;
sysEnv.systemVersion = 0;
sysEnv.processor = 0;
sysEnv.hasFPU = FALSE;
sysEnv.hasColorQD = FALSE;
sysEnv.keyBoardType = 0;
sysEnv.atDrvrVersNum = 0;
sysEnv.sysVRefNum = 0;
Environs(&rom,&machine); /* Get Macs evniroment */
if (machine == macXLMachine)/* Check if Lisa clone */
canDoIt = FALSE; /* Its a Lisa computer! */
else if (rom >= macIIROM) /* Its Mac II */
canDoIt = TRUE; /* Its Mac II computer */
else if (rom >= macSEROM) /* Its Mac SE */
canDoIt = TRUE; /* Its Mac SE computer */
else if (rom >= macPlusROM) {/* its 128K rom */
/* Check if Mac 512KE */
if (MemTop > (char *)(1024L * 512L))
canDoIt = TRUE; /* Its Mac 512K Enhanced*/
else
canDoIt = TRUE; /* Its Mac Plus computer */
}
else if (rom >= macROM) { /* Its 64K rom */
canDoIt = FALSE; /* Its original Mac! */
originalMac = TRUE;
}
if (canDoIt) { /* OK, we can do it! */
/* SysEnvirons valid? */
if ((long)NGetTrapAddress(SysEnvironsTrap,OSTrap) !=
(long)NGetTrapAddress(UnknownTrap,ToolTrap)) {
SysEnvirons(1,&wSysEnv); /* Get system enviroment */
sysEnv = wSysEnv; /* Save configuration */
}
/* Graphics Dev valid? */
if ((long)NGetTrapAddress(GetDeviceListTrap,ToolTrap)
!= (long)NGetTrapAddress(UnknownTrap,ToolTrap))
hasGraphicDevices = TRUE;/* Mark it available */
}
}
void C4th::Close(void)
{
RestoreStates(); /* Restore drawing */
if (tmpRgn) /* Have clipping region ?*/
DisposeRgn(tmpRgn); /* Release region */
tmpRgn = NULL; /* Invalidate it */
delete(this); /* Release this object */
}
void C4th::Idle(void)
{
if (dirty) { /* Check if its dirty */
Draw(); /* Re-draw everything!!! */
dirty = FALSE; /* Reset dirty indicator */
}
}
void C4th::Cursor(Point pt)
{
CursHandle crossHdl; /* Working cursor handle */
/* Check if got cursor */
if (crossHdl = GetCursor(crossCursor))
SetCursor(*crossHdl); /* Set to cross cursor */
}
void C4th::Select(void)
{ active = TRUE; } /* Mark ext area active */
void C4th::Deselect(void)
{ active = FALSE; } /* Mark ext area not act */
void C4th::Scroll(void) {}
void C4th::Draw(void)
{
Rect wRect; /* Working rect area */
wRect = drawArea; /* Set drawing rect area */
PaintRect(&wRect); /* Show something */
}
void C4th::DoClick(Point pt, short modifiers,long ticks)
{}
void C4th::DoKeyDown(char theChar, Byte keyCode) {}
void C4th::DoUndo(void) {}
void C4th::DoCut(void) {}
void C4th::DoCopy(void) {}
void C4th::DoPaste(void) {}
void C4th::DoClear(void) {}
void C4th::DoSelectAll(void) {}
void C4th::SaveStates(void)
{
GetPenState(&savePenState);/* Get current pen states*/
PenNormal(); /* Normalize pen states */
saveFont = wPtr->txFont; /* Save cur fonts states*/
saveSize = wPtr->txSize;
saveStyle = wPtr->txFace;
saveMode = wPtr->txMode;
}
void C4th::RestoreStates(void)
{
SetPenState(&savePenState);/* Restore pen states */
TextFont(saveFont); /* Restore fonts states */
TextSize(saveSize);
TextFace(saveStyle);
TextMode(saveMode);
prevArea = drawArea; /* Save previous area */
if (tmpRgn) /* Check if has temp rgn */
EmptyRgn(tmpRgn); /* Free-up some memory */
}
short C4th::TrackMouse(Point pt,RgnHandle rgn)
{
register RgnHandle wRgn; /* Working region handle */
register short hilite = FALSE;/* Hilite state */
register short status = FALSE;/* Working status */
if (PtInRgn(pt,rgn)) { /* Initially inside rgn? */
if (wRgn = NewRgn()) { /* Check if got region */
CopyRgn(rgn,wRgn); /* Copy mouses region */
InsetRgn(wRgn,1,1); /* Shrink it a bit */
while(Button()) { /* Do while mouse is down*/
GetMouse(&pt); /* Get next mse position */
if (PtInRgn(pt,rgn)) /* Check if mouse inside?*/
status = TRUE; /* Set inside the region */
else /* Nope, outside region */
status = FALSE; /* Set outside of region */
if (hilite != status) { /* Check if change hilite*/
hilite = status; /* Reset hilite state */
HiliteMode &= 0x7f; /* Set highliting bit */
InvertRgn(wRgn); /* Invert it */
}
}
if (hilite) { /* Restore hilite state? */
HiliteMode &= 0x7f; /* Set highliting bit */
InvertRgn(wRgn); /* Invert it */
}
DisposeRgn(wRgn); /* Release region handle */
}
}
return(status); /* Return status flag */
}
short C4th::UsingColor(void)
{
register short hasColor = TRUE;/* Color flag */
register GDHandle theDevice;/* Working screen device*/
Rect globalRect;/* Working ext area */
Rect wRect; /* Working window area */
if (sysEnv.hasColorQD) { /* Check if using color */
if (hasGraphicDevices) { /* Has graphic devices? */
hasColor = TRUE; /* Assume using color */
globalRect = drawArea; /* Setup global rect area*/
LocalToGlobal(&globalRect.top);/* Cnvt to global */
LocalToGlobal(&globalRect.bottom);
theDevice = GetDeviceList();/* Get main device */
while(hasColor && theDevice) {/* Search B&W device*/
/* Area within view? */
if (SectRect(&globalRect,
&(*(*theDevice)->gdPMap)->bounds, &wRect))
if ((*(*theDevice)->gdPMap)->pixelSize <= 2)
hasColor = FALSE;
theDevice = GetNextDevice(theDevice);/* Get next */
}
}
}
return(hasColor); /* Return color indicator*/
}
int DummyProc() {} /* Dummy procedure */
/*
* Source - CalendarDebugger.c
* Author - Alexander S. Colwell
* Copyright © 1990
* Description - This is Calendar simulator.
*/
#include Calendar.h /* Calendar defs */
#include 4th Debugger.h /* 4th Debugger */
/* Define ext references */
pascal void SetCalendar(),GetCalendar();
void DoSetCalendar(),DoGetCalendar();
void C4thDbgApp::InitExtArea(void)
{
Str255 item; /* Working item string */
SetExtArea(65,25,265,127); /* Set external rect area*/
SetExtName(\pCalendarArea);/* Set ext area name */
/* Install ext procedures*/
InstallExtProc(ep1,(ProcPtr)(DoSetCalendar));
InstallExtProc(ep2,(ProcPtr)(DoGetCalendar));
/* Setup ext proc items */
BlockMove(\pSet Calender Data,item,18L);
gBartender->SetCmdText(ep1,item);
BlockMove(\pGet Calendar Data,item,18L);
gBartender->SetCmdText(ep2,item);
gBartender->RemoveMenuCmd(ep3);/* Remove other items*/
gBartender->RemoveMenuCmd(ep4);
gBartender->RemoveMenuCmd(ep5);
gBartender->RemoveMenuCmd(ep6);
gBartender->RemoveMenuCmd(ep7);
gBartender->RemoveMenuCmd(ep8);
gBartender->RemoveMenuCmd(ep9);
}
void DoSetCalendar(CCalendar **eaObject)
{
short itsMonth = 1; /* Working month */
short itsYear = 1990; /* Working year */
long itsSelect = 0L; /* Working day selection */
/* Set new date/selection*/
SetCalendar(eaObject,&itsMonth,&itsYear,&itsSelect);
}
void DoGetCalendar(CCalendar **eaObject)
{
short itsMonth; /* Working month */
short itsYear; /* Working year */
long itsSelect; /* Working day selection */
/* Set new date/selection*/
GetCalendar(eaObject,&itsMonth,&itsYear,&itsSelect);
/* Output debugging info */
DbgPrint(month - %d, year - %d, select - %lx\n,
itsMonth,itsYear,itsSelect);
}
/*
* Source - Calendar.h
* Author - Alexander S. Colwell
* Copyright © 1990
* Description - This is Calendars include file
*/
#ifndef _Calendar_ /* Has been include yet? */
#define _Calendar_ /* Mark it been included */
#include 4th Class.h /* 4th Ext Area defs */
#define headerHeight 16 /* Height for month/year */
struct CCalendar : C4th { /* Calendar object */
/* Variable instances */
short month; /* Current month */
short year; /* Current year */
short dayIndex; /* Day idx 1st row cell */
unsigned long daySelect; /* Current day selection */
RgnHandle nextMonth; /* Next month cntl handle*/
RgnHandle prevMonth; /* Prevs month cntl hdl */
/* Working variable defs */
short dayWidth; /* Day width */
short dayHeight; /* Day height */
/* Method instances */
void IExtArea(short); /* External area init */
void Close(void); /* Close external area */
void Cursor(Point); /* Cursor */
void SetupValues(void); /* Setup working values */
void Draw(void); /* Draw method */
void DrawDay(char *,short,short);/* Draw cell */
void HiliteDay(short,short);/* Hilite day */
void DayRect(Rect *,short,short);/* Get day rect area*/
short MakeDayOutline(void); /* Make day outline rgn */
void Select(void); /* Do ext area selection */
void Deselect(void); /* Do ext area deselect */
void Scroll(void); /* Scroll ext area */
void DoClick(Point,short,long);/* Do click method */
short GetDays(void); /* Get # days this month */
short GetDayIndex(void); /* Get day idx offset */
short GetRowIndex(short); /* Get row idx offset */
short GetColumnIndex(short);/* Get column idx offset */
short LeapYear(void); /* Check if it leap year */
};
#endif
/*
* Source - Calendar.c
* Author - Alexander S. Colwell
* Copyright © 1990
* Description - This is external area to display an
* calendar.
*/
#include Calendar.h /* Calendar defs */
C4th *New(void) { return(new(CCalendar)); }
void CCalendar::IExtArea(short getKeyBoard)
{
Rect wRect; /* Working rect area */
inherited::IExtArea(TRUE); /* Do other inits */
month = 1; /* Set January default */
year = 1990; /* Set 1990 year default */
daySelect = 0L; /* Set no selected days */
dayIndex = GetDayIndex(); /* Set day offset */
nextMonth = NewRgn(); /* Get next button rgn */
prevMonth = NewRgn(); /* Get prevs button rgn */
}
void CCalendar::Close(void)
{
if (nextMonth) /* Region hdl is valid? */
DisposeRgn(nextMonth); /* Release this rgn hdl */
nextMonth = NULL; /* Invalidate region hdl */
if (prevMonth) /* Region hdl is valid? */
DisposeRgn(prevMonth); /* Release this rgn hdl */
prevMonth = NULL; /* Invalidate region hdl */
inherited::Close(); /* Continue closing */
}
void CCalendar::Cursor(Point pt)
{
register short i; /* Working index */
register short days; /* Working # of days */
register short doIt = FALSE;/* Working status flag */
Rect wRect; /* Working day area */
if (nextMonth) /* Next button rgn valid?*/
if (PtInRgn(pt,nextMonth))/* Inside this region? */
doIt = TRUE; /* Lets do it */
if (!doIt) /* Check if should cont */
if (prevMonth) /* Prev button rgn valid?*/
if (PtInRgn(pt,prevMonth))/* Inside this region? */
doIt = TRUE; /* Lets do it */
if (!doIt) { /* Check if should cont */
days = GetDays(); /* Get # of days */
for(i = 1; i <= days; i++) {/* Search selected days*/
DayRect(&wRect,GetRowIndex(i),GetColumnIndex(i));
if (PtInRect(pt,&wRect)) {/* Point inside day? */
doIt = TRUE; /* Lets do it */
break; /* Break-out of da loop! */
}
}
}
if (doIt) /* Check if want to do it*/
inherited::Cursor(pt); /* OK, do standard cursor*/
else /* Nope, lets not do it */
InitCursor(); /* Reset to arrow cursor */
}
void CCalendar::SetupValues(void)
{
dayWidth = width / 7; /* Compute aveages */
dayHeight = (height - headerHeight) / 7;
}
void CCalendar::Draw(void)
{
register short i; /* Working index */
register short days; /* Working # of days */
register short usingColor; /* Working using color */
Str255 label; /* Working label string */
Rect wRect; /* Working rect area */
RGBColor saveColor; /* Working save fore colr*/
register RgnHandle wRgn; /* Working region handle */
TextFont(geneva); /* Set to Geneva font */
TextSize(9); /* Set to 9-point font */
TextFace(0); /* Set to plain text */
wRect = drawArea; /* Setup drawing area */
EraseRect(&wRect); /* Clear-out old stuff */
FrameRect(&wRect); /* Frame da calendar */
SetupValues(); /* Setup working values */
switch(month) { /* Copy month to label */
case 1: BlockMove(\pJanuary ,label,9L); break;
case 2: BlockMove(\pFeburary ,label,10L); break;
case 3: BlockMove(\pMarch ,label,7L); break;
case 4: BlockMove(\pApril ,label,7L); break;
case 5: BlockMove(\pMay ,label,5L); break;
case 6: BlockMove(\pJune ,label,6L); break;
case 7: BlockMove(\pJuly ,label,6L); break;
case 8: BlockMove(\pAugust ,label,8L); break;
case 9: BlockMove(\pSeptember ,label,11L); break;
case 10: BlockMove(\pOctober ,label,9L); break;
case 11: BlockMove(\pNovember ,label,10L); break;
case 12: BlockMove(\pDecember ,label,10L); break;
}
/* Concat year */
NumToString((long)(year),&label[128]);
BlockMove(&label[129],&label[label[0]+1],
(long)(label[128]));
label[0] += label[128];
DrawDay((char *)(label),0,4);/*Draw Month/Year label*/
DrawDay(\pS,1,1); /* Draw Week Day labels*/
DrawDay(\pM,1,2);
DrawDay(\pT,1,3);
DrawDay(\pW,1,4);
DrawDay(\pT,1,5);
DrawDay(\pF,1,6);
DrawDay(\pS,1,7);
days = GetDays(); /* Get # of days */
for(i = 1; i <= days; i++) {/* Draw Day labels */
NumToString((long)(i),label);
DrawDay((char *)(label),GetRowIndex(i), GetColumnIndex(i));
}
if (active) || !tmpRgn) { /* Check if its active */
for(i = 1; i <= days; i++)/* Hilite the days */
if (daySelect & (1L << (long)(i - 0)))
HiliteDay(GetRowIndex(i),GetColumnIndex(i));
}
else { /* Nope, lets frame it */
MakeDayOutline(); /* Make days outline */
if (wRgn = NewRgn()) { /* Check if got rgn hdl */
CopyRgn(tmpRgn,wRgn); /* Copy outline rgn hdl */
InsetRgn(wRgn,1,1); /* Shrink it a bit */
DiffRgn(tmpRgn,wRgn,tmpRgn);/* OK, get difference */
DisposeRgn(wRgn); /* Release working region*/
HiliteMode &= 0x7f; /* Set highliting bit */
InvertRgn(tmpRgn); /* Outline days */
}
else { /* Nope, do sub-optimal */
if (usingColor = UsingColor()) {/* Using color? */
GetForeColor(&saveColor);/* Save fore color */
RGBForeColor(&HiliteRGB);/* Set hilite fore color*/
}
FrameRgn(tmpRgn); /* Outline the days */
if (usingColor) /* Check if using color */
RGBForeColor(&saveColor);/* Restore fore color */
}
}
/* Draw separators */
MoveTo(drawArea.left,drawArea.top + headerHeight);
LineTo(drawArea.left + width, drawArea.top + headerHeight);
MoveTo(drawArea.left,
drawArea.top + dayHeight + headerHeight);
LineTo(drawArea.left + width,
drawArea.top + dayHeight + headerHeight);
if (prevMonth) { /* Region hdl is valid? */
if (EmptyRgn(prevMonth)) {/* Empty to be drawn? */
OpenRgn(); /* Start button drawing */
MoveTo(drawArea.left+3, drawArea.top+headerHeight/2+1);
LineTo(drawArea.left+headerHeight/2+2, drawArea.top+1);
LineTo(drawArea.left+headerHeight/2+2,
drawArea.top+headerHeight/4+1);
LineTo(drawArea.left+headerHeight-headerHeight/6,
drawArea.top+headerHeight/4+1);
LineTo(drawArea.left+headerHeight-headerHeight/6,
drawArea.top+headerHeight-headerHeight/4);
LineTo(drawArea.left+headerHeight/2+2,
drawArea.top+headerHeight-headerHeight/4);
LineTo(drawArea.left+headerHeight/2+2,
drawArea.top+headerHeight-1);
LineTo(drawArea.left+3,
drawArea.top+headerHeight/2+1);
CloseRgn(prevMonth); /* Close button drawing */
}
if (layout || active) /*Check if should draw it*/
FrameRgn(prevMonth); /* Draw prev button */
}
if (nextMonth) { /* Region hdl is valid? */
if (EmptyRgn(nextMonth)) {/* Empty to be drawn? */
OpenRgn(); /* Start button drawing */
MoveTo(drawArea.right-3, drawArea.top+headerHeight/2+1);
LineTo(drawArea.right-headerHeight/2-2, drawArea.top+2);
LineTo(drawArea.right-headerHeight/2-2,
drawArea.top+headerHeight/4+1);
LineTo(drawArea.right-headerHeight+headerHeight/6,
drawArea.top+headerHeight/4+1);
LineTo(drawArea.right-headerHeight+headerHeight/6,
drawArea.top+headerHeight-headerHeight/4);
LineTo(drawArea.right-headerHeight/2-2,
drawArea.top+headerHeight-headerHeight/4);
LineTo(drawArea.right-headerHeight/2-2,
drawArea.top+headerHeight-1);
LineTo(drawArea.right-3, drawArea.top+headerHeight/2+1);
CloseRgn(nextMonth); /* Close button drawing */
}
if (layout || active) /*Check if should draw it*/
FrameRgn(nextMonth); /* Draw previous button*/
}
}
void CCalendar::DrawDay(char *label,
short row, short column)
{
FontInfo fontInfo; /* Working font infor */
Rect wRect; /* Working rect area */
DayRect(&wRect,row,column);/* Get day rect area */
GetFontInfo(&fontInfo); /* Get current font info */
/* Position da string */
MoveTo(wRect.left + dayWidth/2-StringWidth(label)/2,
wRect.top + ((row ? dayHeight : headerHeight) -
fontInfo.ascent - fontInfo.descent) / 2 +
fontInfo.ascent);
DrawString(label); /* Draw the string label */
}
void CCalendar::HiliteDay(short row, short column)
{
Rect wRect; /* Working rect area */
DayRect(&wRect,row,column); /* Get day rect area */
HiliteMode &= 0x7f; /* Set highliting bit */
InvertRect(&wRect); /* Invert it */
}
void CCalendar::DayRect(Rect *rect, short row, short column)
{
rect->left = rect->top = 0;/* Set relative rect area*/
rect->right = dayWidth;
rect->bottom = dayHeight;
/* Offset day for drawing*/
OffsetRect(rect,dayWidth * (column - 1)+drawArea.left,
dayHeight * row + (row ? max(0,headerHeight - day
Height) : 0) + drawArea.top);
}
short CCalendar::MakeDayOutline(void)
{
register short i; /* Working index */
register short days; /* Working # of days */
Rect wRect; /* Working rect area */
register short status = FALSE;/* Working status flag*/
if (tmpRgn) { /* Check if its valid */
days = GetDays(); /* Get # of days */
EmptyRgn(tmpRgn); /* Set region empty */
OpenRgn(); /* Start region drawing */
for(i = 1; i <= days; i++)/* Outline the days */
if (daySelect & (1L << (long)(i - 0))){/*This day?*/
status = TRUE; /*Mark has some outlining*/
DayRect(&wRect,GetRowIndex(i),GetColumnIndex(i));
FrameRect(&wRect);
}
CloseRgn(tmpRgn); /* Copy da region */
}
return(status); /* Return any outlining */
}
void CCalendar::Select(void)
{
inherited::Select(); /* Do other stuff first */
if (MakeDayOutline()) { /* Make days outline */
InsetRgn(tmpRgn,1,1); /* Shrink it a bit */
HiliteMode &= 0x7f; /* Set highliting bit */
InvertRgn(tmpRgn); /* Invert region */
}
}
void CCalendar::Deselect(void)
{
inherited::Deselect(); /* Do other stuff first */
if (MakeDayOutline()) { /* Make days outline */
InsetRgn(tmpRgn,1,1); /* Shrink it a bit */
HiliteMode &= 0x7f; /* Set highliting bit */
InvertRgn(tmpRgn); /* Invert region */
}
}
void CCalendar::Scroll(void)
{
if (nextMonth) /* Got next region hdl?*/
OffsetRgn(nextMonth,drawArea.left - prevArea.left,
drawArea.top - prevArea.top);
if (prevMonth) /* Got prev region hdl?*/
OffsetRgn(prevMonth,drawArea.left - prevArea.left,
drawArea.top - prevArea.top);
}
void CCalendar::DoClick(Point pt, short modifiers, long ticks)
{
register short i; /* Working index */
register short lastDay = 0;/* Working last day */
register short days; /* Working # of days */
register short hiliteMode = TRUE;/* Hilite mode */
register unsigned long mask;/* Working mask */
short row; /* Working row position */
short column; /*Working column position*/
Rect wRect; /* Working rect area */
if (nextMonth) { /* Selecting next month? */
if (TrackMouse(pt,nextMonth)) {/* Track da mouse!! */
daySelect = 0L; /* Zap current selection */
month += 1; /* Go to next month */
if (month == 13) { /* Its into next year? */
month = 1; /* Reset to January */
year += 1; /* Re-draw the calendar */
}
dayIndex = GetDayIndex();/* Set day offset */
Draw(); /* Re-draw the calendar */
}
}
if (prevMonth) { /* Selecting prev month? */
if (TrackMouse(pt,prevMonth)) {/* Still selecting? */
daySelect = 0L; /* Zap current selection */
month -= 1; /* Go to previous month */
if (month == 0) { /* Its into prev year? */
month = 12; /* Reset to Decemeber */
year -= 1; /* Go to previous year */
}
dayIndex = GetDayIndex();/* Set day offset */
Draw(); /* Re-draw the calendar */
}
}
days = GetDays(); /* Get # of days */
do { /* Track da mouse!! */
for(i = 1; i <= days; i++) {/* Search for day */
DayRect(&wRect,row = GetRowIndex(i),
column = GetColumnIndex(i));
if (PtInRect(pt,&wRect)) {/* Point inside day? */
mask = (1L << (long)(i - 0));/* Set mask */
if (!lastDay) { /* Check if first time */
if (daySelect & mask) /* Check if hilited */
hiliteMode = FALSE; /* Reset to hiliting mode*/
}
if (lastDay != i) { /* Check if its new day */
if (hiliteMode) { /* Check if hiliting day?*/
if (!(daySelect & mask)) {/* Not selected ? */
HiliteDay(row,column);/* Hilite day */
daySelect ^= mask; /* Set this day */
}
}
else { /* Nope, unhiliting days */
if (daySelect & mask) {/* Selected ? */
HiliteDay(row,column);/* Unhilite day */
daySelect ^= mask; /* Clear this day */
}
}
}
lastDay = i; /* Save last selected day*/
}
}
GetMouse(&pt); /* Get next mse position */
} while(Button()); /* Track while mouse down*/
}
short CCalendar::GetDays(void)
{
register short days; /* Working number of days*/
static short monthDays[] = {31,28,31,30,31,30,
31,31,30,31,30,31};
/* Check if Feburary */
if ((days = monthDays[month - 1]) == 28)
days += LeapYear(); /* Add leap year day */
return(days); /* Return number of days */
}
short CCalendar::GetDayIndex(void)
{
DateTimeRec dateTime; /* Working date/tim stamp*/
long secs; /* Working seconds */
dateTime.year = year; /* Init date/time stamp */
dateTime.month = month;
dateTime.day = 1;
dateTime.hour = 0;
dateTime.minute = 0;
dateTime.second = 0;
Date2Secs(&dateTime,&secs);/* Translate to seconds */
Secs2Date(secs,&dateTime); /* Get day of week */
return(dateTime.dayOfWeek - 1);/* Return day of week*/
}
short CCalendar::GetRowIndex(short idx)
{ return(2 + ((idx - 1 + dayIndex) / 7)); }
short CCalendar::GetColumnIndex(short idx)
{ return(1 + ((idx - 1 + dayIndex) % 7)); }
short CCalendar::LeapYear(void)
{
DateTimeRec dateTime; /* Working date/tim stamp*/
long secs; /* Working seconds */
register short leapDay = 0;/* Working leap year day */
dateTime.year = year; /* Init date/time stamp */
dateTime.month = month;
dateTime.day = 29;
dateTime.hour = 0;
dateTime.minute = 0;
dateTime.second = 0;
Date2Secs(&dateTime,&secs);/* Translate to seconds */
Secs2Date(secs,&dateTime); /* Convert to real day */
if (dateTime.day == 29) /* Its still same day? */
leapDay = 1; /* Yup, its leap year!!!*/
return(leapDay); /* Return leap year day */
}
/*
* Source - GetCalendar.c
* Author - Alexander S. Colwell
* Copyright © 1990
* Description - This get calendars states.
*/
#include Calendar.h /* Calendar defs */
#ifndef ExtArea /* Check if debug mode */
#undef main /* Remove previous def */
#define main GetCalendar /* Set debug proc name */
#endif
pascal void main(CCalendar **eaObject,
short *itsMonth, short *itsYear,
long *itsSelect)
{
*itsMonth = (*eaObject)->month;/* Copy it */
*itsYear = (*eaObject)->year;
*itsSelect = (*eaObject)->daySelect;
}
/*
* Source - SetCalendar.c
* Author - Alexander S. Colwell
* Copyright © 1990
* Description - This set new calendars states.
*/
#include Calendar.h /* Calendar defs */
#ifndef ExtArea /* Check if debug mode */
#undef main /* Remove previous def */
#define main SetCalendar /* Set debug proc name */
#endif
pascal void main(CCalendar **eaObject,
short *itsMonth, short *itsYear,
long *itsSelect)
{
(*eaObject)->dirty = TRUE; /* Mark ext area dirty */
(*eaObject)->month = *itsMonth;/* Reset it */
(*eaObject)->year = *itsYear;
(*eaObject)->daySelect = *itsSelect;
}
/*
* Source - 4th Debugger.r
* Author - Alexander S. Colwell
* Copyright © 1990
* Description - This is 4th Debugger resource file.
*/
#include Types.r
#include SysTypes.r
type EA4h { pstring; };
resource BNDL (128, purgeable) {
EA4h, 0,
{
ICN#, { 0, 128 },
FREF, { 0, 128 }
}
};
resource FREF (128) {
APPL, 0,
};
resource EA4h (0) {
External Area Debugger
};
resource MBAR (1, preload) {
{ 1, 2, 3, 128 }
};
resource MENU (1, Apple) {
1, textMenuProc, 0x7FFFFFFD, enabled, apple,
{
About 4th Dim Debugger #256,
noIcon, noKey, noMark, plain,
-, noIcon, noKey, noMark, plain
}
};
resource MENU (2, File) {
2, textMenuProc, allEnabled, enabled, File,
{
Page Setup #8, noIcon, noKey, noMark, plain,
Print #9, noIcon, P, noMark, plain,
-, noIcon, noKey, noMark, plain,
Quit#1, noIcon, Q, noMark, plain
}
};
resource MENU (3, Edit, preload) {
3, textMenuProc, 0x7FFFFF80, enabled, Edit,
{
Undo#16, noIcon, Z, noMark, plain,
-, noIcon, noKey, noMark, plain,
Cut#18, noIcon, X, noMark, plain,
Copy#19, noIcon, C, noMark, plain,
Paste#20, noIcon, V, noMark, plain,
Clear#21, noIcon, noKey, noMark, plain,
-, noIcon, noKey, noMark, plain,
Select All#1035, noIcon, A, noMark, plain,
Hide Debugger#1036, noIcon, D, noMark, plain,
Show Clipboard#22, noIcon, noKey, noMark, plain
}
};
resource MENU (128, Emulate) {
128, textMenuProc, allEnabled, enabled, Emulate,
{
Open External Area#1024, noIcon, O, noMark, plain,
Close External Area#1025,
noIcon, W, noMark, plain,
-, noIcon, noKey, noMark, plain,
Run External Procedure 1#1026,
noIcon, 1, noMark, plain,
Run External Procedure 2#1027,
noIcon, 2, noMark, plain,
Run External Procedure 3#1028,
noIcon, 3, noMark, plain,
Run External Procedure 4#1029,
noIcon, 4, noMark, plain,
Run External Procedure 5#1030,
noIcon, 5, noMark, plain,
Run External Procedure 6#1031,
noIcon, 6, noMark, plain,
Run External Procedure 7#1032,
noIcon, 7, noMark, plain,
Run External Procedure 8#1033,
noIcon, 8, noMark, plain,
Run External Procedure 9#1034,
noIcon, 9, noMark, plain
}
};
resource WIND (500, 4th External Area) {
{40, 4, 210, 352},
zoomDocProc, invisible, goAway, 0,
4th External Area
};
resource WIND (501, 4th External Debugger) {
{235, 4, 335, 352},
zoomDocProc, visible, goAway, 0,
Debugger
};
resource DLOG (500, About This...) {
{40, 40, 128, 304},
dBoxProc, visible, noGoAway, 0, 500,
About This...
};
resource DITL (500, About This...) {
{
{8, 52, 26, 216},
StaticText { enabled, 4th Dimension Debugger },
{27, 95, 45, 173},
StaticText { enabled, Version 1.0 },
{46, 29, 64, 240},
StaticText{enabled,Written by Alexander S. Colwell},
{65, 76, 83, 194},
StaticText { enabled, Copyright © 1990 }
}
};
resource STR# (1036, Hide/Show Debugger) {
{
Hide Debugger,
Show Debugger
}
};
resource ICN# (128, purgeable) {
{
$00 00 00 00 72 00 1F E0 45 00 20 20 67 7F C0 7F
$45 00 80 F8 75 01 01 F0 00 02 03 E0 FF FC 07 FF
$00 08 0F 80 00 10 1F 00 00 20 3E 00 FF C0 7F FF
$00 80 FF F8 01 01 F0 10 02 03 E0 20 FC 07 C0 7F
$08 0F 80 F8 10 1F 01 FC 20 00 00 04 C0 00 00 0F
$40 00 00 1F 40 00 00 3E 40 00 00 7C FF E0 3F FF
$3F C0 7F F0 3F 80 FF E0 3F 01 FF C0 FF FF FF FF
$00 7F C0 00 00 FF 80 00 01 FF 00 00 FF FF FF FF,
$FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
$FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
$FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
$FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
$FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
$FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
$FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
$FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
}
};
/*
* Think C Object Resources
* Copyright © 1989
*/
type Estr { pstring; };
resource WIND (200, Clipboard, purgeable, preload) {
{130, 158, 238, 444},
zoomDocProc, invisible, goAway, 0,
Clipboard
};
resource ALRT (128, General, purgeable) {
{32, 10, 164, 328},
128,
{
OK, visible, silent,
OK, visible, silent,
OK, visible, silent,
OK, visible, silent
}
};
resource ALRT (150, Confirm Revert, purgeable) {
{100, 120, 190, 420},
150,
{
OK, visible, silent,
OK, visible, silent,
OK, visible, silent,
OK, visible, silent
}
};
resource ALRT (151, Save Changes, purgeable) {
{42, 34, 184, 350},
151,
{
OK, visible, silent,
OK, visible, silent,
OK, visible, silent,
OK, visible, silent
}
};
resource ALRT (200, Severe Error, purgeable) {
{32, 10, 168, 352},
200,
{
OK, visible, sound1,
OK, visible, sound1,
OK, visible, sound1,
OK, visible, sound1
}
};
resource ALRT (250, No Printer, purgeable) {
{40, 40, 156, 382},
250,
{
OK, visible, sound1,
OK, visible, sound1,
OK, visible, sound1,
OK, visible, sound1
}
};
resource ALRT (300, OS Error, purgeable) {
{32, 10, 168, 352},
300,
{
OK, visible, sound1,
OK, visible, sound1,
OK, visible, sound1,
OK, visible, sound1
}
};
resource DITL (128, General, purgeable) {
{
{98, 231, 118, 291},
Button { enabled, OK },
{14, 25, 82, 299},
StaticText { disabled, ^0 }
}
};
resource DITL (150, Confirm Revert, purgeable) {
{
{60, 208, 80, 290},
Button { enabled, OK },
{60, 105, 80, 187},
Button { enabled, Cancel },
{5, 113, 45, 293},
StaticText { disabled,
Revert to the last version saved ? },
{47, 10, 64, 66},
StaticText { disabled, Caution }
}
};
resource DITL (151, Save Changes, purgeable) {
{
{74, 35, 94, 117},
Button { enabled, Yes },
{111, 35, 131, 117},
Button { enabled, No },
{111, 205, 131, 287},
Button { enabled, Cancel },
{14, 25, 55, 291},
StaticText { disabled,
Save changes to ^0 before ^1? }
}
};
resource DITL (200, Severe Error, purgeable) {
{
{104, 264, 124, 324},
Button { enabled, Proceed },
{104, 168, 124, 228},
Button { enabled, Quit },
{16, 80, 87, 332},
StaticText { disabled, ^0\n\nResult Code = ^1 }
}
};
resource DITL (250, No Printer, purgeable) {
{
{85, 262, 105, 327},
Button { enabled, OK },
{14, 84, 67, 327},
StaticText { disabled,
Printing operations are not possible
until you have selected a Printer using the
Chooser. }
}
};
resource DITL (300, OS Error, purgeable) {
{
{104, 264, 124, 324},
Button { enabled, OK },
{16, 80, 87, 332},
StaticText { disabled, ^0\n\nResult Code = ^1 }
}
};
resource CNTL (300, Scroll Bar, preload) {
{0, 0, 0, 0},
0, invisible, 0, 0, scrollBarProc, 0,
};
resource STR# (128, Common) {
{
quitting,
closing,
Undo ,
Redo ,
Untitled,
Show Clipboard,
Hide Clipboard
}
};
resource STR# (129, Memory Warnings) {
{
Memory is running low. Please close
windows and save documents to avoid losing
data.
}
};
resource STR# (130, Task Names) {
{
}
};
resource STR (150, SaveAs Prompt, purgeable) {
Save File As:
};
resource STR (300, OS Error, purgeable) {
Mac OS Error Encountered
};
resource Estr (-192, resNotFound, purgeable) {
Tried to get a nonexistent resource
};
resource SICN (200, Grow Box, preload) {
{
$FF FF 80 01 80 01 9F C1 90 41 90 7D 90 45 90 45"
$90 45 9F C5 84 05 84 05 84 05 87 FD 80 01 FF FF
}
};