home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-03-10 | 19.8 KB | 469 lines | [TEXT/MPCC] |
- /****************************************************************************************************
- * *
- * CDEFTemplate.c -- Copyright Chris Larson (larson@cs.ucla.edu), 1994 - 1995 All Rights Reserved *
- * *
- * Source file for a CDEF shell. *
- * *
- * This source file and its compiled derivatives may be freely used within any freeware, shareware, *
- * postcardware, beerware, etc. as long as you mention my name in your credits. Neither this source *
- * nor its compiled derivatives are in the public domain and may not be use in any form in public *
- * domain software. Neither this source nor its compiled derivatives may be used in any form in a *
- * commercial product without the expressed, written consent of the author (me). *
- * *
- * Version 1.0 -- March 10, 1995 *
- * *
- ****************************************************************************************************/
-
- // Include Files
-
- #ifndef powerc
- #include <A4Stuff.h>
- #endif
-
- #include "CDEF Template.h"
-
- //---------------------------------------------------------------------------------------------------
- // main -- CDEF entry point. Handle all messages and dispatch to appropriate subroutines.
- //---------------------------------------------------------------------------------------------------
-
- pascal long main (short varCode, ControlHandle theControlHandle, short message, long param)
- {
- long returnValue = 0; // Init return value to 0.
- ControlPtr theControl;
- SignedByte controlRecState;
-
- #ifndef powerc
-
- long oldA4 = SetCurrentA4(); // Set up the A4 register (680x0 only).
-
- #endif
-
-
- // ----------
- // Lock down the ControlRecord and get a pointer to it.
- // ----------
-
- controlRecState = HGetState((Handle)theControlHandle);
- HLock((Handle)theControlHandle);
- theControl = *theControlHandle;
-
- // ----------
- // Dispatch to appropriate subroutine.
- // ----------
-
- switch (message)
- {
- // ----------
- // drawCntl -- Draw the control if it’s visible. The part code to draw is held in the low
- // word of param. The high word contains garbage so only the low word should
- // be used. Note that the prototype of BeginDraw has its third parameter of
- // type short. This takes care of stripping the high word.
- // ----------
-
- case drawCntl:
- if ( theControl->contrlVis )
- BeginDraw(theControlHandle,varCode,param);
- break;
-
- // ----------
- // testCntl -- Determine which part of the control contains the point held in param. The
- // funny cast on param is needed because Point is a struct and param is not,
- // even though they are the same size. Note that IM: Macintosh TB Essentials
- // does not explicitly tell us that param is a Point but the structure and size
- // are both the same when given the testCntl message (a 4-byte quantity with the
- // high word containing the vertical coordinate and the low word containing the
- // horizontal coordinate). The coordinates given are local coordinates.
- // ----------
-
- case testCntl:
- returnValue = FindControlPart(theControl,varCode,*((Point*)(¶m)));
- break;
-
- // ----------
- // calcCRgns -- Calculate control or thumb region (24-bit addressing mode only). If the
- // high bit of param is set, calculate the thumb region. Otherwise, calculate
- // the control region. In either case clear the high bit of param to get the
- // valid region handle.
- // ----------
-
- case calcCRgns:
- if ( ( param & 0x80000000 ) == 0 )
- CalculateControlRegion(theControl,varCode,(RgnHandle)(param&0x7FFFFFFF));
- else
- CalculateIndicatorRegion(theControl,varCode,(RgnHandle)(param&0x7FFFFFFF));
- break;
-
- // ----------
- // initCntl -- Perform any additional initialization.
- // ----------
-
- case initCntl:
- InitControl(theControl,varCode);
- break;
-
- // ----------
- // dispCntl -- Perform any additional disposal actions.
- // ----------
-
- case dispCntl:
- DispControl(theControl,varCode);
- break;
-
- // ----------
- // posCntl -- Displace the control indicator by the offsets in param and update the
- // contrlValue field of the control record. The offsets are stored as follows:
- // vertical offset in high word of param, horizontal offset in low word of param.
- // Both are signed quantities. Once again the stange cast on param is to make
- // the compiler jump through the right hoops and push the high word of param.
- // ----------
-
- case posCntl:
- PositionIndicator(theControl,varCode,*((short*)(¶m)),param);
- break;
-
- // ----------
- // thumbCntl -- Calculate parameters for indicator dragging. The location of the mouse-
- // down event which triggered this message is given, in local coordinates,
- // at the address pointed to by param. Further, param points to a structure
- // of type IndicatorDragConstraint (see header file Controls.h) to be filled
- // in by the CDEF. Fields within the IndicatorDragConstraint structure are
- // analogus to those for DragGrayRgn().
- // ----------
-
- case thumbCntl:
- CalcIndicatorValues(theControl,varCode,*((Point*)(param)),
- (IndicatorDragConstraintPtr)param);
- break;
-
- // ----------
- // dragCntl -- Drag the control or its indicator. If param == 0 then the entire control is
- // to be dragged, otherwise, just the indicator is to be dragged. If you want
- // the Control Manager to drag for you (using DragControl() for controls and
- // DragGrayRgn() for indicators), just return 0. Otherwise, drag it yourself and
- // call MoveControl() when done moving entire controls or change the contrlValue
- // field of the control record and redraw the control. Note that TrackControl()
- // always returns 0 for custom indicator dragging and this can cause problems
- // if it is not expected. Refer to IM: Mac TB Essentials, pp. 5-114 and 5-115
- // for details.
- // ----------
-
- case dragCntl:
- returnValue = CustomDrag(theControl,varCode,(param != 0));
- break;
-
- // ----------
- // autoTrack -- Custom control action procedure. The part code that the user clicked
- // on is contained in the low word of param. The high word contains garbage.
- // Action procedures are described in IM: Mac TB Essentials in the Control
- // Manager chapter. Note that for this to work correctly, -1L must be stored
- // in the contrlAction field by the initCntl handler and -1L must be passed
- // to TrackControl() in the actionProc parameter.
- // ----------
-
- case autoTrack:
- ActionProcedure(theControl,varCode,param);
- break;
-
- // ----------
- // calcCntlRgn -- Calculate the control’s region (32-bit addressing mode only). Place the
- // control’s region into the region handle given in param.
- // ----------
-
- case calcCntlRgn:
- CalculateControlRegion(theControl,varCode,(RgnHandle)param);
- break;
-
- // ----------
- // calcThumbRgn -- Calculate the control indicator’s region (32-bit addressing mode only).
- // Put the control indicator’s region into the region handle given in param.
- // ----------
-
- case calcThumbRgn:
- CalculateIndicatorRegion(theControl,varCode,(RgnHandle)param);
- break;
- }
-
- // ----------
- // Return the control record handle to its previous state, restore the A4 register and exit.
- // ----------
-
- HSetState((Handle)theControlHandle, controlRecState);
-
- #ifndef powerc
-
- SetA4(oldA4);
-
- #endif
-
- return (returnValue);
- }
-
- //---------------------------------------------------------------------------------------------------
- // BeginDraw -- This is the first part of a two-layer drawing system. This function saves off and
- // restores all things that are munged during drawing, it figures out whether to
- // draw in color or not, and it gets pointers to the control’s color table and the
- // control’s window’s color table. The actual drawing is performed by the DrawControl()
- // function. (Do not confuse this with the Control Manager’s Draw1Control() call.)
- // Note that not much is actually saved here -- you should save off anything additional
- // which you alter in DrawControl(). This function exists to prevent the draw routine
- // running out of registers for local variables because some are used as storage for
- // these settings. It is, of course, not necessary to separate this code from the
- // actual drawing code if that’s what you desire.
- //---------------------------------------------------------------------------------------------------
-
- void BeginDraw(ControlHandle theControlHandle, short varCode, short partCode)
- {
- ControlPtr theControl = *theControlHandle;
- GrafPtr savePort, controlPort = theControl->contrlOwner;
- Boolean inColor;
- RgnHandle saveClip, newClip;
- PenState savePen;
- SignedByte controlCTableState, windowCTableState;
- CTabHandle windowColorTableHandle, controlColorTableHandle;
- CTabPtr windowColorTable = NULL, controlColorTable = NULL;
- AuxWinHandle theAuxHandle;
- RGBColor saveForeground, saveBackground;
-
- // ----------
- // Should we draw in color? Yes if we are drawing into a color port.
- // ----------
-
- inColor = ( controlPort->portBits.rowBytes & kColorPort ) == kColorPort;
-
- // ----------
- // Save off the current port and make the control’s port current.
- // ----------
-
- GetPort(&savePort);
- SetPort(controlPort);
-
- // ----------
- // Save off the clipping region and set the clipping region to the intersection of the control’s
- // rectangle and the old clipping region.
- // ----------
-
- saveClip = NewRgn();
- GetClip(saveClip);
- newClip = NewRgn();
- RectRgn(newClip,&(theControl->contrlRect));
- SectRgn(newClip,saveClip,newClip);
- SetClip(newClip);
- DisposeRgn(newClip);
-
- // ----------
- // Save off and reset the pen state.
- // ----------
-
- GetPenState(&savePen);
- PenNormal();
-
- // ----------
- // If we are drawing in color, save the foreground and background colors. Get pointers to the
- // control’s color table and the control’s window’s color table. Note that the color tables need
- // to be locked in order for the FindColorInTable() function (included here) to return stable
- // addresses, so save the states of the color tables’ handles and lock them down.
- // ----------
-
- if ( inColor ) {
-
- GetForeColor(&saveForeground);
- GetBackColor(&saveBackground);
-
- GetAuxWin(controlPort,&theAuxHandle);
- windowColorTableHandle = (**theAuxHandle).awCTable;
- windowCTableState = HGetState((Handle)windowColorTableHandle);
- HLock((Handle)windowColorTableHandle);
- windowColorTable = *windowColorTableHandle;
-
- GetAuxCtl(theControlHandle,(AuxCtlHandle*)(&theAuxHandle));
- controlColorTableHandle = (CTabHandle)(**(AuxCtlHandle)theAuxHandle).acCTable;
- controlCTableState = HGetState((Handle)controlColorTableHandle);
- HLock((Handle)controlColorTableHandle);
- controlColorTable = *controlColorTableHandle;
- }
-
- // ----------
- // Draw the control.
- // ----------
-
- DrawControl(theControl,varCode,partCode,windowColorTable,controlColorTable,inColor);
-
- // ----------
- // If we are in color, restore the foreground and background colors, and return the color
- // tables’ handles to thier previous states.
- // ----------
-
- if ( inColor ) {
-
- HSetState((Handle)windowColorTableHandle,windowCTableState);
- HSetState((Handle)controlColorTableHandle,controlCTableState);
-
- RGBForeColor(&saveForeground);
- RGBBackColor(&saveBackground);
- }
-
- // ----------
- // Restore the pen state.
- // ----------
-
- SetPenState(&savePen);
-
- // ----------
- // Reset the clipping region to the original clipping region.
- // ----------
-
- SetClip(saveClip);
- DisposeRgn(saveClip);
-
- // ----------
- // Set the port back and exit.
- // ----------
-
- SetPort(savePort);
- }
-
- //---------------------------------------------------------------------------------------------------
- // DrawControl -- Perform the actual control drawing. All the relevant information should be given
- // either in the control record or in the function parameters. Note that the inColor
- // parameter is true if the control’s port is a color port -- it does not indicate
- // what bit depth the current device is using, nor does it distinguish between color
- // and greyscale devices. If that information is needed by your CDEF, you will need
- // to get it from the appropriate sources.
- //---------------------------------------------------------------------------------------------------
-
- void DrawControl(ControlPtr theControl, short varCode, short partCode, CTabPtr windowColorTable,
- CTabPtr controlColorTable, Boolean inColor)
- {
- }
-
- //---------------------------------------------------------------------------------------------------
- // FindControlPart -- Determine and return the part code of the control part which contains hitPoint.
- // Note that hitPoint is given in coordinates local to the control’s port. Return
- // 0 if hitPoint lies outside of the given control.
- //---------------------------------------------------------------------------------------------------
-
- short FindControlPart(ControlPtr theControl, short varCode, Point hitPoint)
- {
- return(0);
- }
-
- //---------------------------------------------------------------------------------------------------
- // CalculateControlRegion -- Place in theRegion the region occupied by the entire given control. Note
- // that theRegion is already a valid RgnHandle; you do not need to call
- // NewRgn() to initialize it.
- //---------------------------------------------------------------------------------------------------
-
- void CalculateControlRegion(ControlPtr theControl, short varCode, RgnHandle theRegion)
- {
- EmptyRgn(theRegion);
- }
-
- //---------------------------------------------------------------------------------------------------
- // CalculateIndicatorRegion -- Place in theRegion the region occupied by the control’s indicator.
- // Note that theRegion is already a valid RgnHandle; you do not need to
- // call NewRgn() to initialize it.
- //---------------------------------------------------------------------------------------------------
-
- void CalculateIndicatorRegion(ControlPtr theControl, short varCode, RgnHandle theRegion)
- {
- EmptyRgn(theRegion);
- }
-
- //---------------------------------------------------------------------------------------------------
- // InitControl -- Perform any additional initialization needed.
- //---------------------------------------------------------------------------------------------------
-
- void InitControl(ControlPtr theControl, short varCode)
- {
- }
-
- //---------------------------------------------------------------------------------------------------
- // DispControl -- Perform any additional disposal actions needed.
- //---------------------------------------------------------------------------------------------------
-
- void DispControl(ControlPtr theControl, short varCode)
- {
- }
-
- //---------------------------------------------------------------------------------------------------
- // PositionIndicator -- Offset the position of the control’s indicator by dh in the horizontal
- // direction and dv in the vertical direction. Update the contrlValue field
- // of the ControlRecord and redraw the control to reflect the new setting.
- // See the NOTE under CustomDrag regarding updating contrlValue and redrawing.
- //---------------------------------------------------------------------------------------------------
-
- void PositionIndicator(ControlPtr theControl, short varCode, short dv, short dh)
- {
- }
-
- //---------------------------------------------------------------------------------------------------
- // CalcIndicatorValues -- Calculate parameters for dragging the control’s indicator. The hitPoint
- // parameter contains the point at which the mouse-down event triggering this
- // message occurred. This routine should fill in all the fields of the struct
- // pointed to by info.
- //---------------------------------------------------------------------------------------------------
-
- void CalcIndicatorValues(ControlPtr theControl, short varCode, Point hitPoint,
- IndicatorDragConstraintPtr info)
- {
- }
-
- //---------------------------------------------------------------------------------------------------
- // CustomDrag -- Perform custom dragging of the control or the control’s indicator. If no custom
- // dragging is desired return 0. If the entire control s custom dragged, call
- // MoveControl() to move the control to its destination after the mouse button is
- // released. If the indicator is custom dragged, the new setting must be calculated,
- // the contrlValue field updated, and the control redrawn. A nonzero value should be
- // returned if custom dragging is used. The dragIndicator parameter is true if just
- // the indicator is to be dragged, false if the whole control is to be dragged.
- //
- // NOTE: Updating of the contrlValue field and redrawing of the control should be
- // done directly; don’t call the Control Manager’s functions SetCtlValue() to do
- // this. The reason is that the Control Manager locks the CDEF when calling it and
- // then unlocks it upon returning. This is not reentrant: for example, assume we are
- // called with a dragCntl message. The CDEF is locked, and called. Within the CDEF, a
- // call is made to SetCtlValue(). The Control Manager knows the control should be
- // drawn to reflect it’s new setting so it locks and calls the CDEF with a drawCntl
- // message. When the CDEF returns from drawing, the Control Manager unlocks it and
- // SetCtlValue() returns, coming back to the original invocation of the CDEF. We are
- // now running in an unlocked block of code. If the Memory Manager decides to move
- // the CDEF, crash-o-rama. The moral: DON’T CALL CONTROL MANAGER ROUTINES FROM WITHIN
- // A CDEF -- DO EVERYTHING DIRECTLY.
- //---------------------------------------------------------------------------------------------------
-
- Boolean CustomDrag(ControlPtr theControl, short varCode, Boolean dragIndicator)
- {
- return(false);
- }
-
- //---------------------------------------------------------------------------------------------------
- // ActionProcedure -- Custom action procedure. Action procedures are described in the Control Manager
- // chapter of IM: Mac TB Essentials. Note that for this action procedure to work
- // properly, -1 must be stored in the contrlAction field of the Control Record
- // (best done during the initCntl message -- in the InitControl function here) and
- // -1 must be passed to TrackControl in the actionProc parameter.
- //---------------------------------------------------------------------------------------------------
-
- void ActionProcedure(ControlPtr theControl, short varCode, short partCode)
- {
- }
-
- //---------------------------------------------------------------------------------------------------
- // FindColorInTable -- Returns a pointer to the RGBColor field of the ColorSpec record with the
- // corresponding value field in the given color table. Returns a pointer to the
- // first color in the table if no ColorSpec with value == id was found. (Matches
- // the way the standard CDEF’s search color tables.
- //---------------------------------------------------------------------------------------------------
-
- RGBColor *FindColorInTable (CTabPtr colorTable, short id)
- {
- short counter;
-
- for (counter = colorTable->ctSize; counter > 0; counter--) {
-
- if ( colorTable->ctTable[counter].value == id )
- break;
- }
-
- return ( &( colorTable->ctTable[counter].rgb ) );
- }