; ; File: ScrollBarCDEF.a ; ; Contains: This file contains the control definition procedure ; that defines scrollBar-type dials. ; ; Written by: Andy Hertzfeld August, 1982; color interface by Chris Derossi ; ; Copyright: © 1982-1994 by Apple Computer, Inc., all rights reserved. ; ; This file is used in these builds: BigBang ; ; Change History (most recent first): ; ; 2/1/94 SWC Changed the entry code for setting up the drawing environment to ; only do that for calls that will actually be doing some drawing. ; This is to prevent the situation where a ŌclutÕ resource is ; continuously being loaded (by GetCTable) and unloaded (by ; DisposeCTable) when all that's being done is hit testing, region ; calculations, etc. This fixes a problem when running Microsoft ; Excel 4.0 on a PowerBook: since the resource was always being ; purged, GetResource ended up doing a disk read, which registers ; as machine usage to the Power Manager, and thus the PowerBook ; never auto-sleeps. A beneficial side effect for desktop machines ; is that running thru this code will now be a bit faster. While I ; was at it, changed word branches to short branches, where ; appropriate. ; 6/7/93 CSS Resupport drawthumboutline and make it do something different ; for ROM (render a rgn instead of a rect). ; 4/30/93 CSS DragTheRgn now will drag a black outline instead of a yellow one ; when dragging the scroll bar thumb. So, take out . Also, ; desupported the DrawThumbOutline Message which was for the hack ; on FrameRect which we no longer do. ; 4/21/93 CSS Implement a custom dragging routine so that we can draw a black ; box instead of a yellow one (the standard dragging in ; dragcontrol uses dragthergn which uses xor and creates a nice ; yellow color in 256 colors). This routine will use hilite mode ; in color and notpatxor in black&white. This was implemented in ; 7.1 as a nice comefrompatch hack on _FrameRect (e.g. if we are ; dragging and if we came from _DragControl... you get the idea). ; 11/19/92 RB Set ROMMapInsert to mapTrue to look for resources in ROM first ; when doing GetResource calls. ; <36> 5/30/91 DTY We look for things to make it go faster. ; <35> 4/11/91 gbm dba, ws#-dba041001: Stop trying to do fancy offscreen stuff to ; buffer screen drawing if we're not actually drawing to the ; screen! ; <34> 3/4/91 dba dty: get rid of SysVers conditionals ; <33> 3/1/91 VL DFH, #83253: Rolled out changes in <32> as the fix only obscures ; the crashing problem without solving it. The real problem which ; trashes D0 before SetupColors in @DrawShadedArrowBox is now ; fixed. ; <32> 2/28/91 DFH VL,#83253: Made sure to use long word operations to calculate ; addresses from offsets. Was using word-sized, which caused ; intermittent crashes, since result was incorrect. ; <31> 2/5/91 stb gs: include MenuMgrPriv.a ; <30> 1/25/91 VL dho, #VL002: HitSBar should return 0 if the scroll bar is ; inactive (including the case when its hilite value is 254). ; <29> 1/14/91 VL (dba) Hilite 254 should draw in black instead of gray due to ; compatibility problems in List Manager and Finder/App interface. ; <28> 1/14/91 VL Put in Hilite 254 (which draws only the gray outline). ; Removed IsCtlDisabled since we don't need it to check for 254 ; and 255. ; <27> 1/13/91 VL Removed a line accidentally put in for testing. ; <26> 1/13/91 VL Add a new message to draw the outline of the thumb ; during dragging. ; <25> 12/12/90 VL (gbm) Don't switch to WMgrCPort when drawing a picture. This is ; done by checking picSave of the owner of the control. ; <24> 10/8/90 VL Do a PenNormal to WMgrCPort before drawing to it. Draw ; background of arrow in gray of darker shade when enabled. ; <23> 9/23/90 VL Ignore <14> and <21>. This fixed the HiliteControl(255) problem ; for good (I hope). It checks to see whether the control is ; inactive. If it is inactive (i.e. contrlHilite is 254 or 255), a ; gray box will be drawn. Otherwise, the whole scroll bar will be ; drawn. ; <22> 9/23/90 VL Draw everything even though the part code is inThumb. This is so ; because a lot of apps (including FileMaker and MORE) use ; SetCtlValue which only affects the thumb leaving the arrow boxes ; in an inconsistent state with the thumb. ; <21> 9/20/90 VL Reverted changes to Hilite255 in <14>. Use the variation code (> ; 1) for the Hilite255 (which draws a gray border around the ; erased scroll bar area). ; <20> 9/16/90 csd If the control is not being drawn to the screen, donÕt use ; DeviceLoop, and donÕt switch to the WMgrCPort. ; <19> 9/15/90 VL Switch to sysZone before FillRect so that the pixpat created ; will be persistent. ; <18> 9/15/90 VL Twitched the colors one more time for HI. ; <17> 9/5/90 VL Changed the thumb according to Paulien's design. ; <16> 8/31/90 VL Got rid of pixpat totally to avoid the unnecessary memory ; overhead. ; <15> 8/27/90 VL Got rid of NOP warning. ; <14> 8/24/90 VL Changed Foreground and Background color for copybits in ; transparent mode. Made Hilite255 draw a gray border around the ; erased scroll bar area. Removed unnecessary code for resolving ; the WMgrPort and WMgrCPort. ; <13> 8/22/90 VL Fixed patAlign problems with multiple screens by using SetOrigin ; on the WMgrCPort. Also fixed off-by-one error when called by ; List Manager. ; <12> 8/17/90 VL Fixed pixpat problem by disposing it after fillcrect. Draw ; offscreen to avoid flickering. ; <11> 8/9/90 VL Did some smart drawing to reduce flickering. ; <10> 8/7/90 DTY Tweaked the colors a bit so the scroll bars look more like ; PaulineÕs drawings. ; <9> 8/6/90 VL Another rewrite for color/shaded scroll bars ; (drawing to WMgrCPort, tinged symbols, pix pattern ....) ; <8> 7/20/90 gbm get rid of an Asm warning ; <7> 5/29/90 DDG NEEDED FOR SIXPACK: Added back the 32-bit clean messages to the ; system six portion of the file. ; <6> 5/29/90 DDG NEEDED FOR SIXPACK: Rolled over a bug fix from the old 6.0.5 ; split off sources into the system six portion of the file. Also ; removed the new messages for the 32-bit clean control manager ; from the 6.x portion of the file. Finally, changed the version ; number of the system seven CDEF. ; <5> 4/19/90 csd initialize tempPixels(A6) to nil so that HUnlock doesnÕt blow ; up; renumbered owned resources to be in the correct range. ; <4> 4/13/90 csd Disabled (temporarily) the color interface by requiring 33 ; bits/pixel in CheckAvailableColors. ; <3> 4/12/90 HJR Fix undefined sysvers for rom builds. ; <2> 4/11/90 csd Major rewrite to support shaded scroll bars and _DeviceLoop. ; <1.3> 8/22/89 SES Removed references to nFiles. Updated equates accordingly. ; <1.2> 2/9/89 EMT added new messages for 32-bit clean Control Manager. ; <1.1> 11/11/88 CCH Fixed Header. ; <1.0> 11/9/88 CCH Adding to EASE. ; <„1.1> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles ; <1.0> 2/12/88 BBM Adding file for the first time into EASEÉ ; 1/26/87 DAF Universal defproc (Version 10) ; 12/14/86 DAF Fixed a trashed register ; 10/6/86 DAF Updated color support on nuMac to RGBColor ; 4/28/86 DAF Workshop->MPW, added color support for Reno ; 7/29/85 EHB converted back to porkshop ; 5/16/85 EHB Only return "254" if point in control! ; 4/18/85 EHB Eliminated useless framerects in DrawSBar ; 2/14/85 JTC named rsrc. ; 1/11/85 JTC convert to MDS ; 4/13/84 SC Replaced _EraseRgn with _FillRgn,white ; 12/27/83 AJH Made min=max act disabled; added "254" hiliting ; 11/11/83 AJH Made it redraw all if disabled ; 11/10/83 AJH Changed disabling -- don't fill with gray ; 10/8/83 AJH Changed rounding to fix "off by 1" bug ; 9/4/83 AJH Made it respond to message 8 (just a stub) ; 7/30/83 SC Variant 1 for microsoft - no grey or elevator (Yuck) ; 12/30/82 AJH Changed hystersis for thumbDrag to 24 pixels ; 12/28/82 AJH Put scrollBar definition proc in its own file ; 11/16/82 AJH Made branch tables offset based ; 11/14/82 AJH removed box in arrowBits ; 11/11/82 AJH fixed thumb scaling problem in CalcIBox (subtract min) ; 11/7/82 AJH Made wide scrollBars look better ; 10/17/82 AJH Made controlProcs preserve A1 ; 10/10/82 AJH Converted for QuickDraw Trap Interface ; 10/3/82 AJH Fixed bug in scrollBar positioning -- wasn't ctl relative ; 9/19/82 AJH Re-arranged ScrollBar proc, removed DragThumb ; 8/31/82 AJH Added hysterisis to scrollBar, rounding to value calculations ; 8/29/82 AJH Added "255" hiliting, non-rectangular indicators to ; ScrollBarProc ; ; To Do: ; STRING ASIS LOAD 'StandardEqu.d' INCLUDE 'colorEqu.a' INCLUDE 'ControlPriv.a' INCLUDE 'MenuMgrPriv.a' CDEF1 PROC EXPORT ; ; FUNCTION ScrollBarProc( theControl: ControlHandle; ; message: INTEGER; ; param: LongInt): LongInt; ; ; ------------- RGBInfo record TYPE ------------- RGBInfoRec RECORD 0 ; RGBColor record type red ds.w 1 green ds.w 1 blue ds.w 1 ENDR ; And a stack frame definition StackFrame RECORD {A6Link},DECR ; build a stack frame record ProcResult ds.l 1 ; function's result returned to caller ParamBegin EQU * ; start parameters after this point ; parameters on stack varCode ds.w 1 ; <26> CtlHndl ds.l 1 ; ControlHandle message ds.w 1 ; operation to perform param ds.l 1 ; addition information based on message ParamSize EQU ParamBegin-* ; size of all the passed parameters RetAddr ds.l 1 ; place holder for return address A6Link ds.l 1 ; place holder for A6 link ; local variables being allocated SavePen ds.b psRec ; <24> onScreen ds.b 1 ; are we rendering on the screen? isColor ds.b 1 ; is this a color system? IndicatorRect ds.w 4 AuxCtlHndl ds.l 1 AuxCtlPtr ds.l 1 SavFgCol ds RGBInfoRec ; saved WMgrCPort ForeColor (color only) SavBkCol ds RGBInfoRec ; saved WMgrCPort BackColor (color only) shaded ds.w 1 ; conditions right for shaded controls? curDepth ds.l 1 ; current drawing depth for SetupColor startRGB ds.w 3 endRGB ds.w 3 tempRGB ds.w 3 workPixMap ds.l 1 workCLUT ds.l 1 ; Colour table to attach to PixMap tempPixels ds.l 1 controlRgn ds.l 1 ; region control occupies isHoriz ds.w 1 ; 0 if vertical, 2 if horizontal oldstylePort ds.l 1 ; temporary storage for the old-style port when drawing directly to WMgrCPort wMgrCPortClipRgn ds.l 1 ; temporary storage for WMgrCPort clip region wMgrCPortFgColor ds.w 3 ; temp storage for WMgrCPort RGBForeColor wMgrCPortBkColor ds.w 3 ; temp storage for WMgrCPort RGBBackColor wMgrCPortPenState ds.b psRec ; temp storage for WMgrCPort pen state <24> globalOffset ds.l 1 ; offset of current port from the WMgrCPort tempRgn ds.l 1 ; temp work region for figuring out clip region for WMgrCPort LinkSize EQU * ; size of all the local variables ENDR cHThumbBitmap equ 8 cVThumbBitmap equ 9 kPixmapID equ -10208 kClutID equ -10208 ; Resource IDs for scroll bar parts kVerticalThumb equ -10208 kHorizontalThumb equ -10207 kSolidUpArrow equ -10206 kHollowUpArrow equ -10205 kSolidDownArrow equ -10204 kHollowDownArrow equ -10203 kSolidLeftArrow equ -10202 kHollowLeftArrow equ -10201 kSolidRightArrow equ -10200 kHollowRightArrow equ -10199 ; index to cctb cFillPatColor equ 4 cArrowsLight equ 5 cArrowsDark equ 6 cThumbLight equ 7 cThumbDark equ 8 wHiliteLight equ 9 wHiliteDark equ 10 wTitleBarLight equ 11 wTitleBarDark equ 12 wTingeLight equ 13 wTingeDark equ 14 ; index to the shades lowestShadeIndex equ 16 cArrowShade2 equ 16 wHiliteShade8 equ 17 wTitleBarShade1 equ 18 wTinge0 equ 19 wTinge4 equ 20 wTingeA equ 21 wTingeF equ 22 ; index to table containing pixs info ; Each arrow has 3 pixs (one for the outline, one for the solid and one for the disabled outline). ; If one has the outline index, one can get the disabled outline by (outline index)/2+8. cUpOutlineArrow equ 0 cUpSolidArrow equ 1 cUpDisabledArrow equ 8 cDnOutlineArrow equ 2 cDnSolidArrow equ 3 cDnDisabledArrow equ 9 cLtOutlineArrow equ 4 cLtSolidArrow equ 5 cLtDisabledArrow equ 10 cRtOutlineArrow equ 6 cRtSolidArrow equ 7 cRtDisabledArrow equ 11 cVThumbPat equ 12 cHThumbPat equ 13 ; fakeDeviceFlags is used when we bypass DeviceLoop and draw the control directly, and weÕre ; on a machine that doesnÕt have Color QuickDraw. fakeDeviceFlags equ $A801 ; Hilite mode - this should be in an interface file somwhere hilite equ 50 ; Here is the dispatch table for the scrollBar definition procedure, which implements ; semi-Lisa style scrollBar type controls for the Mac toolBox. It shares a common ; dispatcher with the pushButton proc (see above) with StackFrame BRA.s @0 DC.w 1 DC.b 'CDEF' DC.w 1 DC.w 11 ; version # @0 LINK A6,#LinkSize ; set up a stack frame to address parameters moveM.l D3-D6/A1-A4,-(SP) ; save work registers ; test if the message is in range cmp.w #drawThumbOutlineMsg,message(A6) ; compare to highest value bhi.s OORange ; We respond to 0-12 <1.2> @MsgOK ; save the penState and set it our way PEA SavePen(A6) ; push pointer to savePenState _GetPenState ; remember current penState _PenNormal ; set the pen the way we want it ; fetch the parameters into registers lea 8(A6),A0 ; get ptr to first parameter move.l (A0)+,D3 ; get param in D3 move.w (A0)+,D0 ; get message move.l (A0)+,A3 ; get the control handle move.w (A0)+,D6 ; get selection index clr.l (A0) ; clear out function result move.l (A3),A0 ; get control pointer in A0 ; case out on the message number add D0,D0 ; double for word index lea GoScrollBar,A1 ; get table address add 0(A1,D0),A1 ; compute dispatch address JSR (A1) ; dispatch to appropriate routine ; restore original pen state PEA SavePen(A6) ; push savePenState _SetPenState ; restore original pen state ; we're done -- restore registers and return to caller OORange ; 'Out Of Range, of course' moveM.l (SP)+,D3-D6/A1-A4 ; restore work registers UNLK A6 ; unlink stack frame TenBytExit move.l (SP)+,A0 ; get return address add #12,SP ; strip parameters JMP (A0) ; return to caller JustRTS clr.l ProcResult(a6) ; indicate we didn't handle this message rts GoScrollBar DC.w DrawSBar-GoScrollBar ; draw is message 0 DC.w HitSBar-GoScrollBar ; hit test is message 1 DC.w CalcSBar-GoScrollBar ; calc regions is message 2 DC.w InitSBar-GoScrollBar ; allocate indicator region (3) DC.w DispSBar-GoScrollBar ; de-allocate indicator region (4) DC.w MoveSBar-GoScrollBar ; move indicator call (5) DC.w ThumbSBar-GoScrollBar ; message 6 is thumb dragging DC.w JustRTS-GoScrollBar ; message 7 is thumb dragging custom message DC.w JustRTS-GoScrollBar ; message 8 is not supported DC.w JustRTS-GoScrollBar ; message 9 is not supported DC.w CalcWholeSBar-GoScrollBar; calc whole regions is message 10 <1.2> DC.w CalcThumbSBar-GoScrollBar; calc thumb regions is message 11 <1.2> DC.w DrawThumbOutline-GoScrollBar; <26> ; sets up the drawing environment for calls that do drawing InitDrawingStuff ; ; Determine type of system. We need to know if we have color QuickDraw and a color ; window manager port. cmp.w #$3FFF,ROM85 ; do we have color QD? SLS IsColor(A6) ; set boolean depending on color or B&W system BHI.s @BWSys ; no, this system has B&W QD ; save the current port's colors move.l GrafGlobals(A5),A0 ; get pointer to grafGlobals DAF move.l thePort(A0),A0 ; get pointer to thePort DAF PEA SavFgCol(A6) ; save foreColor _GetForeColor ; PEA SavBkCol(A6) ; save backColor too _GetBackColor ; ; get the CtlAuxRec for this guy and lock it's colortable CLR.l -(SP) ; return the handle here CLR.b -(SP) ; space for boolean func return move.l CtlHndl(A6),-(SP) ; push the control handle PEA 6(SP) ; push a pointer to placeholder _GetAuxCtl ; get its auxRec addQ #2,SP ; don't need boolean result move.l (SP)+,A0 ; get auxCtl handle move.l (A0),A0 ; a pointer to the auxCtlRec move.l acCTable(A0),A0 ; get colortable's handle <1.3> move.l A0,AuxCtlHndl(A6) ; save the handle _HLock ; lock the handle move.l (A0),AuxCtlPtr(A6) ; save a pointer ; ------------- get a pixmap for drawing the gadgets ------------ subq.l #4, SP ; room for a PixMapHandle move.l #'pmap', -(SP) ; the Pixmap resource type move.w #kPixmapID, -(SP) ; ID of working pixmap move.w #MapTrue,RomMapInsert ; rb _GetResource ; look in ROM first rb move.l (SP), workPixmap(A6) ; save it for later move.w #kClutID,-(sp) ; ID of clut for pixmap _GetCTable move.l (sp)+,workCLUT(a6) move.l workPixmap(a6),a0 move.l (a0),a0 move.l workCLUT(a6),pmTable(a0) ; Stash colour table into pmap handle @BWSys clr.l tempPixels(A6) ; init this to NIL rts ; clean up color stuff RestoreDrawingStuff ; tst.b IsColor(A6) ; beq.s @NoColor1 ; if on B&W, then skip move.l AuxCtlHndl(A6),A0 ; unlock the CDEF _HUnlock PEA SavFgCol(A6) ; _RGBForeColor ; PEA SavBkCol(A6) ; _RGBBackColor ; move.l workCLUT(a6),-(sp) _DisposCTable @NoColor1 rts CDefDrawFrame RECORD 0 ; stack frame for DeviceLoop draw proc retAddress ds.l 1 ; return address StartParams EQU * userData ds.l 1 ; long we passed to DeviceLoop devHandle ds.l 1 ; GDevice handle deviceFlags ds.w 1 ; flags for current device depth ds.w 1 ; bits/pixel for this call ParamSize EQU *-StartParams ENDR ; DrawSBar draws a scroll bar as specified by the controlHandle in A3. D3 has the ; desired "hilite" area code. DrawSBar bsr InitDrawingStuff ; initialize the drawing environment ; if we are drawing to the screen, use _DeviceLoop to handle the case of ; multiple monitors. If we are not drawing to the screen, then _DeviceLoop ; could do the wrong thing--just draw the control directly. move.l (A5), A0 ; point to QuickDrawÕs globals move.l thePort(A0), A1 ; get a pointer to the current port <35> lea portBits(A1), A0 ; point to ŅbitmapÓ in the port <35> tst.w rowBytes(A0) ; is this a color port? bpl.s @bitmap move.l baseAddr(A0), A0 ; pixmap handle move.l (A0), A0 ; pixmap pointer @bitmap tst.l picSave(a1) ; are we drawing to a picture? <35> bne.s @notOnScreen ; yes, so it is not a screen no matter what he says <35> move.l ScrnBase, D0 ; get base address of screen cmp.l baseAddr(A0), D0 ; is it the same as thePortÕs ? beq.s @drawToScreen ; if yes, then use DeviceLoop to draw to the screen @notOnScreen clr.b onScreen(a6) ; we are not drawing to the screen <35> move.w #1, -(SP) ; assume old-port, depth equals 1 tst.w rowBytes(A0) ; is this an old-style port? bpl.s @depthOk ; yes. depth of 1 on stack is okay move.w pmPixelSize(A0), (SP) ; fix depth on stack @depthOk move.w #fakeDeviceFlags, -(SP) ; assume non-CQD case clr.l -(SP) ; NIL gDeviceHandle for non-CQD machines btst #6, ROM85 ; Color QuickDraw available? bnz.s @deviceAndFlagsOk ; of not, fake versions on stack are correct move.l theGDevice, A1 ; current device GDHandle move.l A1, (SP) ; fix gdHandle on stack move.l (A1), A1 ; point to the device move.w gdFlags(A1), 4(SP) ; fix gdFlags on stack @deviceAndFlagsOk clr.l -(SP) ; flag clear (not drawing to screen) bsr.s CDefDrawControl ; draw the control bra.s RestoreDrawingStuff ; cleanup after doing drawing @drawToScreen subq #4, SP ; room for RgnHandle _NewRgn move.l (SP), D0 ; get the region handle move.l D0, controlRgn(A6) ; save it for disposal move.l (A3), A0 ; point to control pea contrlRect(A0) ; push controlÕs rect _RectRgn ; make a region of the controlÕs rect st.b onScreen(a6) ; we are drawing to the screen <35> move.l controlRgn(A6), -(SP) pea CDefDrawControl ; address of devloop drawing proc move.l #-1, -(SP) ; flag that weÕre drawing to the screen clr.l -(SP) ; no unusual activities _DeviceLoop move.l controlRgn(A6), -(SP) _DisposRgn bra RestoreDrawingStuff ; cleanup after doing drawing CDefDrawControl with CDefDrawFrame move.w depth(SP), curDepth(A6) ; save this for SetupColor magic move.l devHandle(SP), D1 ; pass this drawing device bsr CheckAvailableColors ; see if we have enough colors and see whether ; we have an old-style grafport on color device tst.l userData(SP) ; are we drawing to the screen? bz.s @dontChangePorts ; if not, donÕt switch to the WMgrCPort bsr SetupWMgrCPort ; see whether we need to use the WMgrCPort. If we ; do, set it up. @dontChangePorts moveq #cFrameColor, D0 ; Set up fore- and backcolors (as a safety precaution) moveq #cBodyColor, D1 bsr SetupColors ; Figure out if the scroll bar is horizontal or vertical and handle each ; case separately. see if its more horizontal or vertical -- A0 points to the ; rect to be tested. D0 returns 0 to select vertical and two to select horizontal. ; After we know which axis, draw the arrows. move.l (A3), A0 ; point to control tst.b ContrlVis(A0) ; is it visible? beq DrawControlExit ; if not, don't draw ; ; Setup the colour table for the gadget images with ramped values from the 'cctb'. ; tst.b shaded(a6) ; Using colour? bz.s @notColour move.l workCLUT(a6),a0 ; Get handle to colour table _HLock move.l (a0),a4 ; Keep pointer to colour table lea 16(a4),a4 ; Point to first tinge entry in colour table lea TingeShades,a2 ; Get table of tinges @tingeSetupLoop tst.w (a2) ; End of tinge table? bz.s @doneWithTingeSetup ; Yes, get out of here. move.l a2,a0 bsr SetupRatioColor ; Get a ramped color move.l tempRGB(a6),2(a4) ; Copy red and green components move.w tempRGB+4(a6),6(a4) ; Copy blue component add.w #16,a4 ; Next tinge entry in table addq #6,a2 ; Next tinge entry in shade table bra.s @tingeSetupLoop @doneWithTingeSetup subq #4,sp _GetCTSeed ; Get a fresh seed move.l workCLUT(a6),a0 move.l (a0),a4 move.l (sp)+,(a4) ; Put new seed in colour table _HUnlock ; And let it float around ; if it was disabled, draw the whole thing @notColour move.l (a3),a0 move.b ContrlHilite(A0),D0 ; get the hilite parameter <28> cmp.b #$FE,D0 ; <28> beq DrawHilite254Ctl ; yes => just draw the frame <28> cmp.b #$FE, D3 ; disabled part code? <28> blo.s @0 ; if not, skip moveq #0, D3 ; if so, draw all @0 move.b ContrlHilite(A0),D4 ; get current hilite in register bsr GetTCtlRect ; copy the control rect into tempRect bsr TestHV ; get horizontal/vertical index in D0 move.w D0, isHoriz(A6) ; save orientation ; adjust for 1st arrow (if we're supposed to) move.w top(A1, D0), D1 ; get vertical coordinate add D2, D1 ; compute bottom move.w D1, bottom(A1, D0) ; update bottom moveq #inUpButton, D1 ; signal 1st arrow movem D0/D2, -(SP) ; remember hv selector bsr ShouldIDraw ; test hilite to see if we should draw bne.s SkipUp move.w #kHollowUpArrow,d0 bsr DrawArrowBox ; draw the arrow box ; now do the other arrow SkipUp bsr GetTCtlRect ; copy bounding rect into tempRect movem (SP)+, D0/D2 ; restore hv selector ; adjust rect for 2nd arrow move Bottom(A1,D0), D1 ; get bottom coordinate sub D2, D1 ; compute top move D1, top(A1,D0) ; adjust box top moveq #inDownButton, D1 ; signal in 2nd arrow bsr ShouldIDraw ; dont't draw if we done have to BNE.s SkipDown move.w #kHollowUpArrow,d0 bsr DrawArrowBox ; draw the arrow box ; paint the body of the scrollBar light gray SkipDown cmp #1,D6 ; flavor one has no grey beq FrameCtl move.w #inThumb,D1 ; get thumb part code bsr ShouldIDraw ; draw it? bne DrawControlExit ; don't need to frame scrollbar bsr GetTCtlRect ; get control bounding rectangle move.l A1,A0 ; put in A0 for TestHV bsr TestHV ; get h/v index swap D2 ; get width in high part move.w #1,D2 ; get 1 in low part tst.w D0 ; which dimension? beq.s @1 ; skip correction if vertical swap D2 @1 move.l A1,-(SP) ; push a pointer to the rectangle move.l D2,-(SP) ; push inset factor _InsetRect ; inset it appropriately bsr CalcIBox ; get the rect for thumb bsr IsDisabled ; is it disabled? bne.s @enabled ; if not, skip tst.b shaded(A6) ; is it shaded? beq.s @whiteOutScrollBar ; no => white it out moveq #cFrameColor,D0 ; yes => set up the shaded color moveq #wTitleBarShade1,D1 ; bsr SetupColors ; PEA TempRect ; push the rectangle _EraseRect ; paint the shade on the scroll bar bra.s DoIndicator ; done drawing background of scroll bar @whiteOutScrollBar PEA TempRect ; push the rectangle move.l (A5),A0 ; get grafGlobals pea White(A0) ; get address of white pattern _FillRect ; white out the rect bra.s DoIndicator ; @enabled lea TempRect,A0 ; get scroll bar rect in A0 for TestHV bsr TestHV ; get the offset to rect in D0 move.l D0,D4 ; save off the values before they get trashed move.l A0,A4 ; move.w 4(A4,D4),-(SP) ; save the right(H)/bottom(V) of scroll bar rect move.w IndicatorRect(A6,D4),4(A4,D4) ; put the left(H)/top(V) of thumb to scroll bar ; Color in the page up and down regions bsr PlotLtGray move.w (SP)+,4(A4,D4) ; restore the right(H)/bottom(V) of scroll bar rect move.w IndicatorRect+4(A6,D4),(A4,D4) ; put the right(H)/bottom(V) of thumb to scroll bar bsr PlotLtGray ; Check the hilite state. If the control is inactive (hilite = 255), don't draw ; the indicator at all. DoIndicator bsr IsDisabled ; is it disabled bz.s FrameCtl ; yes => go frame the control move.l IndicatorRect(A6),TempRect move.l IndicatorRect+4(A6),TempRect+4 tst.b shaded(a6) ; is it shaded bnz.s @drawShadedThumb ; yes => handle shaded thumb move.l #$FFFF0000,d0 ; Inset height tst.w isHoriz(a6) ; Horizontal thumb? bnz.s @thumbIsHorizontal ; Yes swap d0 ; Inset width move.w #cVThumbBitmap,-(sp) ; Remember bitmap offset for vertical thumb bra.s @insetThumbRect @thumbIsHorizontal move.w #cHThumbBitmap,-(sp) ; Remember bitmap offset for horizontal thumb @insetThumbRect pea TempRect move.l d0,-(sp) ; Inset value _InsetRect ; Inset the rectangle move.w (sp)+,d0 ; Get bitmap offset bra.s @thumbCommon @drawShadedThumb tst.w isHoriz(a6) ; Use horizontal thumb? bz.s @useVerticalThumb ; Nope move.w #kHorizontalThumb,d0 bra.s @thumbCommon @useVerticalThumb move.w #kVerticalThumb,d0 @thumbCommon bsr SetUpColorPict ; Set up the right thumb image bsr PlotSymbol ; Draw it ; Frame the scroll bar FrameCtl moveq #cFrameColor, D0 ; set up color to draw in black moveq #cBodyColor,D1 ; bsr SetupColors ; bsr GetTCtlRect ; get the control rect move.l A1,-(SP) ; _FrameRect ; frame it bra.s DrawControlExit DrawHilite254Ctl moveq #cFrameColor,D0 ; set the color to white moveq #cBodyColor,D1 ; bsr SetupColors ; bsr GetTCtlRect ; get rect containing the scroll bar pea TempRect ; get rect for _EraseRect move.l (SP),-(SP) ; get rect for _InsetRect move.l (SP),-(SP) ; get rect for _FrameRect _FrameRect move.l OneOne,-(SP) ; Inset by 1 to avoid flickering _InsetRect _EraseRect ; erase the rect DrawControlExit ; all done drawing the scroll bar tst.l userData(SP) ; are we drawing to the screen? bz.s @dontRestorePort ; if not, we didnÕt switch to the WMgrCPort bsr RestoreOldPort @dontRestorePort move.l (SP)+, A0 ; return address lea CDefDrawFrame.ParamSize(SP), SP ; pop params jmp (A0) endwith ; DrawArrowBox is a routine that clears and frames an arrow box and then blits ; across the appropriate arrow (looks at hilite state). On entry, TempRect has the ; box for the arrow, D0 has h/v selector, D1 has left/right selector,A1 points to the ; arrow bitMap, A3 has the control handle. ; DrawArrowBox move.w shaded(A6), -(SP) ; Save the shade flag. tst.w isHoriz(a6) ; Horizontal? bz.s @orientationOk addq #4, D0 ; offset to horiz gadget numbers @orientationOk cmp.w #inDownButton, D1 ; do we want down/right arrows? bne.s @directionOk addq #2, D0 ; offset to opposite direction arrow @directionOk move.l (A3),A0 ; get the control pointer cmp.b ContrlHilite(A0),D1 ; should it be hilited? bne.s @notHighlighted ; if not, skip subq #1, D0 ; offset to hilited version tst.b shaded(a6) ; Color arrows? bnz.s @drawArrow move.w d0,d1 bra.s @bwScrollBar ; Go draw a hilighted arrow @notHighlighted move.w D0, D1 ; Save gadget resource ID tst.b shaded(a6) ; If weÕre drawing in black and white, then bz.s @bwScrollBar ; it doesnÕt matter if weÕre disabled or not. bsr.s IsDisabled ; If disabled & drawing in colour, bnz.s @notDisabled ; use black and white arrows to draw. ; Set up colours to match faint gray used in body of scroll bar movem.l d0-d1,-(sp) ; Need to save registers across call to SetupColors moveq #wHiliteShade8,D0 moveq #wTitleBarShade1,D1 bsr SetupColors movem.l (sp)+,d0-d1 ; ; If the arrows are disabled, use the black and white arrows, and change the ; fore and background colours to shades of gray. To get the right gadget, ; convert the resource ID into an index into the BitMap table. ; @bwScrollBar clr.w shaded(A6) ; pretend we donÕt have color exg d0,d1 ; Save a branch by doing this exchange move.w #kHollowRightArrow,d1 sub.w d0,d1 ; Change resource ID into bitmap index @notDisabled move.w d1,d0 @drawArrow bsr SetupColorPict ; prepare the picture move.w (SP)+,shaded(A6) ; restore Ōuse colorÕ flag bra PlotSymbol ; Go plot the arrow ; Utility ShouldIDraw -- to test when to skip drawing a part of the scrollBar. ; On entry, D3 has parameter indicating part that needs drawing while D1 holds ; the part we are about to draw. If D3 is zero, always draw it. Otherwise, ; draw only if it matches. Returning 0 in the Z-flag means you should draw ShouldIDraw tst D3 ; examine the parameter beq.s StubSBar ; its zero so don't test further cmp #inThumb,D3 ; if we need to draw the thumb, let's draw everything else <22> beq.s StubSBar ; <22> cmp D1,D3 ; the right part StubSBar rts ; the z-flag has the answer ; IsDisabled is a utility to check to see if a scrollBar is disabled or not. ; It returns with the z-flag set if it is disabled IsDisabled move.l (A3),A0 ; get sBar pointer move.w ContrlMin(A0),D0 ; get the min cmp.w ContrlMax(A0),D0 ; same as the max? beq.s doneChecking ; move.b ContrlHilite(A0),D0 ; get the hilite parameter addQ.b #1,D0 ; was it 255? doneChecking rts ; return to caller with z-flag result ; TestHV is a utility that determines if the rectangle pointed to by A0 is more horizontal ; or vertical. Return 0 in D0 if its more vertical and 2 if its more horizontal. ; This routine trashes D1. The result is also reflected in the condition code. ; It also returns the width/height of the minor dimension in D2. TestHV move Bottom(A0),D0 sub Top(A0),D0 ; get height move Right(A0),D1 sub Left(A0),D1 ; get width cmp D0,D1 ; compare width and height BGT.s @1 ; branch it width is greater move D1,D2 ; horizontal in D2 moveq #0,D0 ; signal its vertical rts @1 move D0,D2 ; vertical in D2 moveq #2,D0 ; signal its horizontal rts ; CalcIBox is the crucial routine that computes the position of the top/left of the ; thumb by scaling the control's value according to its range and the screen area. ; Return the rectangle in IndicatorRect(A6). It expects that A3 will hold the ; control handle as usual CalcIBox move D3,-(SP) ; preserve D3 lea IndicatorRect(A6),A1 ; get address of indicator rectangle bsr.s GetCtlRect ; first set it to control bounding rect moveq #0,D1 ; clear out high part of D1 move.l (A3),A0 ; get pointer to control lea ContrlRect(A0),A0 ; get pointer to the bounding rectangle bsr.s TestHV ; get h/V selector index in D0 ; ???? was .s move D2,D3 ; keep minor dimension in D3 ; compute control screen area in relevant dimension move Bottom(A0,D0),D1 ; get logical "bottom" sub Top(A0,D0),D1 ; compute "height" sub D2,D1 ; discount arrow box sub D2,D1 ; discount other one, too sub D2,D1 ; and the indicator ; compute "screenSize times value" move.l (A3),A0 ; get control pointer move.w ContrlValue(A0),D2 ; get current value sub.w ContrlMin(A0),D2 ; get delta from min MULU D2,D1 ; compute value*screensize ; compute size of logical space move ContrlMax(A0),D2 ; get max sub ContrlMin(A0),D2 ; compute size of space beq.s Scale0 ; dont divide by 0 ; perform the scaling DIVU D2,D1 ; compute where iBox should go bsr RoundOff ; round off D1 add D3,D1 ; skip over arrow box ; update indicator rect to correct position UpdateIRect lea IndicatorRect(A6),A1 ; get pointer to rect add Top(A1,D0),D1 ; compute the logical "top" move D1,Top(A1,D0) ; update it add D3,D1 ; bump to "bottom" move D1,Bottom(A1,D0) ; update "bottom" EOR #2,D0 ; flip to minor dimension addQ #1,Top(A1,D0) ; inset logical "left" subQ #1,Bottom(A1,D0) ; inset logical "right" ; set up the indicator region move.l ContrlData(A0),-(SP) ; push indicator region handle move.l A1,-(SP) ; push rect ptr _RectRgn ; make a rectangular region CalcIDone move (SP)+,D3 ; restore D3 rts ; if min = max, pin at top Scale0 move D3,D1 BRA.s UpdateIRect ; GetCtlRect is a code saving utility that copies the bounding rectangle of the control ; whose handle is in A3 into the rectangle pointed to by A1. This routine blows ; A0 but preserves A1. GetTCtlRect is an alternative entry used to save code GetTCtlRect lea TempRect,A1 GetCtlRect move.l (A3),A0 ; get pointer to control lea ContrlRect(A0),A0 ; get pointer to bounding rect move.l (A0),(A1) ; copy topLeft move.l 4(A0),4(A1) ; copy botRight NoSBarHit rts ; HitSBar is the hit test routine for the scroll bar definition routine. It classifies ; the position of the mouse passed in D3 HitSBar move.b ContrlHilite(A0),D4 ; get hilite state beq.s NoSBarHit ; => yes, return 0 <30> bsr IsDisabled ; otherwise disabled? beq.s NoSBarHit ; => yes, return with 0 lea ContrlRect(A0),A4 ; keep rect pointer in A4 CLR.w -(SP) ; make room for function result move.l D3,-(SP) ; push the point move.l A4,-(SP) ; push address of rect _PtInRect ; in the rectangle? tst.b (SP)+ ; examine result beq.s NoSBarHit ; if not, we're done ; its in the rect, so classify if in upButton,downButton,pageUp,pageDown or thumb bsr.s NormalizePt ; swap relevant coordinate into low part ; ; and set up D0,D2 ; see if its in the top button @1 move D3,D1 ; get copy of mousePoint sub 0(A4,D0),D1 ; subtract rectangle top cmp D2,D1 ; is it within width of the top? BGT.s @2 ; it not, go check bottom moveq #inUpButton,D0 ; classify it BRA.s UpdateResult ; all done ; see if its in the bottom button @2 move 4(A4,D0),D1 ; get bottom sub D3,D1 ; get distance from bottom cmp D2,D1 ; is it in it? BGT.s CheckInd ; if not, go check indicator moveq #inDownButton,D0 UpdateResult move D0,22(A6) ; return result rts ; its not in either button so it must be the thumb or one of the page areas. Check ; for the thumb first CheckInd cmp #1,D6 ; for flavor one don't test beq.s NoSBarHit bsr CalcIBox ; calculate the indicator rectangle bsr.s NormalizePt ; restore back to normal point CLR.w -(SP) ; make space for boolean result move.l D3,-(SP) ; push the point move.l (A3),A0 move.l ContrlData(A0),-(SP) ; push the indicator region _PtInRgn ; is the mouse in the indicator? tst.b (SP)+ ; (..the suspense builds...) beq.s CheckPage ; branch if its not in the indicator ; its in the thumb so report that to the application move #inThumb,D0 ; get result BRA.s UpdateResult ; all done -- go update result ; it must be in one of the two page areas. Determine which one by looking at the ; midPoint of the indicator's bounding rectangle. CheckPage bsr.s NormalizePt ; normalize (get interesting low word) move.l (A3),A0 ; get control pointer move.l ContrlData(A0),A0 ; get region handle move.l (A0),A0 ; get region pointer lea RgnBBox(A0),A0 ; point to the region bounding box ; determine midpoint move Bottom(A0,D0),D1 ; get logical bottom sub Top(A0,D0),D1 ; get logical height LSR #1,D1 ; divide by 2 add Top(A0,D0),D1 ; add to get the midpoint ; at this point, D1 has the midpoint in the important dimension. Compare with the ; mouse point to decide if its page up or down. cmp D1,D3 ; compare mousePt with midPoint BLT.s PageItUp ; if above its the logical "top" moveq #inPageDown,D0 ; set result code BRA.s UpdateResult ; all done -- go update result PageItUp moveq #inPageUp,D0 ; set result code BRA.s updateResult ; all done ; NormalizePt takes a rect pointer in A4 and a point in D3 and swaps the points ; coordinates according to the relevant dimensions NormalizePt move.l A4,A0 ; get rect pointer in A0 bsr TestHV ; get horizontal vertical offset BNE.s @1 ; if horizontal, skip swap D3 ; its vertical so get y in low part @1 rts ; all done ; CalcSBar returns the bounding region of the scroll bar. D3 holds the region parameter. ; If the high bit of D3 is set, return the indicator region, other return the entire ; bounding region CalcSBar tst.l D3 ; indicator or body? BPL.s GetWholeRgn ; if positive, go get body AND.l #$00FFFFFF, D3 ; Negative, strip out high byte ; the indicator region was requested so copy the one in the dataHandle GetIndRgn bsr CalcIBox ; calculate indicator region move.l (A3),A0 ; get pointer to control move.l ContrlData(A0),-(SP) ; push indicator region move.l D3,-(SP) ; push result region _CopyRgn ; clone the region ; set the pattern for dragging bsr.s GetOldStyleLtGray ; get pointer to light gray move.l (A0),A0 move.l (A0)+,DragPattern ; update the drag pattern move.l (A0),DragPattern+4 ; update the drag pattern rts ; the whole region was requested CalcWholeSBar move.l #1, ProcResult(A6) ; return 1 to show that we respond GetWholeRgn move.l D3,-(SP) ; push the region handle PEA ContrlRect(A0) ; push rectangle pointer _RectRgn ; return a rectangular region rts ; all done! CalcThumbSBar move.l #1, ProcResult(A6) ; return 1 to show that we respond BRA.s GetIndRgn ; PlotLtGray move.l theZone,-(SP) ; save the current zone <19> move.l sysZone,theZone ; going to create the pixpat in sysZone <19> pea TempRect ; get rectangle to be filled tst.b shaded(A6) ; is it shaded scroll bar (=> do we use pixpat?) beq.s @useOldStyle ; no => fill using black on white move.w #wHiliteShade8,D0 ; use a dark gray for dots in pattern move.w #cArrowShade2,D1 ; use a light gray for the background bra.s @plotPAT ; @useOldStyle move.w #cFrameColor,D0 ; black foreground move.w #cBodyColor,D1 ; white background @plotPAT bsr SetupColors ; set up the foreground and background colors bsr.s GetOldStyleLtGray ; use common routine to get the PAT move.l (A0),-(SP) ; dereference to get PatPtr _FillRect ; fill the rect @doneGetLtGray move.w #cFrameColor,D0 ; revert the color to normal move.w #cBodyColor,D1 bsr SetupColors move.l (SP)+,theZone ; restore the zone <19> rts GetOldStyleLtGray subQ #4,SP move.w #SBarPatID,-(SP) ; push resource ID _GetPattern ; get the pattern move.l (SP)+,A0 ; return PatHandle in A0 rts ; handle the "position yourself" message by calling figuring out the new value and ; calling SetCtlValue. D3 holds the amount to move by. MoveSBar move.l ContrlData(A0),A0 ; get handle of indicator region move.l (A0),A0 ; get a pointer to it lea RgnBBox(A0),A4 ; get pointer to the bounding rect ; figure out new position by adding topLeft of current position to offset add Left(A4),D3 ; add the x coordinates swap D3 ; get y in low word add Top(A4),D3 ; add the y coordinates ; select the relevant dimension and get it into the low word of D3 move.l (A3),A0 ; get the control pointer lea ContrlRect(A0),A0 ; get the bounding rectangle bsr TestHV ; get h/v index beq.s @1 ; if its y, we're cool swap D3 ; get x into D3 ; determine amount of screen area devoted to the scrollBar @1 sub Top(A0,D0),D3 ; make size ctl-relative sub D2,D3 ; subtract arrow offset move Bottom(A0,D0),D1 ; get logical bottom sub Top(A0,D0),D1 ; compute logical height sub D2,D1 ; compute active area sub D2,D1 sub D2,D1 move D1,D2 ; get answer in D2 ; compute range of logical values: controlMax - controlMin move.l (A3),A0 ; get control pointer move ContrlMax(A0),D1 ; get max value sub ContrlMin(A0),D1 ; compute range ; compute position*logical range/physical range MULU D3,D1 ; D3 has current position DIVU D2,D1 ; divide by physical range bsr.s RoundOff ; round to nearest integer ; at this point D1 has the value so set it, after offsetting by the minimum add.w ContrlMin(A0),D1 ; offset by minimum move.l A3,-(SP) ; push control handle move.w D1,-(SP) ; push the new value _SetCtlValue ; go set the new value rts ; all done! ; InitSBar gets called when the scroll bar is allocated. It allocates an empty region ; to use as the indicator region InitSBar subQ #4,SP _NewRgn ; get a new region on the stack top move.l (A3),A0 ; get control pointer move.l (SP)+,ContrlData(A0) ; remember new region in control data rts ; DispSBar de-allocates the region used for the indicator DispSBar move.l ContrlData(A0),A0 ; get handle of indicator region _DisposHandle ; dispose of it rts ; Utility RoundOff -- RoundOff the number in D1 to the nearest integer. The remainder ; from dividing by D2 is in the high part of the word. RoundOff move.w D0,-(SP) ; preserve D0 move D2,D0 ; get old divisor LSR #1,D0 ; divide by 2 swap D1 ; get remainder cmp D0,D1 ; compare remainder with 1/2 divisor BLE.s TruncateIt ; if smaller, we're done swap D1 ; get normal D1 back addQ #1,D1 ; round up RoundDone move.w (SP)+,D0 ; restore D0 rts ; no need to round up so just truncate it TruncateIt swap D1 ; restore quotient BRA.s RoundDone ; all done with roundOff ; ThumbSBar receives the "drag thumb message for the scroll bar. On entry, D3 points ; to a structure that contains the starting point, it returns with pointers to ; the bounds and slopRect and the axis parameter ; Local Variable Equates BRect EQU 0 ; boundsRect SRect EQU 8 ; slopRect TAxis EQU 16 ; axis ThumbSBar move.l D3,A4 ; keep pointer to parameter block move.l (A4),D3 ; get the mouse point lea BRect(A4),A2 ; get pointer to boundsRect move.l A2,A1 ; get pointer in A1 bsr GetCtlRect ; copy control bounds rect move.l A2,A0 ; point to boundsRect bsr TestHV ; get h/v selector in D0 move D2,-(SP) ; preserve D2 swap D2 move.w #$FFE8,D2 ; get inset factor (24 pixels hyst) move D0,D4 ; keep selector in D4 beq.s @1 ; if vertical, we're cool swap D2 ; adjust inset factor BRA.s @2 @1 swap D3 ; adjust mouse pt @2 move.l A2,-(SP) ; push pointer to rectangle move.l D2,-(SP) ; push inset factor _InsetRect ; go inset it ; build the slopRect by insetting the boundsRect lea SRect(A4),A0 ; get slopRect pointer move.l (A4),(A0) ; copy boundsRect into slopRect move.l 4(A4),4(A0) ; copy botRight, too move.l #$FF800000,D0 ; get inset factor (assume vertical) tst D4 ; which dimension beq.s @3 ; if vertical, we're cool swap D0 @3 move.l A0,-(SP) ; push slopRect pointer move.l D0,-(SP) ; push inset factor _InsetRect ; inset it ; now further adjust the boundsRect depending where the mousePt is relative to the ; indicator box. move.l (A3),A0 ; get control pointer move.l ContrlData(A0),A0 ; get region handle move.l (A0),A0 ; get region pointer sub RgnBBox(A0,D4),D3 ; subtract relevant coordinate add D3,Top(A2,D4) ; offset logical top ; fix up logical bottom, too move (SP)+,D2 ; get back D2 subQ #1,D2 sub D2,Bottom(A2,D4) add D3,Bottom(A2,D4) ; subtract (15-number) from bottom ; now set up axis parameter LSR #1,D4 ; divide by 2 EOR #1,D4 ; flip the sense addQ #1,D4 ; add increment move D4,TAxis(A4) ; to derive axis parameter rts ;---------------------------------------------------------------------------- ; ; These routines are the heart of the WDEFÕs ability to draw the right thing ; on the right device based on the depth of the device. There are three kinds ; of window color types we can draw: ; ; Black and White Drawn on non-CQD Macs, and on devices that have less ; than 8 bits per pixel. 8 bits per pixel is a high, ; arbitrary limit that we may be able to relax if we ; can integrate use of the Palette Manager into the ; WDEF. ; Custom wctbs If there is a custom color table associated with ; this window, then its colors are used. This may ; change in the future if we find a way to customize ; the colors of the System 7 three-d windows. ; System 7.0 & later Our new default for color environments. ;---------------------------------------------------------------------------- MakeRatioRGB movem.l D7/A2, -(SP) lea endRGB(A6), A0 lea startRGB(A6), A1 lea tempRGB(A6), A2 mulu #$1111, D2 move.w #2, D0 @nextChannel moveq #0, D1 ; clear high word move (A0)+, D1 ; background color component sub (A1), D1 ; change from foreground slo D7 ; remember if it was negated bhs.s @orderedOK neg D1 ; flip if subtraction would overflow @orderedOK mulu D2, D1 ; multiply times scale factor swap D1 ; divide by 65K tst.b D7 beq.s @notFlipped neg.l D1 ; flip it @notFlipped add.w (A1)+, D1 move.w D1, (A2)+ dbra D0, @nextChannel movem.l (SP)+, D7/A2 rts CheckAvailableColors ;---------------------------------------------------------------------------- ; This routine is called just as we enter the _DeviceLoop drawing proc, after ; the current depth has been stored in curDepth(A6). If the depth is 8 bits ; per pixel or greater, and the wctb for this window is the default, then ; weÕre going to draw the System 7 three-d windows instead (threeDWind gets ; set to TRUE). Otherwise, threeDWind gets set to FALSE. ;---------------------------------------------------------------------------- movem.l D3-D4/A2, -(SP) ; these should be saved move.w curDepth(A6), D0 ; how deep is the current device? cmp.w #4, D0 ; must be 4 bits/pixel or better sge shaded(A6) ; set prelim answer blt.s @exit ; get out if already no good move.l TheGDevice, -(SP) ; save this move.l D1, TheGDevice ; set our device for color mapping lea HiliteShades, A2 ; point at shades we need bsr.s CheckShadesAvailable ; see if all these shades are here tst.b shaded(A6) ; did we fail to get the shades? bz.s @colorExit ; get out if so lea TitleBarShades, A2 ; point at shades we need bsr.s CheckShadesAvailable ; see if all these shades are here tst.b shaded(A6) ; did we fail to get the shades? bz.s @colorExit ; get out if so lea TingeShades, A2 ; point at shades we need bsr.s CheckShadesAvailable ; see if all these shades are here tst.b shaded(A6) ; did we fail to get the shades? ; bz.s @colorExit ; get out if so @colorExit move.l (SP)+, TheGDevice ; restore device @exit movem.l (SP)+, D3-D4/A2 rts CheckShadesAvailable move.w (A2), D3 ; get next ŌlightÕ color move.l #'csd ', D4 ; an unlikely pixel value @rampLoop cmp (A2), D3 ; get the next shadeÕs light color bne.s @exit ; if new, reinit for new ramp move.l A2, A0 ; point to shade entry bsr SetupRatioColor ; get shade in tempRGB subq.l #4, SP ; room for pixel index pea tempRGB(A6) ; the shade RGB we want _Color2Index ; what does it map to? move.l (SP)+, D0 ; get the pixel index cmp.l D0, D4 ; is it the same as last time? beq.s @failure ; if so, not enough colors move.l D0, D4 ; update ŌlastÕ shade index addq.l #6, A2 ; point to next shade bra.s @rampLoop ; and test it @failure sf shaded(A6) ; use the old kind @exit rts ; ; SetupWMgrCPort ; ; Since the old-style grafport cannot handle color, we have to draw to the WMgrCPort ; directly to have the colored scroll bars. ; In order to draw correctly, we must find the offset of the old-style grafport from ; the WMgrCPort and store the clip region of the WMgrCPort. The fore and back colors ; of the WMgrCPort should be stored too. ; SetupWMgrCPort movem.l a2-a4/d4,-(SP) tst.b shaded(A6) ; is it shaded? beq.s @dontDrawToWMgrCPort ; no => don't draw to WMgrCPort lea globalOffset(A6),A2 clr.l (A2) move.l A2,-(SP) _LocalToGlobal ; Get the intersection of the clipRgn and visRgn of the window to use as the ; clipping region for drawing the scroll bar. subq.l #4,SP ; allocate a new region _NewRgn ; move.l (SP)+,tempRgn(A6) ; move.l GrafGlobals(A5),A3 ; get the portRect of current port move.l thePort(A3),A3 ; move.l clipRgn(A3),-(sp) ; get clip region from old-style port move.l visRgn(A3),-(sp) ; get visRgn from old-style port move.l tempRgn(a6),-(sp) ; _SectRgn ; Get intersection of portRect & visRgn pea oldstylePort(A6) ; save the old-style port _GetPort ; move.l WMgrCPort,-(SP) ; from now on, use the WMgrCPort _SetPort ; pea wMgrCPortPenState(A6) ; Get the pen state <24> _GetPenState _PenNormal ; Draw normally <24> neg.w globalOffset(A6) neg.w globalOffset+2(A6) move.l globalOffset(A6),-(SP) _SetOrigin pea wMgrCPortFgColor(A6) ; save the fore color of WMgrCPort _GetForeColor ; pea wMgrCPortBkColor(A6) ; save the back color of WMgrCPort _GetBackColor ; clr.l -(SP) ; _NewRgn ; Allocate new region move.l (SP),wMgrCPortClipRgn(A6) _GetClip ; save WMgrPortÕs clipRgn move.l tempRgn(a6),-(sp) ; pea old-style clip region (for DisposRgn) move.l (sp),-(sp) ; (for SetClip) _SetClip ; Clip to the windowÕs clipRgn _DisposRgn ; Get rid of tempRgn @dontDrawToWMgrCPort movem.l (SP)+,a2-a4/d4 rts ; ; RestoreOldPort ; ; This is the counterpart of SetupWMgrCPort. It checks whether we are drawing directly to ; the WMgrCPort. If we are, it will restore the WMgrCPort clip region, forecolor and ; backcolor. And most important of all, it will restore the old-style grafport. ; RestoreOldPort tst.b shaded(A6) ; is it shaded? beq.s @doneRestore ; no => we are not drawing to WMgrCPort move.l wMgrCPortClipRgn(A6),-(SP) ; restore the WMgrCPort clipRgn move.l (SP),-(SP) ; _SetClip ; _DisposRgn ; Get rid of saved region pea wMgrCPortFgColor(A6) ; Restore the fore and back color _RGBForeColor ; pea wMgrCPortBkColor(A6) ; _RGBBackColor ; clr.l -(SP) _SetOrigin pea wMgrCPortPenState(A6) ; Restore pen state <24> _SetPenState move.l oldstylePort(A6),-(SP) ; Restore the old-style grafport _SetPort @doneRestore rts DefaultCCTB ;---------------------------------------------------------- ; This table of bytes represents the colors in the default ; wctb. It uses bytes because we know that the default ; table only has black and white. ;---------------------------------------------------------- dc.b $00, $FF, $00, $FF, $00, $FF, $00, $FF dc.b $00, $FF, $00, $FF, $00, $FF align SetupRatioColor move.w 4(A0), -(SP) ; push shade percent move.w 2(A0), -(SP) ; push dark (to/fore) end of shade move.w (A0), D0 ; get light shade color number bsr.s SetUpColor ; get the color of the light (from/back) end move.l (SP)+, A0 ; get pointer to light color move.l (A0)+, startRGB(A6) ; copy red and green move.w (A0), startRGB+4(A6) ; copy blue move.w (SP)+, D0 ; get dark color number bsr.s SetUpColor ; get the color of the light end move.l (SP)+, A0 ; get pointer to light color move.l (A0)+, endRGB(A6) ; copy red and green move.w (A0), endRGB+4(A6) ; copy blue move.w (SP)+, D2 ; get shade percentage bsr MakeRatioRGB ; create a shade between the two rts ; ================================================ SetupColors ; ================================================ ; Added this routine to help setup fore- and back color and save code. ; SetUpColor takes a fore color in D0, and a back color in D1. ; It then calls SetUpColor with both of them (which likes its ; parameter in D0), and calls RGBForeColor and RGBBackColor ; where appropriate. move.w D1,-(SP) ; save part identifier of back color bsr.s SetupForeColor move.w (SP)+,D0 ; get saved part bsr.s SetupBackColor rts ; all done ; ================================================ SetupForeColor ; ================================================ bsr.s SetUpColor ; D0 has forecolor part identifier bz.s @setClassicFore ; if non-CQD answer, branch _RGBForeColor bra.s @exit @setClassicFore _ForeColor @exit rts ; all done ; ================================================ SetupBackColor ; ================================================ bsr.s SetUpColor ; D0 has forecolor part identifier bz.s @setClassicBack ; if non-CQD answer, branch _RGBBackColor bra.s @exit @setClassicBack _BackColor @exit rts ; all done ; ================================================ SetUpColor ; ================================================ ; SetUpColor takes a window part identifier in D0, finds the corresponding ; part in the AuxWinTable (the part code is in the .value field) and returns ; a pointer to its RGB on the stack. If the requested part is not found, ; the old black and white color for that part is used. tst.b shaded(A6) ; can we use System 7 windows? bz.s @useBlackAndWhite ; nope? Try other cases cmp.w #lowestShadeIndex, D0 ; is this a shade color? blt.s @notShade ; not a shade color sub.w #lowestShadeIndex, D0 ; normalize to shade colors mulu #6, D0 ; x6 for table index lea ShadeTable, A0 ; point at table of shade colors add.w D0, A0 ; point to correct entry bsr.s SetupRatioColor ; get color in tempRGB move.l (SP)+, A0 ; pop the return address pea tempRGB(A6) ; point to rgb color moveq #1, D0 ; indicate color answer jmp (A0) ; get outa here @notShade move.l AuxCtlPtr(A6), A0 ; get the color table pointer move.w ctSize(A0), D1 ; get the color table size asl.w #3, D1 ; (x8) convert to color table index @legalIndex cmp.w ctTable+value(A0,D1), D0 ; is this the one? beq.s @foundIt ; if equal, then done subq.w #8, D1 ; try the previous one bge.s @legalIndex ; loop while index positive mulu #6, D0 ; (x6) index into rgb specs move.l (SP)+, D1 ; pop the return address lea DefaultCtlColors, A0 ; point at standard colors pea (A0, D0.w) ; point at correct color move.l D1, A0 ; get return address bra.s @exitColor @foundIt lea ctTable+rgb(A0, D1), A0 ; get the address of the color to use move.l A0, D0 ; we'll need A0 in a second move.l (SP)+, A0 ; get the return address move.l D0, -(SP) ; push the rgb addr on the stack @exitColor moveq #1, D0 ; indicate color answer jmp (A0) ; return to caller @useBlackAndWhite lea DefaultCCTB, A0 ; point to cheesy color table move.b (A0, D0.w), D0 ; get white or black (as a byte) bnz.s @simpleWhite ; branch if we want white move.l #blackColor, D0 ; get the old-style color bra.s @classicExit ; get outa here @simpleWhite move.l #whiteColor, D0 ; get old-style white @classicExit move.l (SP)+, A0 ; return address move.l D0, -(SP) ; classic color moveq #0, D0 ; indicate classic answer jmp (A0) SetupColorPict tst.b shaded(A6) ; are we using pictures? bz.s @blackAndWhiteBits ; if not, use bits instead subq.l #4, SP ; room for the PicHandle move.l #'pixs', -(SP) move.w d0, -(SP) ; push the resource ID move.w #MapTrue,RomMapInsert ; rb _GetResource ; look in ROM first rb move.l (SP)+, A0 ; pixels handle _HLock ; donÕt want it to move move.l A0, tempPixels(A6) ; save for dispose move.l (A0), A2 ; point to pixels info move.l workPixmap(A6), A1 ; get pixmap handle move.l (A1), A1 ; point to pixmap move.w (a2),pmRowBytes(a1) ; Get size of pixmap move.l 2(a2),pmBounds(a1) ; TopLeft of image move.l 6(a2),pmBounds+4(a1) ; Bottom right lea 10(a2),a0 ; Load base address move.l A0, pmBaseAddr(A1) ; Stash base address moveq #1, D2 ; indicate color solution bra.s @exit @blackAndWhiteBits asl.w #1, D0 ; convert to index into words lea BitmapOffsets, A2 ; point to offset table adda.w (A2, D0.w), A2 ; add offset to correct bitmap moveq #0, D2 ; indicate b&w bits @exit rts ; ; PlotSymbol ; ; D2 is non-zero for pixmap, zero for bitmap ; A2 points to bounds/rect/bits ; TempRect holds destination rect PlotSymbol tst.b D2 ; use picture or bits? bz.s @1 ; if zero, use CopyBits move.l workPixmap(A6), A0 ; get work pixmap move.l (A0), A0 ; move.l A0, -(SP) ; bra.s @copyBitsPixCommon ; @1 lea IconBitmap,A0 ; get pointer to source bitmap move.w (A2)+, rowBytes(A0) move.l (A2)+, bounds(A0) move.l (A2)+, bounds+4(A0) move.l A2, baseAddr(A0) pea IconBitmap ; push pointer source bitmap @copyBitsPixCommon move.l (SP),A0 ; remember in A0, too move.l GrafGlobals(A5),A1 ; get lisaGraf global baseaddress move.l thePort(A1),A1 ; get thePort pea portBits(A1) ; that's the destination bitmap pea bounds(A0) ; boundsRect of bitmap is source pea TempRect ; tempRect is the destination clr.w -(sp) ; srcCopy clr.l -(SP) ; no mask region ; the colors should be OK here ; transfer the bitMap (stretching as necessary...) _CopyBits ; let Bill stretch those bits move.l tempPixels(A6), A0 ; get the locked pixels (if any) _HUnlock ; and unlock them rts ; return to caller ; ; AdjustRect ; ; AdjustRect is a utility to adjust the boundary of a rect. ; The ptr to rectangle must be in A0. D0 will be added to ; the left and top of the rectangle while D1 will be added to ; the bottom of the rect. ; AdjustRect LEA TempRect,A0 ADD.W D0,left(A0) ADD.W D0,top(A0) ADD.W D1,right(A0) ADD.W D1,bottom(A0) RTS ; <26> The following routine is used to draw the outline of the thumb during dragging. DrawThumbOutline bsr InitDrawingStuff ; initialize the drawing environment IF NOT forROM THEN subq.l #4,sp ; get a new rgn _NewRgn move.l (sp),-(sp) ; push rgn move.l param(a6),-(sp) ; push rect _RectRgn ; put rect in rgn move.l (sp),-(sp) ; thumb rgn ELSE move.l param(a6),-(sp) ; push rgn handle ENDIF pea ThumbDrawRoutine ; draw routine move.l param(a6),-(sp) ; rect clr.l -(sp) _DeviceLoop IF NOT forROM THEN _DisposRgn ENDIF ST ProcResult(a6) bra RestoreDrawingStuff ; cleanup after doing drawing ; <26> The following routine is for drawing of the outline of a dragged thumb. ; If the thumb is in a B&W scrollbar, we will use notPatXor to invert the thumb ; outline. If the thumb is in a color scrollbar, we will use hilite mode to ; draw the outline. The hilite mode switches the frame between the background ; and Hilite color of WMgrCPort. In this case, we can get the desired effect ; on a color scroll in an old-style grafport. Since the background color for ; hilite mode is hardwired to a specific shade of gray, this color may need to ; be modified if we ever decide to change the color of the background of scrollbar. ; Since this routine is called by DeviceLoop, the drawing of the thumb outline ; across monitors will be correct. ; ThumbDrawFrame RECORD 0 ; stack frame for DeviceLoop draw proc retAddress ds.l 1 ; return address StartParams EQU * userData ds.l 1 ; long we passed to DeviceLoop devHandle ds.l 1 ; GDevice handle deviceFlags ds.w 1 ; flags for current device depth ds.w 1 ; bits/pixel for this call ParamSize EQU *-StartParams ENDR ThumbDrawRoutine with ThumbDrawFrame move.w depth(SP), curDepth(A6) ; save this for SetupColor magic move.l devHandle(SP), D1 ; pass this drawing device bsr CheckAvailableColors ; see if we have enough colors and see whether tst.b shaded(a6) bne.s @colorWindow PEA DragPattern ;XOR specified pattern _PenPat MOVE #notPatXor,-(SP) ;set pen mode to notPatXor _PenMode move.l userData(sp),-(sp) ; no => do the normal notPatXor framerect IF forROM THEN _PaintRgn ELSE _FrameRect ENDIF bra.s @doneDrawThumb ; @colorWindow ; yes => use the HiliteMode bsr SetupWMgrCPort move.w #hilite,-(sp) ; set HiliteMode _PenMode move.l WMgrCPort,a0 ; save Hilite color in WMgrCPort move.l grafVars(a0),a0 move.l (a0),a0 move.w rgbHiliteColor+blue(a0),-(sp) move.l rgbHiliteColor(a0),-(sp) pea trueGray ; set BackColor to light gray _RGBBackColor pea RGBBlack ; set hilite color to black _HiliteColor move.l userData+6(sp),-(sp) ; get the thumb outline rect IF forROM THEN _PaintRgn ELSE _FrameRect ; frame it ENDIF move.l sp,-(sp) ; restore hilite color _HiliteColor addq.l #6,sp bsr RestoreOldPort @doneDrawThumb move.l (sp)+,a0 ; get return address add.l #12,sp ; pop params jmp (a0) trueGray dc.w $DDDE,$DDDE,$DDDE PixelRsrcIDs ;---------------------------------------------------------- ; This is a table of resource IDs for the PICTs which are ; used to draw the small pieces of the System 7 scroll bars. ;---------------------------------------------------------- dc.w -10206 ; cUpOutlineArrow dc.w -10205 ; cUpSolidArrow dc.w -10204 ; cDnOutlineArrow dc.w -10203 ; cDnSolidArrow dc.w -10202 ; cLtOutlineArrow dc.w -10201 ; cLtSolidArrow dc.w -10200 ; cRtOutlineArrow dc.w -10199 ; cRtSolidArrow dc.w -10206 ; cUpDisabledArrow dc.w -10204 ; cDnDisabledArrow dc.w -10202 ; cLtDisabledArrow dc.w -10200 ; cRtDisabledArrow dc.w -10208 ; cVThumbPat dc.w -10207 ; cHThumbPat DefaultCtlColors ;----------------------------------------------------------- ; These are the RGB colors which are used to draw the shaded ; windows. ;----------------------------------------------------------- dc.w $0000, $0000, $0000 ; cFrameColor 00 dc.w $FFFF, $FFFF, $FFFF ; cBodyColor FF dc.w $0000, $0000, $0000 ; cTextColor (not used) 00 dc.w $FFFF, $FFFF, $FFFF ; cThumbColor (not used) FF dc.w $5555, $5555, $5555 ; cFillPatColor 00 dc.w $FFFF, $FFFF, $FFFF ; cArrowsLight FF dc.w $0000, $0000, $0000 ; cArrowsDark 00 dc.w $FFFF, $FFFF, $FFFF ; cThumbLight FF dc.w $0000, $0000, $0000 ; cThumbDark 00 dc.w $FFFF, $FFFF, $FFFF ; wHiliteLight FF dc.w $0000, $0000, $0000 ; wHiliteDark 00 dc.w $FFFF, $FFFF, $FFFF ; wTitleBarLight FF dc.w $0000, $0000, $0000 ; wTitleBarDark 00 dc.w $CCCC, $CCCC, $FFFF ; wTingeLight FF dc.w $3333, $3333, $6666 ; wTingeDark 00 ShadeTable ArrowShades dc.w cArrowsLight, cArrowsDark, $2 ; cArrowShade2 HiliteShades dc.w wHiliteLight, wHiliteDark, $8 ; wHiliteShade8 TitleBarShades dc.w wTitleBarLight, wTitleBarDark, $1 ; wTitleBarShade1 TingeShades dc.w wTingeLight, wTingeDark, $0 ; wTinge0 dc.w wTingeLight, wTingeDark, $4 ; wTinge4 dc.w wTingeLight, wTingeDark, $A ; wTingeA dc.w wTingeLight, wTingeDark, $F ; wTingeF dc.w 0 BitmapOffsets ;---------------------------------------------------------- ; This is a table of words which represent the offsets ; from WDEFBitmaps to the beginning of each bitmap ;---------------------------------------------------------- dc.w RightArrowBitmap-BitmapOffsets dc.w RightArrowHilited-BitmapOffsets dc.w LeftArrowBitmap-BitmapOffsets dc.w LeftArrowHilited-BitmapOffsets dc.w DownArrowBitmap-BitmapOffsets dc.w DownArrowHilited-BitmapOffsets dc.w UpArrowBitmap-BitmapOffsets dc.w UpArrowHilited-BitmapOffsets dc.w HThumbBitmap-BitmapOffsets dc.w VThumbBitmap-BitmapOffsets CDEFBitmaps ;---------------------------------------------------------- ; These bitmaps are used when drawing on classic QD ; machines, or when the bit depth is too low to draw in ; color. ;---------------------------------------------------------- UpArrowBitmap dc.w $0002 ; rowBytes dc.w $0000, $0000, $0010, $0010 ; bounds dc.w $FFFF ; „„„„„„„„„„„„„„„„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $8181 ; „......„„......„ dc.w $8241 ; „.....„..„.....„ dc.w $8421 ; „....„....„....„ dc.w $8811 ; „...„......„...„ dc.w $9009 ; „..„........„..„ dc.w $BC3D ; „.„„„„....„„„„.„ dc.w $8421 ; „....„....„....„ dc.w $8421 ; „....„....„....„ dc.w $8421 ; „....„....„....„ dc.w $87E1 ; „....„„„„„„....„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $FFFF ; „„„„„„„„„„„„„„„„ UpArrowHilited dc.w $0002 ; rowBytes dc.w $0000, $0000, $0010, $0010 ; bounds dc.w $FFFF ; „„„„„„„„„„„„„„„„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $8181 ; „......„„......„ dc.w $83C1 ; „.....„„„„.....„ dc.w $87E1 ; „....„„„„„„....„ dc.w $8FF1 ; „...„„„„„„„„...„ dc.w $9FF9 ; „..„„„„„„„„„„..„ dc.w $BFFD ; „.„„„„„„„„„„„„.„ dc.w $87E1 ; „....„„„„„„....„ dc.w $87E1 ; „....„„„„„„....„ dc.w $87E1 ; „....„„„„„„....„ dc.w $87E1 ; „....„„„„„„....„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $FFFF ; „„„„„„„„„„„„„„„„ DownArrowBitmap dc.w $0002 ; rowBytes dc.w $0000, $0000, $0010, $0010 ; bounds dc.w $FFFF ; „„„„„„„„„„„„„„„„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $87E1 ; „....„„„„„„....„ dc.w $8421 ; „....„....„....„ dc.w $8421 ; „....„....„....„ dc.w $8421 ; „....„....„....„ dc.w $BC3D ; „.„„„„....„„„„.„ dc.w $9009 ; „..„........„..„ dc.w $8811 ; „...„......„...„ dc.w $8421 ; „....„....„....„ dc.w $8241 ; „.....„..„.....„ dc.w $8181 ; „......„„......„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $FFFF ; „„„„„„„„„„„„„„„„ DownArrowHilited dc.w $0002 ; rowBytes dc.w $0000, $0000, $0010, $0010 ; bounds dc.w $FFFF ; „„„„„„„„„„„„„„„„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $87E1 ; „....„„„„„„....„ dc.w $87E1 ; „....„„„„„„....„ dc.w $87E1 ; „....„„„„„„....„ dc.w $87E1 ; „....„„„„„„....„ dc.w $BFFD ; „.„„„„„„„„„„„„.„ dc.w $9FF9 ; „..„„„„„„„„„„..„ dc.w $8FF1 ; „...„„„„„„„„...„ dc.w $87E1 ; „....„„„„„„....„ dc.w $83C1 ; „.....„„„„.....„ dc.w $8181 ; „......„„......„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $FFFF ; „„„„„„„„„„„„„„„„ LeftArrowBitmap dc.w $0002 ; rowBytes dc.w $0000, $0000, $0010, $0010 ; bounds dc.w $FFFF ; „„„„„„„„„„„„„„„„ dc.w $8001 ; „..............„ dc.w $8101 ; „......„.......„ dc.w $8301 ; „.....„„.......„ dc.w $8501 ; „....„.„.......„ dc.w $89F1 ; „...„..„„„„„...„ dc.w $9011 ; „..„.......„...„ dc.w $A011 ; „.„........„...„ dc.w $A011 ; „.„........„...„ dc.w $9011 ; „..„.......„...„ dc.w $89F1 ; „...„..„„„„„...„ dc.w $8501 ; „....„.„.......„ dc.w $8301 ; „.....„„.......„ dc.w $8101 ; „......„.......„ dc.w $8001 ; „..............„ dc.w $FFFF ; „„„„„„„„„„„„„„„„ LeftArrowHilited dc.w $0002 ; rowBytes dc.w $0000, $0000, $0010, $0010 ; bounds dc.w $FFFF ; „„„„„„„„„„„„„„„„ dc.w $8001 ; „..............„ dc.w $8101 ; „......„.......„ dc.w $8301 ; „.....„„.......„ dc.w $8701 ; „....„„„.......„ dc.w $8FF1 ; „...„„„„„„„„...„ dc.w $9FF1 ; „..„„„„„„„„„...„ dc.w $BFF1 ; „.„„„„„„„„„„...„ dc.w $BFF1 ; „.„„„„„„„„„„...„ dc.w $9FF1 ; „..„„„„„„„„„...„ dc.w $8FF1 ; „...„„„„„„„„...„ dc.w $8701 ; „....„„„.......„ dc.w $8301 ; „.....„„.......„ dc.w $8101 ; „......„.......„ dc.w $8001 ; „..............„ dc.w $FFFF ; „„„„„„„„„„„„„„„„ RightArrowBitmap dc.w $0002 ; rowBytes dc.w $0000, $0000, $0010, $0010 ; bounds dc.w $FFFF ; „„„„„„„„„„„„„„„„ dc.w $8001 ; „..............„ dc.w $8081 ; „.......„......„ dc.w $80C1 ; „.......„„.....„ dc.w $80A1 ; „.......„.„....„ dc.w $8F91 ; „...„„„„„..„...„ dc.w $8809 ; „...„.......„..„ dc.w $8805 ; „...„........„.„ dc.w $8805 ; „...„........„.„ dc.w $8809 ; „...„.......„..„ dc.w $8F91 ; „...„„„„„..„...„ dc.w $80A1 ; „.......„.„....„ dc.w $80C1 ; „.......„„.....„ dc.w $8081 ; „.......„......„ dc.w $8001 ; „..............„ dc.w $FFFF ; „„„„„„„„„„„„„„„„ RightArrowHilited dc.w $0002 ; rowBytes dc.w $0000, $0000, $0010, $0010 ; bounds dc.w $FFFF ; „„„„„„„„„„„„„„„„ dc.w $8001 ; „..............„ dc.w $8081 ; „.......„......„ dc.w $80C1 ; „.......„„.....„ dc.w $80E1 ; „.......„„„....„ dc.w $8FF1 ; „...„„„„„„„„...„ dc.w $8FF9 ; „...„„„„„„„„„..„ dc.w $8FFD ; „...„„„„„„„„„„.„ dc.w $8FFD ; „...„„„„„„„„„„.„ dc.w $8FF9 ; „...„„„„„„„„„..„ dc.w $8FF1 ; „...„„„„„„„„...„ dc.w $80E1 ; „.......„„„....„ dc.w $80C1 ; „.......„„.....„ dc.w $8081 ; „.......„......„ dc.w $8001 ; „..............„ dc.w $FFFF ; „„„„„„„„„„„„„„„„ VThumbBitmap dc.w $0002 ; rowBytes dc.w $0000, $0000, $0010, $0010 ; bounds dc.w $FFFF ; „„„„„„„„„„„„„„„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $C003 ; „„............„„ dc.w $FFFF ; „„„„„„„„„„„„„„„„ HThumbBitmap dc.w $0002 ; rowBytes dc.w $0000, $0000, $0010, $0010 ; bounds dc.w $FFFF ; „„„„„„„„„„„„„„„„ dc.w $FFFF ; „„„„„„„„„„„„„„„„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $8001 ; „..............„ dc.w $FFFF ; „„„„„„„„„„„„„„„„ dc.w $FFFF ; „„„„„„„„„„„„„„„„ END