home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD2.img
/
d4xx
/
d463
/
rexxlib
/
rexxlib.lzh
/
FreeDraw.asm
< prev
next >
Wrap
Assembly Source File
|
1990-06-26
|
46KB
|
1,640 lines
;***************************************************************************
; This program is an example of how to add a Rexx implementation to any
; program using the rexxapp.library. The original Freedraw program (without
; REXX) is from Fred Fish Disk 1. The rexxapp.library is based upon a C module
; by Radical Eye Software which was modified and down-coded to a 68000 shared
; library.
; All the REXX stuff is bracketed by IFNE TALKTOREXX, so you can identify it
; easily. If you assemble with TALKTOREXX equ 0, you will get the default
; program with no REXX port. The REXX port on this program increases the
; executable slightly, but a lot of functionality comes with that. You can draw
; from Rexx, spawn macros from Rexx, etc. But go to the next TALKTOREXX for
; more information. To run a rexx macro on startup, simply give that rexx macro
; as part of the command line, as in "freedraw sample" or "freedraw bspline 20
; 100 20 20 280 20 280 100". All modifications are placed in the public domain.
;
; Note that I did not do much more than just run the original C through a
; compiler to produce this assembly module. I did not think it worthwhile to
; optimize the example, although the rexxapp.library is a very tight Rexx
; interface.
TALKTOREXX equ 1
;**********************************************************************
; FreeDraw - PD graphics for Amiga
;
; This is an extremely simple graphics editor which works in the windowing
; environment of the Amiga. It is very limited in features. The basic idea of
; this program is to provide some minimal image editing functions which can be
; used to develop images for other programs. I know there will be a lot of
; Paint There are only two menu topics in this version, so using it is really
; quite easy. Boxes are not allowed to be drawn in areas outside of the window
; where border gadgets are located, and the pen-draw mode also clips to these
; same boundaries. If you have begun to draw a box by clicking the left button
; while the cursor is located in the FreeDraw window, then you can cancel that
; box by clicking the right button. In the pen mode pressing and holding the
; left button will draw. Colors are selected by simply releasing the menu
; button over the desired color in the Color menu. The erase feature always
; clears the window to the currently selected color. This is no gem of
; programming style, but you're getting it for the right price so be patient
; with its design flaws. New versions will appear here on BIX as soon as I can
; get them in shape for release. I apologize to anyone who objects to my lack
; of coding grace, but I just want to get the project off the ground, and
; improvements will be forthcoming. There are a lot of comments, but I didn't
; know what needed to be made clear so I just commented everything.
;
;Rick Ross 11/14/85
OBJFILE "rad:freedraw.o"
ADDSYM
SMALLOBJ
;from small.lib or amiga.lib
XREF _LVOWindowToBack,_LVOWindowToFront,_LVOCloseWindow,_LVOOpenWindow
XREF _LVOSetMenuStrip,_LVOClearMenuStrip,_LVOSetWindowTitles
XREF _LVOGetMsg,_LVOReplyMsg,_LVOWait
XREF _LVOOpenLibrary,_LVOOldOpenLibrary,_LVOCloseLibrary
XREF _LVODraw,_LVOMove,_LVOSetAPen,_LVORectFill,_LVOSetDrMd
;from StartUp.o
XREF _exit,_SysBase,_DOSBase
;from Rexx App lib
_LVOSetRexxPort equ -30
_LVOReceiveRexx equ -36
_LVOFreeRexxPort equ -42
_LVOSendRexxCmd equ -48
_LVOASyncRexxCmd equ -54
_LVOSyncRexxCmd equ -60
_LVOSetupResults equ -66
;**************************************************************
;DrawBox - Simple routine to draw an unfilled rectangle
;
;It accepts the coordinates of the top-left and lower-right points of the
;rectangle, a pointer to the Window structure, and the color in which to render
;the rectangle. The current FgPen color of the window is preserved thru the
;call. No clipping is done.
;
;DrawBox(topleftx, toplefty, lowrightx, lowrighty, window, color )
XDEF DrawBox
DrawBox:
link a5,#0
movea.l _GfxBase,a6
movem.l d2/a2,-(sp)
;---save window's FgPen
movea.l 24(a5),a0
movea.l 50(a0),a2 ;RastPort
move.b 25(a2),d2
;---set draw color for box
move.l 28(a5),d0
movea.l a2,a1
jsr _LVOSetAPen(a6)
;---move to top-left point
move.l 12(a5),d1
move.l 8(a5),d0
movea.l a2,a1
jsr _LVOMove(a6)
;---Draw to each of the four corners of the box
move.l 12(a5),d1
move.l 16(a5),d0
movea.l a2,a1
jsr _LVODraw(a6)
move.l 20(a5),d1
move.l 16(a5),d0
movea.l a2,a1
jsr _LVODraw(a6)
move.l 20(a5),d1
move.l 8(a5),d0
movea.l a2,a1
jsr _LVODraw(a6)
move.l 12(a5),d1
move.l 8(a5),d0
movea.l a2,a1
jsr _LVODraw(a6)
;---restore old FgPen
moveq #0,d0
move.b d2,d0
movea.l a2,a1
jsr _LVOSetAPen(a6)
movem.l (sp)+,d2/a2
unlk a5
rts
;**************************************************************
;The following function initializes the structure arrays
;needed to provide the Color menu topic.
;
;InitColorItems(depth)
; d0
;
;depth is the number of bit-planes in window
XDEF InitColorItems
InitColorItems:
movem.l d2/d3/d4/d5,-(sp)
;---get # of colors allowed for this depth
move.w d0,d4
lea _palette,a0
adda.w d0,a0
moveq #0,d2
move.b (a0),d2
lea _coloritem,a0
lea _colorimage,a1
moveq #0,d3
bra 2$
;=============== Init Next Item ===============
;coloritem[n].NextItem = &coloritem[n+1]
1$ lea 34(a0),a6
move.l a6,(a0)+
;the next two items might be changed for when bit-planes is greater than 2
;coloritem[n].LeftEdge = 2 + CW * (n % 4)
move.l d3,d0
moveq #4,d1
divu.w d1,d0
move.w d0,d5
swap d0
moveq #40,d1
mulu.w d1,d0
addq.w #2,d0
move.w d0,(a0)+
;coloritem[n].TopEdge = CH * (n / 4)
moveq #25,d1
mulu.w d1,d5
move.w d5,(a0)+
;coloritem[n].Width = CW
move.w #40,(a0)+
;coloritem[n].Height = CH
move.w #25,(a0)+
;coloritem[n].Flags = ITEMSTUFF
move.w #144,(a0)+
;coloritem[n].MutualExclude = 0
clr.l (a0)+
;coloritem[n].ItemFill = (APTR)&colorimage[n]
move.l a1,(a0)+
;coloritem[n].SelectFill = NULL
clr.l (a0)+
;coloritem[n].Command = 0
clr.w (a0)+
;coloritem[n].SubItem = NULL
clr.l (a0)+
;coloritem[n].NextSelect = 0
clr.w (a0)+
;=============== Init next Image ===============
;colorimage[n].LeftEdge = 1
move.w #1,(a1)+
;colorimage[n].TopEdge = 1
move.w #1,(a1)+
;colorimage[n].Width = CW-2
move.w #38,(a1)+
;colorimage[n].Height = CH-2
move.w #23,(a1)+
;colorimage[n].Depth = depth
move.w d4,(a1)+
;colorimage[n].ImageData = NULL
clr.l (a1)+
;colorimage[n].PlanePick = 0
clr.b (a1)+
;colorimage[n].PlaneOnOff = n
move.b d3,(a1)+
;colorimage[n].NextImage = 0
clr.l (a1)+
addq.w #1,d3
2$ Dbra d2,1$(pc)
;coloritem[colors-1].NextItem = NULL (needed for last item in list)
clr.l -34(a0)
movem.l (sp)+,d2/d3/d4/d5
rts
;******************************************************
;* Main Program *
;* *
;* This is the main body of the program. *
;******************************************************
XDEF _main
_main:
link a5,#-310
;---DrawColor = 1 (initial drawing color)
move.b #1,-5(a5)
;---OldBRX = 30, OldBRY = 30 (point coords used for boxes)
move.w #30,-8(a5)
move.w #30,-10(a5)
;---TLX = 20, TLY = 20 (initial top-left point coords)
move.w #20,-12(a5)
move.w #20,-14(a5)
;---MouseMoved = FALSE (indicates new mouse position ready)
clr.w -38(a5)
;---ClipIt = FALSE (are new point coords out of bounds?)
clr.w -40(a5)
;---ClippedLast = FALSE (was last PenDraw operation clipped?)
clr.w -42(a5)
;---PenMode = FALSE (indicates PenDraw mode is set)
clr.w -44(a5)
;---PenDown = FALSE (if mouse moved, then should it draw?)
clr.w -46(a5)
;---RubberBox = FALSE (are we currently rubberbanding a box?)
clr.w -48(a5)
;---FilledBox = FALSE (should boxes be filled when drawn?)
clr.w -50(a5)
;---Open Graphics
movea.l _SysBase,a6
lea GfxName,a1
jsr _LVOOldOpenLibrary(a6)
move.l d0,_GfxBase
;---Open Intuition
lea IntuiName,a1
jsr _LVOOldOpenLibrary(a6)
move.l d0,_IntuitionBase
IFNE TALKTOREXX
;---Open RexxApp lib
lea RexxName,a1
moveq #0,d0
jsr _LVOOpenLibrary(a6)
move.l d0,_rexxBase
beq CLSE2
ENDIF
;---Try to open new window for application
lea _NewWindow,a0
movea.l _IntuitionBase,a6
jsr _LVOOpenWindow(a6)
move.l d0,_Window
beq CLSE
;set initial clipping boundaries from the values found in the window
;structure for border dimensions
bsr SetBounds
;initialize Color menu arrays
moveq #2,d0
bsr InitColorItems
;SetMenuStrip( Window, &menu[0] )
lea _menu1,a1
move.l _Window,a0
movea.l _IntuitionBase,a6
jsr _LVOSetMenuStrip(a6)
;set initial draw mode JAM1 and color
moveq #0,d0
movea.l _Window,a0
movea.l 50(a0),a1
movea.l _GfxBase,a6
jsr _LVOSetDrMd(a6)
;SetAPen( Window->RPort, DrawColor )
moveq #0,d0
move.b -5(a5),d0
movea.l _Window,a0
movea.l 50(a0),a1
jsr _LVOSetAPen(a6)
;==================================================================
IFNE TALKTOREXX
;For rexx, we open up a Rexx port, and send out the first command, if there
;was one, that the user typed on the CLI line. We send it out asynchronously
;(ie as a macro for the ARexx server to execute). Arexx will load the script
;(ie our command string will be the name of the script) and execute it (ie
;send ARexx msgs to the target task). It just so happens that all the demo
;ARexx scripts that we wrote use Freedraw itself as the target task. In
;other words, we are sending out a Rexxmsg which will cause the ARexx server
;to execute a script which sends ARexx msgs to Freedraw. This is how a self-
;running demo of a program might be implemented. We could have written some
;scripts to control other products, which Freedraw could start up as so:
move.l 8(a5),d2
movea.l 12(a5),a2
addq.l #4,a2
;---Save a5, and set it up as the base of our RexxData
move.l a5,-(sp)
lea _rexxPort,a5
;---rexxMask = SetRexxPort()
movea.l _rexxBase,a6
lea RXname,a1
jsr _LVOSetRexxPort(a6)
beq.s 4$ ;an error in setting up the port
;---append all the args from the CLI into 1 string with spaces between each arg
subq.l #2,d2 ;don't count the name of the program
bcs.s 5$
lea ArexxCmdStr,a1 ;here's where we'll make our Arexx scriptname
1$ movea.l (a2)+,a0
2$ move.b (a0)+,(a1)+
bne.s 2$
move.b #' ',-1(a1)
clr.b (a1)
dbra d2,1$
;---Send this command string out as a macro (ie asyncRexxCmd)
lea ArexxCmdStr,a0
jsr _LVOASyncRexxCmd(a6)
;---If an error in sending out Rexxmsg, print the returned err msg to window
bne.s 5$
4$ ;---null-term error string in a0
bsr printRexxErr
;---Restore a5
5$ movea.l (sp)+,a5
ENDIF
;Everything the program needs is now initialized and put in place. The
;program enters the following loop and processes message continuously as they
;are received from Intuition. I guess this loop is the real workhorse of the
;program. By the way, the loop control variable KeepGoing remains TRUE until a
;CLOSEWINDOW message is received. At that point it goes FALSE, and the program
;cleans up and exits.
; while( KeepGoing )
.37 tst.w _KeepGoing
beq .38
;stay here until a message is received from Intuition or REXX port
movea.l _Window,a0
movea.l 86(a0),a1
IFNE TALKTOREXX
move.l RexxMask,d0 ;If ARexx, use the mask that the lib setup
ENDIF
IFEQ TALKTOREXX
moveq #0,d0
ENDIF
move.b 15(a1),d1
bset.l d1,d0
movea.l _SysBase,a6
jsr _LVOWait(a6)
IFNE TALKTOREXX
;---see if any REXX msgs to handle (safe to call even if Rexx port not setup)
; If there are any ARexx msgs, receiveRexx will handle them by calling our
; ErrorVector for msgs that WE sent out (ie the msg that started up the
; whole, initial script process), or by calling myDispatch() for msgs that
; some other task sends us (ie the ARexx server will be sending us msgs when
; it executes that script file, or another program could be sending msgs to
; our FreeDraw _rexxPort).
move.l a5,-(sp)
lea _rexxPort,a5 ;setup a5 as base of Rexx data section
movea.l _rexxBase,a6
jsr _LVOReceiveRexx(a6)
movea.l (sp)+,a5
ENDIF
;---MouseMoved = FALSE (clear this flag each time thru loop)
clr.w -38(a5)
;---get next IntuiMsg at window
.39 movea.l _Window,a0
movea.l 86(a0),a0
movea.l _SysBase,a6
jsr _LVOGetMsg(a6)
move.l d0,-4(a5)
beq .40
movea.l d0,a1
move.l 20(a1),-18(a5)
;code = NewMessage->Code
move.w 24(a1),-20(a5)
;x = Window->MouseX
move.l _Window,a0
move.w 14(a0),-22(a5)
;y = Window->MouseY
move.w 12(a0),-24(a5)
;Reply the IntuiMessage
jsr _LVOReplyMsg(a6)
;Examine point coords from message received and set the clipping flag if out
;of bounds. If user was drawing in PenMode when message was received, then the
;ClippedLast flag should also be set to indicate this to the next draw oper-
;ation.
;if(ClipIt = ( x < MinX || x > MaxX || y < MinY || y > MaxY )) if( PenDown )
move.w -22(a5),d0
cmp.w _MinX,d0
blt.s .43
move.w -22(a5),d0
cmp.w _MaxX,d0
bgt.s .43
move.w -24(a5),d0
cmp.w _MinY,d0
blt.s .43
move.w -24(a5),d0
cmp.w _MaxY,d0
ble.s .42
.43 moveq #1,d0
bra.s .44
.42 moveq #0,d0
.44 move.w d0,-40(a5)
beq .41
;ClippedLast = TRUE
tst.w -46(a5)
beq.s .41
move.w #1,-42(a5)
;enter switch on type of message received
.41 move.l -18(a5),d0
subq.l #2,d0
beq.s .49
subq.l #6,d0
beq.s .51
subq.l #8,d0
beq.s .48
sub.l #240,d0
beq .66
sub.l #256,d0
beq.s .50
sub.l #523776,d0
beq .82
bra .39
;========================case MOUSEMOVE:
;Don't really do anything with this one
;until any other, more important, messages
;are received and processed.
;MouseMoved = TRUE
.48 move.w #1,-38(a5)
bra .39
;========================case NEWSIZE:
.49 bsr SetBounds
bra .39
;========================case CLOSEWINDOW:
;User is ready to quit, so indicate that execution should terminate
;with next iteration of the IDCMP loop.
.50 clr.w _KeepGoing
bra .39
;=======================case MOUSEBUTTONS:
;A number of things could have happened here, and further examination of data
;received from message is needed to determine what action should be taken.
;The code variable holds important info about what actually caused the message
;to be sent in the first place.
.51 move.w -20(a5),d0
subi.w #104,d0
beq.s .55
subq.w #1,d0
beq .64
subi.w #127,d0
bne .39
;case SELECTUP:
;User was holding down the left button and just released it. The PenMode
;flag variables are set accordingly. The pen can no longer be down, and
;ClippedLast is reset for next time.
;PenDown = ClippedLast = FALSE
.54 clr.w -42(a5)
clr.w -46(a5)
bra .39
;case SELECTDOWN:
;User has pressed the left button, and
;several differnt actions may need to
;be taken. If the ClipIt value is TRUE,
;then no action should be taken at all.
;
;if( ClipIt ) break;
.55 tst.w -40(a5)
bne .39
;If user is currently in PenMode, then set up to draw when MOUSEMOVED messages
;are received until a subsequent SELECTUP message comes in.
;if( PenMode )
tst.w -44(a5)
beq .56
;PenDown = TRUE
move.w #1,-46(a5)
;ClippedLast = FALSE
clr.w -42(a5)
;make sure to set appropriate mode, JAM1
moveq #0,d0
movea.l _Window,a0
movea.l 50(a0),a1
movea.l _GfxBase,a6
jsr _LVOSetDrMd(a6)
;and establish initial position to draw
moveq #0,d1
move.w -24(a5),d1
moveq #0,d0
move.w -22(a5),d0
move.l _Window,a0
move.l 50(a0),a1
jsr _LVOMove(a6)
bra .39
;If user is currently rubberbanding a box, then a SELECTDOWN message means it
;is time to stop rubberbanding and actually draw it. The following code will
;be executed if this is the case, and it will determine if a filled box is
;needed before rendering.
;if( RubberBox )
.56 tst.w -48(a5)
beq .57
;set draw mode back to JAM1 since it is now currently set to COMPLEMENT
moveq #0,d0
movea.l _Window,a0
movea.l 50(a0),a1
movea.l _GfxBase,a6
jsr _LVOSetDrMd(a6)
;RubberBox = FALSE (turn off rubberbanding)
clr.w -48(a5)
;Restore the condition of the RMBTRAP bit in the Window structure's Flags
;member. Menubutton events will not be received by this loop.
movea.l _Window,a0
bclr.b #0,25(a0)
;RectFill is not condusive to the smooth execution of programs if arguments are
;out of order, so this code sorts them in preparation for the call.
;if( FilledBox )
tst.w -50(a5)
beq .58
;first sort the x-coords
;if TLX < OldBRX
move.w -12(a5),d0
cmp.w -8(a5),d0
bge.s .59
;x1 = TLX, x2 = OldBRX
move.w -12(a5),-26(a5)
move.w -8(a5),-30(a5)
bra.s .60
;x1 = OldBRX, x2 = TLX
.59 move.w -8(a5),-26(a5)
move.w -12(a5),-30(a5)
;then sort the y-coords
;if TLY < OldBRY
.60 move.w -14(a5),d0
cmp.w -10(a5),d0
bge.s .61
;y1 = TLY; y2 = OldBRY
move.w -14(a5),-28(a5)
move.w -10(a5),-32(a5)
bra.s .62
;y1 = OldBRY; y2 = TLY
.61 move.w -10(a5),-28(a5)
move.w -14(a5),-32(a5)
; now generate the filled rectangle
;RectFill( Window->RPort, (long)x1, (long)y1,(long)x2, (long)y2 )
.62 moveq #0,d3
move.w -32(a5),d3
moveq #0,d2
move.w -30(a5),d2
moveq #0,d1
move.w -28(a5),d1
moveq #0,d0
move.w -26(a5),d0
move.l _Window,a0
move.l 50(a0),a1
jsr _LVORectFill(a6)
bra .39
;FilledBox not set, so draw hollow box
;DrawBox( TLX, TLY, OldBRX, OldBRY, Window, DrawColor )
.58 moveq #0,d0
move.b -5(a5),d0
move.l d0,-(sp)
move.l _Window,-(sp)
moveq #0,d0
move.w -10(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -8(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -14(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -12(a5),d0
move.l d0,-(sp)
bsr DrawBox
lea 24(sp),sp
bra .39
;If execution comes here, then PenMode was
;not set and user was not rubberbanding.
;SELECTDOWN therefore indicates to start the
;rubberbanding process at this point. The
;initial coords are set to the values we
;received when the GetMsg() was executed.
;TLX = OldBRX = x, TLY = OldBRY = y
.57 move.w -22(a5),-8(a5)
move.w -22(a5),-12(a5)
move.w -24(a5),-10(a5)
move.w -24(a5),-14(a5)
;set to render in COMPLEMENT mode
moveq #2,d0
movea.l _Window,a0
movea.l 50(a0),a1
movea.l _GfxBase,a6
jsr _LVOSetDrMd(a6)
;/* set flag to indicate we are now rubberbanding */
;RubberBox = TRUE
move.w #1,-48(a5)
;This instruction indicates to Intuition that we now wish to receive a message
;each time the Menubutton is pressed. This is how we hijack the right button
;for temporary use as a Cancel button instead of a Menubutton.
;Window->Flags |= RMBTRAP
move.l _Window,a0
bset.b #0,25(a0)
;render the initial rubberbox and exit
;DrawBox( TLX, TLY, OldBRX, OldBRY, Window, DrawColor )
moveq #0,d0
move.b -5(a5),d0
move.l d0,-(sp)
move.l _Window,-(sp)
moveq #0,d0
move.w -10(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -8(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -14(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -12(a5),d0
move.l d0,-(sp)
bsr DrawBox
lea 24(sp),sp
bra .39
;=======================case MENUDOWN:
;WE only receive this message class if
;the RMBTRAP flag bit has been set, so
;it always means that we should cancel
;the box which is currently rubberbanding.
;turn the flag off */
;RubberBox = FALSE
.64 clr.w -48(a5)
;restore control of menubutton to Intuition */
;Window->Flags &= ( 0xFFFFFFFF ^ RMBTRAP );
move.l _Window,a0
bclr.b #0,25(a0)
;erase (by double XOR'ing) the current
;rubberbox and exit switch.
;DrawBox( TLX, TLY, OldBRX, OldBRY, Window, DrawColor );
moveq #0,d0
move.b -5(a5),d0
move.l d0,-(sp)
move.l _Window,-(sp)
moveq #0,d0
move.w -10(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -8(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -14(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -12(a5),d0
move.l d0,-(sp)
bsr DrawBox
lea 24(sp),sp
bra .39
;=======================case MENUPICK:
;A menu event has taken place and is ready to be processed. Examine the code
;variable received from the message to determine what action should be taken.
;The first check is for code=MENUNULL, which means that nothing should be done.
.66 cmp.w #-1,-20(a5)
beq .39
;get menu and item numbers from code
;MenuNum = MENUNUM( code )
moveq #31,d0
and.w -20(a5),d0
move.w d0,-34(a5)
;ItemNum = ITEMNUM( code )
move.w -20(a5),d1
lsr.w #5,d1
and.w #63,d1
move.w d1,-36(a5)
;determine appropriate action by menu number
;switch ( MenuNum )
tst.w d0
beq.s .70
subq.w #1,d0
beq.s .71
bra .39
;case 0:
;Menu 0 is the Color menu. The item number indicates which new color to set.
;DrawColor = ItemNum
.70 moveq #0,d0
move.b d1,d0
move.b d0,-5(a5)
movea.l _Window,a0
movea.l 50(a0),a1
movea.l _GfxBase,a6
jsr _LVOSetAPen(a6)
bra .39
;case 1:
;Menu 1 is the DrawMode menu. The item number indicates what to do.
;NOTE: Since we cannot have received this message if we were rubberbanding,
;then there is no need to clean up before changing drawing modes.
.71 move.w d1,d0
beq.s .74
subq.w #1,d1
beq.s .75
subq.w #1,d1
beq.s .76
subq.w #1,d1
bne .39
;case 3:
;set flag variables for PenMode
;PenMode = TRUE;
.77 move.w #1,-44(a5)
bra .39
;case 1: set flag variables for hollow box */
;PenMode = FALSE;
.75 clr.w -44(a5)
;FilledBox = FALSE;
clr.w -50(a5)
bra .39
;case 2: set flag variables for filled box
;PenMode = FALSE
.76 clr.w -44(a5)
;FilledBox = TRUE
move.w #1,-50(a5)
bra .39
;case 0: Erase window to current color
;---set JAM1
.74 moveq #0,d0
movea.l _Window,a0
movea.l 50(a0),a1
movea.l _GfxBase,a6
jsr _LVOSetDrMd(a6)
;RectFill( Window->RPort, (long)MinX, (long)MinY,(long)MaxX, (long)MaxY);
moveq #0,d3
move.w _MaxY,d3
moveq #0,d2
move.w _MaxX,d2
moveq #0,d1
move.w _MinY,d1
moveq #0,d0
move.w _MinX,d0
move.l _Window,a0
move.l 50(a0),a1
jsr _LVORectFill(a6)
bra .39
;============case INACTIVEWINDOW:
.82
;User has de-selected our window, so a
;little bit of cleaning up may be needed
;to prevent untoward events when he comes
;back to it.
;erase any outstanding rubberbox */
;if( RubberBox )
;DrawBox( TLX, TLY, OldBRX, OldBRY, Window, DrawColor)
tst.w -48(a5)
beq .83
moveq #0,d0
move.b -5(a5),d0
move.l d0,-(sp)
move.l _Window,-(sp)
moveq #0,d0
move.w -10(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -8(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -14(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -12(a5),d0
move.l d0,-(sp)
bsr DrawBox
lea 24(sp),sp
;reset all the flafg variables */
;PenDown = ClippedLast = RubberBox = FALSE;
.83
clr.w -48(a5)
clr.w -42(a5)
clr.w -46(a5)
;return possibly diverted menubutton events to Big I
;Window->Flags &= ( 0xFFFFFFFF ^ RMBTRAP );
move.l _Window,a0
bclr.b #0,25(a0)
bra .39
;============================================================
;There are no more messages waiting at the IDCMP port, so we can now proceed
;to process any MOUSEMOVED message we may have received.
;if( MouseMoved && !ClipIt)
.40 tst.w -38(a5)
beq .37
tst.w -40(a5)
bne .37
;the mouse did move, and we don't need to clip
;check first if we are drawing in PenMode
;if( PenDown )
tst.w -46(a5)
beq .88
;We have to examine if we clipped the
;last PenMode draw operation. If we did,
;then this is the first move back into
;window boundaries, so we mov instead of
;drawing.
;if( ClippedLast )
tst.w -42(a5)
beq .89
;ClippedLast = FALSE; /* reset this flag
clr.w -42(a5)
moveq #0,d1
move.w -24(a5),d1
moveq #0,d0
move.w -22(a5),d0
move.l _Window,a0
move.l 50(a0),a1
movea.l _GfxBase,a6
jsr _LVOMove(a6)
bra .37
;Draw( Window->RPort, (long)x, (long)y ); /* draw to x,y coords
.89 moveq #0,d1
move.w -24(a5),d1
moveq #0,d0
move.w -22(a5),d0
move.l _Window,a0
move.l 50(a0),a1
movea.l _GfxBase,a6
jsr _LVODraw(a6)
bra .37
;We weren't in PenMode, but we still might
;be rubberbanding a box. If so, then we
;should erase the current rubberbox and
;draw a new one with the new mouse coords.
;
;if( RubberBox )
.88 tst.w -48(a5)
beq .37
;erase the old rubberbox - draw mode is COMPLEMENT
;DrawBox( TLX, TLY, OldBRX, OldBRY, Window, DrawColor );
moveq #0,d0
move.b -5(a5),d0
move.l d0,-(sp)
move.l _Window,-(sp)
moveq #0,d0
move.w -10(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -8(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -14(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -12(a5),d0
move.l d0,-(sp)
bsr DrawBox
lea 24(sp),sp
;assign new values to box coords */
;OldBRX = x; OldBRY = y;
move.w -22(a5),-8(a5)
move.w -24(a5),-10(a5)
;and draw the new rubberbox */
;DrawBox( TLX, TLY, OldBRX, OldBRY, Window, DrawColor );
moveq #0,d0
move.b -5(a5),d0
move.l d0,-(sp)
move.l _Window,-(sp)
moveq #0,d0
move.w -10(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -8(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -14(a5),d0
move.l d0,-(sp)
moveq #0,d0
move.w -12(a5),d0
move.l d0,-(sp)
bsr DrawBox
lea 24(sp),sp
bra .37
;====================== PROGRAM CLEANUP AND EXIT ========================
.38
;It must be time to quit, so we have to clean up and exit.
IFNE TALKTOREXX
;With Rexx, we need to bring the port down. You must call freeRexxPort before
;doing any exit() for programs that have multiple paths to exit.
move.l a5,-(sp)
lea _rexxPort,a5
movea.l _rexxBase,a6
jsr _LVOFreeRexxPort(a6)
movea.l (sp)+,a5
ENDIF
;---Clear our MenuStrip
movea.l _Window,a0
movea.l _IntuitionBase,a6
jsr _LVOClearMenuStrip(a6)
;---Close our Window
move.l _Window,a0
jsr _LVOCloseWindow(a6)
;---Close the RexxApp lib
CLSE movea.l _SysBase,a6
IFNE TALKTOREXX
movea.l _rexxBase,a1
jsr _LVOCloseLibrary(a6)
ENDIF
;---Close Graphics and Intuition
CLSE2 movea.l _IntuitionBase,a1
jsr _LVOCloseLibrary(a6)
movea.l _GfxBase,a1
jsr _LVOCloseLibrary(a6)
;---exit the program
pea 1
jsr _exit
add.w #4,sp
unlk a5
rts
SetBounds:
;---MinX = Window->BorderLeft
move.l _Window,a0
move.b 54(a0),d0
ext.w d0
move.w d0,_MinX
;---MinY = Window->BorderTop
move.b 55(a0),d0
ext.w d0
move.w d0,_MinY
;---MaxX = Window->Width - Window->BorderRight - 1
move.w 8(a0),d0
move.b 56(a0),d1
ext.w d1
sub.w d1,d0
subq.w #1,d0
move.w d0,_MaxX
;---MaxY = Window->Height - Window->BorderBottom - 1
move.w 10(a0),d0
move.b 57(a0),d1
ext.w d1
sub.w d1,d0
subq.w #1,d0
move.w d0,_MaxY
rts
IFNE TALKTOREXX
;Now we get into the actual code necessary for our REXX port; functions
;that do the real work. Note that this program was not structured
;particularly nicely for Rexx. I had to write each of these functions.
;Many programs have these subroutines already in place. They are called
;as part of the event loop. This program, however, just has one big
;IDCMP loop in main with different actions . . .
;********************************************************************
;This is our REXX dispatch function. This is called whenever some other appli-
;cation has sent us an Arexx msg with a command that our program understands.
;The ARexx app lib has already determined which command, and set up a3 as
;the address of the appropriate handler. We now check to make sure a Window
;currently exists. Then, we store away the `current color' and change it to
;Rexx's current color, call our handler function, and then restore the color.
;If our handler replies, it sets userreplied to indicate that. If the parse and
;everything else was successful, we send an rm_Result of 0 (via setupResults).
;Otherwise, we send a failure of 20 to ARexx server to indicate that the args
;were messed up. We always return TRUE, because we don't have an instance of
;needing to hold onto a Rexxmsg after we use it here. Note that we must not
;alter register a5, but a2, a3, and a4 are OK to scratch.
;
;myDispatch(Rexxmsg, asscListVector, string, RexxDataBase)
; a2 a3 a4 a5
XDEF myDispatch
myDispatch:
;---Make sure that our window is open
move.l _Window,d0
beq.s 1$
;---Initially, error = 0 (indicate no error with getting args from Argstring)
clr.l error
;---Initially, no returned Result string
clr.l ResultStr
;---Save window's current PenA
move.l d4,-(sp)
movea.l d0,a0
movea.l 50(a0),a1
moveq #0,d4
move.b 25(a1),d4
;---Set PenA to currrexxcolor
move.l _currrexxcolor,d0
movea.l _GfxBase,a6
jsr _LVOSetAPen(a6)
;---Call our vector for this rexx command
movea.l a4,a0 ;put Argstring in a0 too
jsr (a3)
;---Restore PenA
move.l d4,d0
movea.l _Window,a0
movea.l 50(a0),a1
movea.l _GfxBase,a6
jsr _LVOSetAPen(a6)
move.l (sp)+,d4
;---if error = 0 (success), SetupResults(Rexxmsg, 0, 0, ResultStr)
movea.l ResultStr,a0
move.l error,d0 ;primary return
bne.s 1$
moveq #0,d1
3$ movea.l a2,a1
movea.l _rexxBase,a6
jsr _LVOSetupResults(a6)
;---Tell the lib to reply it now
moveq #1,d0
rts
;---ERROR: SetupResults(Rexxmsg, error, 10, NULL)
1$ moveq #10,d1
suba.l a0,a0 ;no return Argstring
bra.s 3$
;*******************************************************
;This handler sets the current rexx color.
;
;rexxcolor(Rexxmsg, string)
; a2 a0,a4
XDEF rexxcolor
rexxcolor:
;---Get 1 number from the ascii string
bsr.s getnm
move.l d0,_currrexxcolor
rxout rts
;***********************************************************************
;This function takes an address of a string (in a0), parses the next number
;(ie converts the next ascii digits into a numeric value), returns it in d0,
;and advances a0 to point to the next char after the last ascii digit. If
;there are no ascii digits in the string at all (if we called this function
;then we must have expected some), then set error to indicate an error in
;this ARexx supplied string (ie there's an arg missing from this ARexx line).
;
;number,string = getnm(string)
; d0 a0 a0
XDEF getnm
getnm:
;---value = 0
moveq #0,d0
moveq #0,d1
;---If between '0' to '9'
2$ move.b (a0)+,d1
beq.s 3$
subi.b #'0',d1
bcs.s 2$
cmp.b #9,d1
bhi.s 2$
5$ mulu.w #10,d0
add.l d1,d0
move.b (a0)+,d1
beq.s 6$
subi.b #'0',d1
bcs.s 6$
cmp.b #9,d1
bls.s 5$
subq.l #1,a0
4$ rts
;---No ascii chars to convert
3$ move.b #20,error+3 ;indicate an error upon return to myDispatch of level 20
6$ subq.l #1,a0
rts
;**********************************************************************
;This function trys to find `numArgs' numeric arguments in the command
;string, and stuffs them into the args array.
;
;parseargs(string, numArgs)
; a0 d0
XDEF parseargs
parseargs:
move.l d4,-(sp)
move.l d0,d4
lea Points,a1
bra.s 2$
1$ bsr.s getnm
move.l d0,(a1)+
2$ dbra d4,1$(pc)
move.l (sp)+,d4
rts
;***********************************************************************
;This function silently clips the x and y values of the passed Point
;structure to the current window bounds. My Point is defined as so:
;
;X dc.l [x pixel position of the Point]
;Y dc.l [y pixel position]
;
;clipxy(LineStruct)
; a0
XDEF clipxy
clipxy:
;---Check that Rectangle[leftX] > MinX
moveq #0,d1
move.w _MinX,d1
move.l (a0),d0
cmp.l d0,d1
bls.s 1$
move.l d1,d0
;---Check that Rectangle[leftX] < MaxX
1$ move.w _MaxX,d1
cmp.l d0,d1
bcc.s 2$
move.l d1,d0
2$ move.l d0,(a0)+
;---Check that Rectangle[topY] > MinY
move.w _MinY,d1
move.l (a0),d0
cmp.l d0,d1
bls.s 3$
move.l d1,d0
;---Check that Rectangle[topY] < MaxY
3$ move.w _MaxY,d1
cmp.l d0,d1
bcc.s 4$
move.l d1,d0
4$ move.l d0,(a0)+
rts
;*************************************************************************
; This gets 4 numbers from the passed ascii string and stores them in the
; Rectangle array (4 LONGS). It then clips the Rec to the window dimensions.
;
;leftX dc.l [the left x pixel position of the rectangle]
;topY dc.l [the upper y pixel position]
;rightX dc.l [the right x]
;bottomY dc.l [the bottom y pixel position]
;
;Note that I treat the Rectangle structure as two adjacent Point structures
;
;GetBoxCoords(string)
; a0
GetBoxCoords:
;---Parse 4 numbers from the ARexx string into a Rectangle structure
moveq #4,d0
bsr.s parseargs
;---Check the leftX and topY coords
lea Points,a0
bsr.s clipxy
;---Now check the rightX and bottomY coords
bra.s clipxy
;***********************************************************
;This handler parses 4 numbers into Rectangle struct and draws a wireframe box.
;
;rexxbox(Rexxmsg, string)
XDEF rexxbox
rexxbox:
bsr.s GetBoxCoords
;DrawBox(args[0], args[1], args[2], args[3], Window, currrexxcolor)
move.l _currrexxcolor,-(sp)
move.l _Window,-(sp)
move.l Points+12,-(sp)
move.l Points+8,-(sp)
move.l Points+4,-(sp)
move.l Points,-(sp)
bsr DrawBox
lea 24(sp),sp
unlk a5
rts
;******************************************************************
; This handler parses 4 numbers into Rectangle struct and draws a filled box.
;
; rexxfbox(Rexxmsg, string)
XDEF rexxfbox
rexxfbox:
movem.l d2/d3,-(sp)
bsr.s GetBoxCoords
;---Get 4 corners and error check
move.l Points+12,d3
move.l Points+8,d2
move.l Points+4,d1
move.l Points,d0
cmp.l d2,d0
bls.s 1$
exg.l d0,d2
1$ cmp.l d3,d1
ble.s 2$
exg.l d1,d3
;---Draw box
2$ movea.l _Window,a0
movea.l 50(a0),a1
movea.l _GfxBase,a6
jsr _LVORectFill(a6)
movem.l (sp)+,d2/d3
rts
;*********************************************************************
;This handler grabs four numbers from the Rexxstring and draws a line
;We interprete the 4 numbers as X and Y pixel start positions, and X and Y end
;positions.
;
;rexxline(Rexxmsg, string)
XDEF rexxline
rexxline:
bsr GetBoxCoords
;---Move to start position
move.l Points+4,d1
move.l Points,d0
movea.l _Window,a0
movea.l 50(a0),a1
movea.l _GfxBase,a6
jsr _LVOMove(a6)
;---Draw to end position
move.l Points+12,d1
move.l Points+8,d0
movea.l _Window,a0
movea.l 50(a0),a1
jmp _LVODraw(a6)
;**********************************************************
;This handler pops the window to front.
;
;rexxtofront(Rexxmsg, string)
XDEF rexxtofront
rexxtofront:
movea.l _Window,a0
movea.l _IntuitionBase,a6
jmp _LVOWindowToFront(a6)
;******************************************************************
;This handler pops the window to back.
;
;rexxtoback(Rexxmsg, string)
XDEF rexxtoback
rexxtoback:
movea.l _Window,a0
movea.l _IntuitionBase,a6
jmp _LVOWindowToBack(a6)
;***************************************************************
;This handler sets the exit flag.
;
;rexxexit(Rexxmsg, string)
XDEF rexxexit
rexxexit:
clr.w _KeepGoing
suba.l a0,a0 ;no returned Result string
rts
;**************************************************************
;This handler returns the version of the program.
;
;rexxversion(Rexxmsg, string)
XDEF rexxversion
rexxversion:
;---Setup the address of VERSION as the returned Argstring
; Note that this is our only example of returning a Result string
lea VERSION,a0
move.l a0,ResultStr
rts
;***********************************************************************
;This handler sends the rest of the command asynchronously, allowing us to
;run macros in parallel. Note that the App lib strips leading whitespace from
;the Argstring, so we don't have to do that here.
;
;rexxspawn(Rexxmsg, string)
XDEF rexxspawn
rexxspawn:
;string in a0
movea.l _rexxBase,a6
jmp _LVOASyncRexxCmd(a6)
;*************************************************************************
; The error routine for Rexxmsgs that we sent out and were returned with an
; error. The error message is in a0 and the error code is in d0. Let's just
; print out the message in the title bar.
printRexxErr:
movea.l _IntuitionBase,a6
movea.l a0,a1
movea.l _Window,a0
move.l a2,-(sp)
suba.l a2,a2
jsr _LVOSetWindowTitles(a6)
movea.l (sp)+,a2
rts
;*************************************************************************
; The Result routine for Rexxmsgs that we sent out and were returned success-
; fully. The Result string is in a0 (or NULL if none) and the Result1 code is
; in d0. Let's just print out the message in the title bar (if not 0) since
; we really don't have any rexx handlers that expect returned strings.
doResult:
move.l a0,d1
bne.s printRexxErr
rts
ENDIF
; SECTION FDdata,DATA ;some asms may need this uncommented
_Window dc.l 0
_MinX dc.w 0
_MinY dc.w 0
_MaxX dc.w 0
_MaxY dc.w 0
_KeepGoing dc.w 1 ;when this is a 0, we exit
XDEF _IntuitionBase,_GfxBase
_IntuitionBase dc.l 0
_GfxBase dc.l 0
; This is the Window structure declaration. Nothing fancy is going on here,
;but note the Flags and IDCMPFlags members of the structure define which
;messages will be sent by Intuition. I haven't used them all and if you want
;to change the settings you should probably do it here instead of using
;ModifyIDCMP later.
XDEF _NewWindow
_NewWindow:
dc.w 10,10,600,180
dc.b 0,1
;CLOSEWINDOW | MOUSEMOVE | MOUSEBUTTONS | MENUPICK | NEWSIZE | INACTIVEWINDOW
dc.l $8031a
;WINDOWCLOSE | SMART_REFRESH | ACTIVATE | WINDOWDRAG | WINDOWDEPTH | WINDOWSIZING | REPORTMOUSE
dc.l $120f
dc.l 0,0
dc.l WindowTitle
dc.l 0,0
dc.w 100,35,-1,-1
dc.w 1
;****************************** MENUS ********************************
_menu1 dc.l _menu2
dc.w 10,0,50,10,1
dc.l Color
dc.l _coloritem
dc.w 0,0,0,0
_menu2 dc.l 0
dc.w 65,0,85,10,1
dc.l DrawMode
dc.l EraseItem
dc.w 0,0,0,0
;================= Menu Items For DrawMode Menu =================
EraseItem:
dc.l HollowItem
dc.w 0,0,112,10
dc.w 146 ;ITEMTEXT|ITEMENABLED|HIGHBOX
dc.l 0
dc.l EraseText
dc.l 0
dc.b 0,0
dc.l 0
dc.w 0
HollowItem:
dc.l FilledItem
dc.w 0,10,112,10
dc.w 146
dc.l 0
dc.l HollowBoxText
dc.l 0
dc.b 0,0
dc.l 0
dc.w 0
FilledItem:
dc.l PenItem
dc.w 0,20,112,10
dc.w 146
dc.l 0
dc.l FilledBoxText
dc.l 0
dc.b 0,0
dc.l 0
dc.w 0
PenItem:
dc.l 0
dc.w 0,30,112,10
dc.w 146
dc.l 0
dc.l PenDrawText
dc.l 0
dc.b 0,0
dc.l 0
dc.w 0
EraseText:
dc.b 0,1,1,0
dc.w 0,1
dc.l 0,EraseAll,0
HollowBoxText:
dc.b 0,1,1,0
dc.w 0,1
dc.l 0,HollowBox,0
FilledBoxText:
dc.b 0,1,1,0
dc.w 0,1
dc.l 0,FilledBox,0
PenDrawText:
dc.b 0,1,1,0
dc.w 0,1
dc.l 0,PenDraw,0
;******************************************************
; Color Select Menu *
; *
; This is where the menu for color selection is *
; defined. It should be flexible enough to allow for *
; increased palette sizes, but this version is only *
; for the 4-color mode of the WorkBench screen. *
_coloritem ds.b 136
_colorimage ds.b 80
;array of palette sizes to correspond with depth of window in bit-planes
_palette dc.b 0,2,4,8,16,32
IFNE TALKTOREXX
;These first 6 variables are only needed by this program and are not required
;by the Rexx App lib. (ie they exist merely for the use of FreeDraw's ARexx
;handlers)
;the base of rexxapp.library
_rexxBase dc.l 0
;A buffer into which we place the user's command string for ARexx
ArexxCmdStr ds.b 256
;The address of the Result string
ResultStr dc.l 0
;What color is *rexx* drawing in?
_currrexxcolor dc.l 1
;what args did we see to this function? MAX 4 LONGS
Points ds.l 4
;was argument parsing successful? A 0 if so, a 1 for error
error dc.l 0
;******************************** RexxData *********************************
; This part is the mandatory data section needed by the Rexx App lib. Whenever
; you call a function in this library, register a5 must be setup with the base
; of this data block (ie lea _rexxPort,a5). The data must be in this order
; up to the end of the association list! Note that the association list can
; be any length as long as it ends with a 0 LONG.
;
; For another program, you will need to alter the command association list
; (and the strings for it). Also, change RexxMacroExt and RXname. If you call
; your Dispatch, Error, and Result vector routines the same as I did, then you
; won't need to alter the variables dispatchFunc, ErrorVector and ResultVector.
;These are the offsets from the base of the data (ie from _rexxPort)
mr_RexxPort equ 0 ;The imbedded RexxPort (to be setup by SetRexxPort)
mr_RxName equ 10 ;DO NOT ALTER
mr_RxSig equ 15 ;DO NOT ALTER
mr_RxTask equ 16 ;DO NOT ALTER
mr_Flags equ 32 ;DO NOT ALTER the highest 4 bits (4-7)
mr_MsgsOut equ 33 ;how many RexxMsgs this app created and has not received back (DO NOT ALTER)
mr_Exten equ 34 ;the extension for invoking Rexx scripts
mr_Func equ 38 ;a routine to handle received RexxMsg's from some other application
mr_RxsLib equ 42 ;the lib base of ARexx server library (DO NOT ALTER)
mr_ErrorV equ 46 ;a routine for error return of a RexxMsg the app created and sent
mr_Return equ 50 ;a routine for successful return of a RexxMsg the app created and sent
mr_RexxMask equ 54 ;signal mask of the Rexx port's mp_SigBit
mr_UserData equ 58 ;for application's use
mr_AsscList equ 62 ;the imbedded association list
CNOP 0,2
XDEF _rexxPort
;Our Rexx port
_rexxPort:
dc.l 0,0
dc.b 4,0
dc.l RXname
dc.b 0
dc.b -1 ;This is negative (bit 7 set) whenever our port isn't set up
dc.l 0
rxmsg dc.l rxmsg+4
dc.l 0
dc.l rxmsg
dc.b 0 ;DO NOT ALTER THESE LAST 2 BYTES OF THE PORT
dc.b 0
;extension is the address of a null-term file extension string for ARexx macros
;invoked by this program. If not 0, any `primitive' not in the association
;list will be sent out to ARexx for interpretation, thus allowing macro
;programs to work just like primitives. If you do not want this behavior,
;supply a 0 here, and those commands not specified in your association list
;will be sent back to ARexx with an error value of RXERRORNOCMD. It should be
;noted that extension should point to a nulled string if no particular
;extention is desired. Here, I've set it to point to 'fd',0
extension dc.l RexxMacroExt
;dispatchFunc is the address of the app's Dispatch function. This function
;will *only* be called by the library when the application calls ReceiveRexx().
;Anytime a command match is found in the association list, this function will
;be called with 3 arguments--- the Rexx message that was received (a2), a
;pointer to the association jmp vector in a3 (ie the handler to be executed),
;and the Argstring in a4 (ARG0) stripped of the command. This function should
;return a 1 if the message is to be replied to by the lib or a 0 if not. If
;not, the application itself is responsible for replying the message later via
;Exec's ReplyMsg(). Otherwise, the library ALWAYS takes care of properly
;replying all messages. (Freedraw lets the lib take care of all replies. Unless
;you need to hold onto a Rexxmsg and consequently "put the Rexx script to
;sleep" until you reply it later, you'll let the lib take care of replies.
;Also, the app should setup the return values with SetupResults().
dispatchFunc dc.l myDispatch
;Address of rexxsyslib.library (DO NOT ALTER)
_RexxSysBase dc.l 0
;This routine is called when each msg that the application created and sent out
;is returned with an error. It is passed an appropriate error message in a0,
;and the error code in d0. Typically, this routine needs to do nothing more
;than print the message for the user. You must supply at least a dummy routine.
ErrorVector dc.l printRexxErr
;This routine is called when each msg that the application created and sent out
;is returned successfully. It is passed any returned Result string in a0,
;and the Result1 code in d0. This routine may do various things with the
;Result1 string or code depending upon which function initially sent the
;message out. You must supply at least a dummy routine.
ResultVector dc.l doResult
;The mask of our rexxPort's SigBit (used by our app to wait for Arexx msgs)
RexxMask dc.l 0
;The application can do anything with this
dc.l 0
;Here is our command association list. This is simply a table of LONGS. Each
;two LONGS is an entry for a REXX command. For example, the first 2 LONGS in
;the table are for the first REXX command. Remember that REXX commands are
;null-terminated strings. The first LONG is the address of the command string.
;For example, in our command association list for FreeDraw, the first long
;points to the string "color". The next LONG is the address of the function
;that implements the REXX command. For example, the next LONG points to the
;function, rexxcolor. Now whenever we receive a REXX msg with its command
;string being "color", we jsr to the function, rexxcolor. This is the way the
;Rexx app lib determines whether a received Rexxmsg holds a legitimate command
;for our application. For another program, you simply make a new association
;list (and write the respective handlers). This list MUST end with a 0 LONG.
;Please note that your command strings must also be lower case letters (and
;only letters with no imbedded spaces). You will probably also write a new
;dispatch function (modeled after myDispatch), since you may need to do other
;things besides change window colors, check for an open window, etc like what
;FreeDraw needs to do with its ARexx implementation.
XDEF myAsscList
myAsscList:
;"color"
dc.l color
dc.l rexxcolor
;"box"
dc.l box
dc.l rexxbox
;"fbox"
dc.l fbox
dc.l rexxfbox
;"line"
dc.l line
dc.l rexxline
;"tofront"
dc.l tofront
dc.l rexxtofront
;"toback"
dc.l toback
dc.l rexxtoback
;"exit"
dc.l exit
dc.l rexxexit
;"version"
dc.l version
dc.l rexxversion
;"spawn"
dc.l spawn
dc.l rexxspawn
;END OF LIST
dc.l 0
;The following data can be placed anywhere, and will change for another application
;These are the command strings that we will accept ARexx msgs for
color dc.b 'color',0
box dc.b 'box',0
fbox dc.b 'fbox',0
line dc.b 'line',0
version dc.b 'version',0
spawn dc.b 'spawn',0
exit dc.b 'exit',0
tofront dc.b 'tofront',0
toback dc.b 'toback',0
;This is the name of our Rexx port, and is used with the ADDRESS command
;within a Rexx macro to find this app's rexx port. This must be unique for
;every Rexx application. Note that if the user runs 2 copies of FreeDraw,
;the second port's name will be "freedraw2". Also, note that we have an extra
;null byte on the end of our name. THIS EXTRA BYTE IS REQUIRED!
RXname dc.b 'freedraw',0,0
RexxMacroExt dc.b 'fd',0 ;the macro extention desired for ARexx
RexxName dc.b 'rexxapp.library',0
ENDIF
;********************** END OF MANDATORY REXX DATA **********************
GfxName dc.b 'graphics.library',0
IntuiName dc.b 'intuition.library',0
VERSION dc.b 'Freedraw 0.01 by Richard M. Ross',0
WindowTitle dc.b 'AMIGA FreeDraw 0.01',0
Color dc.b 'Color',0
DrawMode dc.b 'DrawMode',0
EraseAll dc.b 'Erase All',0
HollowBox dc.b 'Hollow Box',0
FilledBox dc.b 'Filled Box',0
PenDraw dc.b 'Pen Draw',0
END