home *** CD-ROM | disk | FTP | other *** search
-
- /*
- **
- ** $VER: dispatch.c 1.3 (12.10.97)
- ** embed.datatype 1.3
- **
- ** Dispatch routine for a DataTypes class
- **
- ** Written 1996/1997 by Roland 'Gizzy' Mainz
- ** Original example source from David N. Junod
- **
- */
-
- /* main includes */
- #include "classbase.h"
-
- /*****************************************************************************/
- /* Source configuration */
-
- #define DRAW_BOX_AROUND_OBJECT 1
-
- /*****************************************************************************/
-
- #define EMBEDA_Dummy (TAG_USER + 0x002B2000UL)
- #define EMBEDA_Sync (EMBEDA_Dummy + 1UL)
- #define EMBEDA_SyncObjectLine (EMBEDA_Dummy + 2UL)
-
- /*****************************************************************************/
-
- /* local prototypes */
- static struct GadgetInfo *CreateGadgetInfoClipBuffer( struct ClassBase *, struct GadgetInfo *, struct EmbedLine * );
- static void FreeGadgetInfoClipBuffer( struct ClassBase *, struct GadgetInfo * );
- static void SyncGadgetInfoClipBuffer( struct ClassBase *, struct GadgetInfo *, struct GadgetInfo *, struct EmbedLine * );
- static BOOL IsKindOf( struct ClassBase *, Object *, struct IClass *, ClassID );
-
- /*****************************************************************************/
-
- /* A single line segment in our object */
- struct EmbedLine
- {
- struct Line el_Line;
- struct MinNode el_VisibleLink;
- struct IBox el_LineBox;
- struct IBox el_VisibleBox;
- ULONG el_TopVert;
- ULONG el_TopHoriz;
- Object *el_Object; /* datatypesclass object */
- struct BitMap *el_ObjectBitMap;
- BOOL el_IsDTObject;
- BOOL el_ObjectCanClip;
- BOOL el_ObjectIsClipped;
- BOOL el_Pad0;
- Object *el_Model; /* model */
- };
-
- #define VisibleLink2EmbedLine( vl ) ((struct EmbedLine *)(((UBYTE *)(vl)) - offsetof( struct EmbedLine, el_VisibleLink )))
-
- /* embed.datatype instance data */
- struct EmbedInstData
- {
- APTR eid_Pool; /* Object memory pool (misc usage) */
- LONG eid_OldTopVert; /* Last layouted position */
- LONG eid_OldTopHoriz; /* Last layouted position */
- struct IBox eid_OldParentDomain; /* Old parent (win/req/grp) domain */
- struct MinList *eid_LineList;
- struct MinList eid_VisibleMembers;
-
- struct EmbedLine *eid_HitMemberLine;
- struct EmbedLine *eid_HelpMemberLine;
- ULONG eid_HelpMemberCode;
- ULONG eid_HelpMemberReturnedCode;
- struct EmbedLine *eid_ActiveMemberLine;
- };
-
- /*****************************************************************************/
-
- /* Embed model, which saves some usefull object data */
- struct EmbedModelInstData
- {
- struct EmbedLine *emid_ObjectLine;
- BOOL emid_Sync;
- BOOL emid_Busy;
- };
-
- /*****************************************************************************/
-
-
- BOOL initClass( struct ClassBase *cb )
- {
- struct IClass *cl;
-
- /* Create our classes... */
- if( cl = MakeClass( NULL, MODELCLASS, NULL, (ULONG)sizeof( struct EmbedModelInstData ), 0UL ) )
- {
- cl -> cl_Dispatcher . h_Entry = (HOOKFUNC)DispatchModel;
- cl -> cl_UserData = (ULONG)cb;
-
- cb -> cb_EmbedModel = cl; /* store class ptr */
-
- if( cl = MakeClass( EMBEDDTCLASS, TEXTDTCLASS, NULL, (ULONG)sizeof( struct EmbedInstData ), 0UL ) )
- {
- cl -> cl_Dispatcher . h_Entry = (HOOKFUNC)Dispatch;
- cl -> cl_UserData = (ULONG)cb;
-
- cb -> cb_Lib . cl_Class = cl; /* store class ptr */
-
- AddClass( cl );
-
- return( TRUE );
- }
- else
- {
- FreeClass( (cb -> cb_EmbedModel) );
- cb -> cb_EmbedModel = NULL;
- }
- }
-
- return( FALSE );
- }
-
- /*****************************************************************************/
-
- void mysprintf( struct ClassBase *cb, STRPTR buffer, STRPTR fmt, ... )
- {
- APTR args;
-
- args = (APTR)((&fmt) + 1);
-
- RawDoFmt( fmt, args, (void (*))"\x16\xc0\x4e\x75", buffer );
- }
-
-
- /*****************************************************************************/
-
- struct MyStackSwapStruct
- {
- struct StackSwapStruct stk;
- struct IClass *cl;
- Object *o;
- Msg msg;
- };
-
- /*****************************************************************************/
-
- DISPATCHERFLAGS
- ULONG Dispatch( REGA0 struct IClass *cl, REGA2 Object *o, REGA1 Msg msg )
- {
- struct ClassBase *cb = (struct ClassBase *)(cl -> cl_UserData);
- ULONG retval;
- struct MyStackSwapStruct mystk;
- UBYTE *lower,
- *upper,
- *sp;
- struct Task *ThisTask;
- ULONG stacksize;
-
- mystk . cl = cl;
- mystk . o = o;
- mystk . msg = msg;
-
- ThisTask = FindTask( NULL );
- stacksize = (ULONG)(((UBYTE *)(ThisTask -> tc_SPReg)) - ((UBYTE *)(ThisTask -> tc_SPLower)));
-
- #define DTSTACKSIZE (16384UL)
-
- /* Enougth stack ? */
- if( stacksize > (DTSTACKSIZE / 2UL) )
- {
- retval = MyDispatch( (&mystk) );
- }
- else
- {
- /* Alloc a new stack frame... */
- while( !(lower = (UBYTE *)AllocMem( DTSTACKSIZE, MEMF_PUBLIC )) );
-
- sp = upper = lower + DTSTACKSIZE;
-
- mystk . stk . stk_Lower = lower;
- mystk . stk . stk_Upper = (ULONG)upper;
- mystk . stk . stk_Pointer = sp;
-
- retval = SwapMe( (&mystk) );
-
- FreeMem( lower, DTSTACKSIZE );
- }
-
- return( retval );
- }
-
-
- DISPATCHERFLAGS
- ULONG SwapMe( REGA0 struct MyStackSwapStruct *mystk )
- {
- ULONG retval;
-
- #define cb ((struct ClassBase *)(mystk -> cl -> cl_UserData))
-
- StackSwap( (&(mystk -> stk)) );
-
- retval = MyDispatch( mystk );
-
- StackSwap( (&(mystk -> stk)) );
- #undef cb
-
- return( retval );
- }
-
-
- DISPATCHERFLAGS
- ULONG MyDispatch( REGA0 struct MyStackSwapStruct *mystk )
- {
- struct IClass *cl = mystk -> cl;
- Object *o = mystk -> o;
- Msg msg = mystk -> msg;
-
- struct ClassBase *cb = (struct ClassBase *)(cl -> cl_UserData);
- struct EmbedInstData *eid;
- struct MinList *linelist;
- ULONG retval = 0UL;
-
- switch( msg -> MethodID )
- {
- case OM_NEW:
- {
- if( retval = DoSuperMethodA( cl, o, msg ) )
- {
- ULONG len,
- estlines,
- poolsize;
- BOOL success = FALSE;
- STRPTR buffer;
-
- /* Get a pointer to the object data */
- eid = (struct EmbedInstData *)INST_DATA( cl, (Object *)retval );
-
- NewList( (struct List *)(&(eid -> eid_VisibleMembers)) );
-
- /* Get the attributes that we need to determine
- * memory pool size
- */
- GetDTAttrs( (Object *)retval,
- TDTA_Buffer, (&buffer),
- TDTA_BufferLen, (&len),
- TAG_DONE );
-
- /* Make sure we have a text buffer */
- if( buffer && len )
- {
- /* Estimate the pool size that we will need */
- estlines = (len / 80) + 1;
- estlines = (estlines > 200) ? 200 : estlines;
- poolsize = sizeof (struct EmbedLine) * estlines;
-
- /* Create a memory pool for the line list */
- if( eid -> eid_Pool = CreatePool( (MEMF_CLEAR | MEMF_PUBLIC), poolsize, poolsize ) )
- {
- success = TRUE;
- }
- else
- {
- SetIoErr( ERROR_NO_FREE_STORE );
- }
- }
- else
- {
- /* Indicate that something was missing that we needed */
- SetIoErr( ERROR_REQUIRED_ARG_MISSING );
- }
-
- if( success )
- {
- parseMethod( cb, cl, (Object *)retval );
- }
- else
- {
- CoerceMethod( cl, (Object *)retval, OM_DISPOSE );
- retval = NULL;
- }
- }
- }
- break;
-
- case OM_UPDATE:
- {
- /* Avoid OM_NOTIFY loops */
- if( DoMethod( o, ICM_CHECKLOOP ) )
- {
- break;
- }
- }
- case OM_SET:
- {
- struct GadgetInfo *gi = ((struct opSet *)msg) -> ops_GInfo;
-
- /* Get a pointer to the object data */
- eid = (struct EmbedInstData *)INST_DATA( cl, o );
-
- /* Pass the attributes to the text class and force a refresh if we need it */
- retval = DoSuperMethodA( cl, o, msg );
-
- /* Do layout, if required */
- if( BumpMembers( cl, o, gi ) )
- {
- /* If there was a layout => redraw */
- retval = 1UL;
- }
-
- /* Is this a member sync msg ? */
- if( FindTagItem( EMBEDA_Sync, (((struct opSet *)msg) -> ops_AttrList) ) )
- {
- BOOL busy = FALSE;
- struct EmbedLine *worknode,
- *nextnode;
- struct EmbedLine *refreshline;
-
- /* Check if we need only to update a single object... */
- if( refreshline = (struct EmbedLine *)GetTagData( EMBEDA_SyncObjectLine, 0UL, (((struct opSet *)msg) -> ops_AttrList) ) )
- {
- /* We don't need to update a single member when a global refresh will be triggered... */
- if( retval == 0UL )
- {
- struct RastPort *rp;
- struct GadgetInfo *buffer_gi = NULL,
- *member_gi = gi;
-
- if( !((refreshline -> el_ObjectCanClip) || ((refreshline -> el_ObjectIsClipped) == FALSE)) )
- {
- member_gi = buffer_gi = CreateGadgetInfoClipBuffer( cb, gi, refreshline );
- }
-
- if( member_gi )
- {
- /* Get a pointer to the rastport */
- if( rp = ObtainGIRPort( member_gi ) )
- {
- struct gpRender gpr;
-
- /* Force a redraw */
- gpr . MethodID = GM_RENDER;
- gpr . gpr_GInfo = member_gi;
- gpr . gpr_RPort = rp;
- gpr . gpr_Redraw = GREDRAW_REDRAW;
-
- (void)DoMethodA( (refreshline -> el_Object), (Msg)(&gpr) );
-
- /* Release the temporary rastport */
- ReleaseGIRPort( rp );
- }
- }
-
- if( buffer_gi );
- {
- SyncGadgetInfoClipBuffer( cb, gi, buffer_gi, refreshline );
-
- FreeGadgetInfoClipBuffer( cb, buffer_gi );
- }
- }
- }
- else
- {
- /* Broadcast refresh: Refresh whole object */
- retval = 1UL;
- }
-
- /* Any member busy ? */
- worknode = (struct EmbedLine *)(eid -> eid_LineList -> mlh_Head);
-
- while( nextnode = (struct EmbedLine *)(worknode -> el_Line . ln_Link . mln_Succ) )
- {
- if( worknode -> el_Model )
- {
- if( busy = IsModelBusy( cb, (worknode -> el_Model) ) )
- {
- break;
- }
- }
-
- worknode = nextnode;
- }
-
- /* Tell everyone that we are busy doing things */
- notifyAttrChanges( o, gi, 0UL,
- GA_ID, G( o ) -> GadgetID,
- DTA_Busy, busy,
- TAG_DONE );
- }
-
- /* Refresh ? */
- if( retval )
- {
- /* Top instance ? */
- if( OCLASS( o ) == cl )
- {
- struct RastPort *rp;
-
- /* Get a pointer to the rastport */
- if( rp = ObtainGIRPort( gi ) )
- {
- struct gpRender gpr;
-
- /* Force a redraw */
- gpr . MethodID = GM_RENDER;
- gpr . gpr_GInfo = gi;
- gpr . gpr_RPort = rp;
- gpr . gpr_Redraw = GREDRAW_REDRAW;
-
- DoMethodA( o, (Msg)(&gpr) );
-
- /* Release the temporary rastport */
- ReleaseGIRPort( rp );
- }
-
- retval = 0UL;
- }
- }
- }
- break;
-
- case GM_HITTEST:
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *)(G( o ) -> SpecialInfo);
-
- eid = (struct EmbedInstData *)INST_DATA( cl, o );
-
- if( AttemptSemaphoreShared( (&(si -> si_Lock)) ) )
- {
- struct MinNode *worknode,
- *nextnode;
- struct IBox *domain;
-
- GetDTAttrs( o, DTA_Domain, (&domain), TAG_DONE );
-
- /* Query all members (gadgets) */
- worknode = eid -> eid_VisibleMembers . mlh_Head;
-
- while( nextnode = worknode -> mln_Succ )
- {
- struct EmbedLine *work = VisibleLink2EmbedLine( worknode );
-
- if( work -> el_Object )
- {
- /* Member disabled ? */
- if( !((EXTG( (work -> el_Object) ) -> Flags) & GFLG_DISABLED) )
- {
- if( retval = DoMemberHitTest( domain, (work -> el_Object), (struct gpHitTest *)msg ) )
- {
- eid -> eid_HitMemberLine = work;
-
- break;
- }
- }
- }
-
- worknode = nextnode;
- }
-
- ReleaseSemaphore( (&(si -> si_Lock)) );
- }
- }
- break;
-
- case GM_HELPTEST:
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *)(G( o ) -> SpecialInfo);
-
- eid = (struct EmbedInstData *)INST_DATA( cl, o );
-
- if( AttemptSemaphoreShared( (&(si -> si_Lock)) ) )
- {
- UWORD member_count = 0U;
-
- struct MinNode *worknode,
- *nextnode;
- struct IBox *domain = NULL;
- struct EmbedLine *memberline = NULL;
- Object *member = NULL;
-
- GetDTAttrs( o, DTA_Domain, (&domain), TAG_DONE );
-
- /* Query all members (gadgets) */
- worknode = eid -> eid_VisibleMembers . mlh_Head;
-
- while( nextnode = worknode -> mln_Succ )
- {
- memberline = VisibleLink2EmbedLine( worknode );
-
- if( member = memberline -> el_Object )
- {
- member_count++;
-
- /* Does the object request GM_HELPTEST ? */
- if( (EXTG( member ) -> MoreFlags) & GMORE_GADGETHELP )
- {
- ULONG member_retval;
-
- if( member_retval = DoMemberHitTest( domain, member, (struct gpHitTest *)msg ) )
- {
- if( member_retval == GMR_HELPHIT )
- {
- retval = (GMR_HELPCODE | member_count);
-
- eid -> eid_HelpMemberCode = 0x0000FFFFUL;
- }
- else
- {
- /* Note that member_retval includes GMR_HELPCODE */
- retval = (member_retval | member_count);
-
- eid -> eid_HelpMemberCode = member_retval & (~GMR_HELPCODE);
- }
-
- break;
- }
- }
- }
-
- worknode = nextnode;
- }
-
- /* Something hit ? */
- if( nextnode )
- {
- /* Did another group member return the same helpcode like the last help member ??
- * Note that intuition won't send IDCMP_GADGETHELP for those msgs.
- * In this case we're creating a different helpcode,
- * the orginal one may be obtained through EMBEDA_HelpCode attribute
- */
- if( ((eid -> eid_HelpMemberReturnedCode) == retval) && ((eid -> eid_HelpMemberLine -> el_Object) != member) )
- {
- retval += 1UL;
- }
- }
-
- eid -> eid_HelpMemberReturnedCode = retval;
- eid -> eid_HelpMemberLine = memberline;
-
- ReleaseSemaphore( (&(si -> si_Lock)) );
- }
- else
- {
- /* retval = GMR_NOHELPHIT;
- * GMR_NOHELPHIT == 0UL, which will be NOP
- */
- }
- }
- break;
-
- case GM_GOACTIVE:
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *)(G( o ) -> SpecialInfo);
-
- eid = (struct EmbedInstData *)INST_DATA( cl, o );
-
- /* During layout we cannot be activated */
- if( !((si -> si_Flags) & DTSIF_LAYOUT) )
- {
- /* Will be released inside GM_HANDLEINPUT method, see below */
- if( AttemptSemaphoreShared( (&(si -> si_Lock)) ) )
- {
- if( ((eid -> eid_ActiveMemberLine) == NULL) )
- {
- struct EmbedLine *memberline;
-
- memberline = eid -> eid_HitMemberLine;
- eid -> eid_HitMemberLine = NULL;
-
- if( !((EXTG( (memberline -> el_Object) ) -> Flags) & GFLG_DISABLED) )
- {
- eid -> eid_ActiveMemberLine = memberline;
-
- (EXTG( (memberline -> el_Object) ) -> Activation) |= GACT_ACTIVEGADGET;
- }
- }
- }
- else
- {
- /* Object locked by another task */
- retval = GMR_NOREUSE;
- break;
- }
- }
- else
- {
- /* Currently in layout, can't render yet */
- retval = GMR_NOREUSE;
- break;
- }
- }
- case GM_HANDLEINPUT:
- {
- struct gpInput gpi = *((struct gpInput *)msg);
- struct GadgetInfo *gi;
- struct IBox gbox;
- struct DTSpecialInfo *si = (struct DTSpecialInfo *)(G( o ) -> SpecialInfo);
- struct EmbedLine *memberline;
- struct IBox *domain;
-
- eid = (struct EmbedInstData *)INST_DATA( cl, o );
-
- gi = gpi . gpi_GInfo;
-
- /* Check if instance semaphore wasn't already obtained by GM_GOACTIVE (see upstairs) */
- if( (msg -> MethodID) == GM_HANDLEINPUT )
- {
- /* During layout we cannot be active */
- if( !((si -> si_Flags) & DTSIF_LAYOUT) )
- {
- /* Obtain instance data, if possible */
- if( !AttemptSemaphoreShared( (&(si -> si_Lock)) ) )
- {
- retval = GMR_NOREUSE;
- break;
- }
- }
- else
- {
- /* Layout in progress */
- retval = GMR_NOREUSE;
- break;
- }
- }
-
- GetDTAttrs( o, DTA_Domain, (&domain), TAG_DONE );
-
- if( memberline = eid -> eid_ActiveMemberLine )
- {
- Object *member = memberline -> el_Object;
-
- if( (memberline -> el_ObjectCanClip) || ((memberline -> el_ObjectIsClipped) == FALSE) )
- {
-
- gbox = GetAbsGadgetBox( (&(gi -> gi_Domain)), EXTG( member ), FALSE );
- #if 0
- if( gpi . gpi_IEvent )
- {
- gpi . gpi_IEvent -> ie_X -= ((gbox . Left) - (domain -> Left));
- gpi . gpi_IEvent -> ie_Y -= ((gbox . Top) - (domain -> Top));
- }
- #endif
-
- (gpi . gpi_Mouse . X) -= ((gbox . Left) - (domain -> Left));
- (gpi . gpi_Mouse . Y) -= ((gbox . Top) - (domain -> Top));
-
- retval = DoMethodA( member, (Msg)(&gpi) );
-
- (gpi . gpi_Mouse . X) += ((gbox . Left) - (domain -> Left));
- (gpi . gpi_Mouse . Y) += ((gbox . Top) - (domain -> Top));
-
- #if 0
- if( gpi . gpi_IEvent )
- {
- gpi . gpi_IEvent -> ie_X += ((gbox . Left) - (domain -> Left));
- gpi . gpi_IEvent -> ie_Y += ((gbox . Top) - (domain -> Top));
- }
- #endif
- }
- else
- {
- struct GadgetInfo *buffer_gi;
-
- #if 0
- kprintf( "class %lu sub %lu ie x %ld ie y %ld mx %ld my %ld\n",
- (LONG)(gpi . gpi_IEvent -> ie_Class), (LONG)(gpi . gpi_IEvent -> ie_SubClass),
- (LONG)(gpi . gpi_IEvent -> ie_X), (LONG)(gpi . gpi_IEvent -> ie_Y),
- (LONG)(gpi . gpi_Mouse . X), (LONG)(gpi . gpi_Mouse . Y) );
- #endif
-
- if( buffer_gi = CreateGadgetInfoClipBuffer( cb, gi, memberline ) )
- {
- gpi . gpi_GInfo = buffer_gi;
-
- (gpi . gpi_Mouse . X) -= (memberline -> el_TopHoriz);
- (gpi . gpi_Mouse . Y) -= (memberline -> el_TopVert);
-
- retval = DoMethodA( (memberline -> el_Object), (Msg)(&gpi) );
-
- (gpi . gpi_Mouse . X) += (memberline -> el_TopHoriz);
- (gpi . gpi_Mouse . Y) += (memberline -> el_TopVert);
-
- gpi . gpi_GInfo = gi;
-
- SyncGadgetInfoClipBuffer( cb, gi, buffer_gi, memberline );
-
- FreeGadgetInfoClipBuffer( cb, buffer_gi );
- }
- }
-
- if( retval != GMR_MEACTIVE )
- {
- #ifdef COMMENTED_OUT
- if( retval & (GMR_NEXTACTIVE | GMR_PREVACTIVE) )
- {
- Object *member;
- BOOL match;
- struct TagItem ActivateMemberTags[ 2 ];
- struct gpGoInactive gpgi;
-
- match = FALSE;
-
- if( retval & GMR_NEXTACTIVE )
- {
- /* Activate next member... */
-
- /* Scan through GadgetCollectionList and return the next member after member_object
- * which has the GFLG_TABCYCLE flag set.
- * First scan until member_object was found (then set match = TRUE)...
- * ...then (if( match == TRUE)) get the next GFLG_TABCYCLE member
- */
- object_state = (Object *)(eid -> eid_GadgetCollectionList . mlh_Head);
-
- while( member = (Object *)NextObject( (&object_state) ) )
- {
- if( match )
- {
- if( ((EXTG( member ) -> Flags) & GFLG_TABCYCLE) && (!((EXTG( member ) -> Flags) & GFLG_DISABLED)) )
- {
- break;
- }
- }
- else
- {
- if( member == member_object )
- {
- match = TRUE;
- }
- }
- }
-
- /* If there a match but we reach end of GadgetCollectionList, get the first GFLG_TABCYCLE member */
- if( (member == NULL) && (match == TRUE) )
- {
- object_state = (Object *)(eid -> eid_GadgetCollectionList . mlh_Head);
-
- while( member = (Object *)NextObject( (&object_state) ) )
- {
- if( ((EXTG( member ) -> Flags) & GFLG_TABCYCLE) && (!((EXTG( member ) -> Flags) & GFLG_DISABLED)) )
- {
- break;
- }
- }
- }
- }
- else
- {
- /* Activate previous member... */
- member = member_object;
-
- /* Scan through GadgetCollectionList until...
- * ...PrevObjectContinous returns NULL
- * ...we found a previous member which has the GFLG_TABCYCLE flag set or
- * ...the object PrevObjectContinous returns is the same as the member_object one
- */
- do
- {
- member = PrevObjectContinous( member, (&(eid -> eid_GadgetCollectionList)) );
-
- if( member == NULL )
- {
- break;
- }
- } while( ((!((EXTG( member ) -> Flags) & GFLG_TABCYCLE)) || ((EXTG( member ) -> Flags) & GFLG_DISABLED)) && (member != member_object) );
- }
-
- if( member == NULL )
- {
- member = member_object;
- }
-
- /* Abort (deactivate) current member */
- gpgi . MethodID = GM_GOINACTIVE;
- gpgi . gpgi_GInfo = gi;
- gpgi . gpgi_Abort = 0UL; /* Aborted on own request (GMR_NEXTACTIVE or GMR_PREVACTIVE) */
-
- DoMethodA( o, (Msg)(&gpgi) );
-
-
- /* Activate the next/previous member */
- ActivateMemberTags[ 0 ] . ti_Tag = EMBEDA_ActiveMember;
- ActivateMemberTags[ 0 ] . ti_Data = (ULONG)member;
- ActivateMemberTags[ 1 ] . ti_Tag = TAG_DONE;
- ActivateMemberTags[ 1 ] . ti_Data = 0UL;
-
- DoMethod( o, OM_SET, ActivateMemberTags, gi );
-
- retval = ((eid -> eid_ActiveMember) == member)?(GMR_MEACTIVE):(GMR_NOREUSE);
- }
- else
- #endif
- {
- if( retval & GMR_REUSE )
- {
- /* Check if any of my members was hit... */
- struct gpHitTest gpht;
-
- gpht . MethodID = GM_HITTEST;
- gpht . gpht_GInfo = gi;
- gpht . gpht_Mouse . X = gpi . gpi_Mouse . X;
- gpht . gpht_Mouse . Y = gpi . gpi_Mouse . Y;
-
- /* Check if a member was hit -- but it shouldn't be the current active member */
- if( DoMethodA( o, (Msg)(&gpht) ) == GMR_GADGETHIT )
- {
- if( (eid -> eid_ActiveMemberLine) != (eid -> eid_HitMemberLine) )
- {
- /* If there was a hit, deactivate the old member and activate the new one */
- struct gpInput member_gpi;
-
- /* Abort (deactivate) current member */
- struct gpGoInactive gpgi;
-
- gpgi . MethodID = GM_GOINACTIVE;
- gpgi . gpgi_GInfo = gi;
- gpgi . gpgi_Abort = 0UL; /* Aborted on own request (retval != GMR_MEACTIVE) */
-
- DoMethodA( o, (Msg)(&gpgi) );
-
- /* Change msg to a GM_GOACTIVE one */
- member_gpi = gpi;
- member_gpi . MethodID = GM_GOACTIVE;
-
- /* Activate new member (found in (eid -> eid_HitMemberLine)),
- * which should return GMR_MEACTIVE
- */
- retval = DoMethodA( o, (Msg)(&member_gpi) );
- }
- }
- }
- }
- }
- }
- else
- {
- /* intuition should reuse this event (no member active etc.) */
- retval = GMR_REUSE;
- }
-
- ReleaseSemaphore( (&(si -> si_Lock)) );
- }
- break;
-
- case GM_GOINACTIVE:
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *)(G( o ) -> SpecialInfo);
- struct EmbedLine *memberline;
- Object *member;
- struct gpGoInactive *gpgi = (struct gpGoInactive *)msg;
- struct GadgetInfo *gi;
-
- eid = (struct EmbedInstData *)INST_DATA( cl, o );
-
- gi = gpgi -> gpgi_GInfo;
-
- ObtainSemaphoreShared( (&(si -> si_Lock)) );
-
- if( memberline = eid -> eid_ActiveMemberLine )
- {
- member = memberline -> el_Object;
-
- /* pass msg to active member... */
- if( (memberline -> el_ObjectCanClip) || ((memberline -> el_ObjectIsClipped) == FALSE) )
- {
- retval = DoMethodA( member, msg );
- }
- else
- {
- struct GadgetInfo *buffer_gi;
-
- if( buffer_gi = CreateGadgetInfoClipBuffer( cb, gi, memberline ) )
- {
- gpgi -> gpgi_GInfo = buffer_gi;
-
- retval = DoMethodA( (memberline -> el_Object), (Msg)gpgi );
-
- gpgi -> gpgi_GInfo = gi;
-
- SyncGadgetInfoClipBuffer( cb, gi, buffer_gi, memberline );
-
- FreeGadgetInfoClipBuffer( cb, buffer_gi );
- }
- }
-
- /* Clear the GACT_ACTIVEGADGET flag */
- (EXTG( member ) -> Activation) &= (~GACT_ACTIVEGADGET);
-
- /* No active member */
- eid -> eid_ActiveMemberLine = NULL;
- }
-
- ReleaseSemaphore( (&(si -> si_Lock)) );
- }
- break;
-
- case GM_RENDER:
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *)(G( o ) -> SpecialInfo);
-
- /* We must not render during layout */
- if( !((si -> si_Flags) & DTSIF_LAYOUT) )
- {
- struct gpRender gpr = *((struct gpRender *)msg);
- struct GadgetInfo *gi = gpr . gpr_GInfo;
-
- eid = (struct EmbedInstData *)INST_DATA( cl, o );
-
- /* Be sure that all members (gadgets) are on the right place when redrawing ! */
- BumpMembers( cl, o, gi );
-
- /* Clear our gadget box */
- if( gpr . gpr_RPort )
- {
- /* If this is a major redraw, then erase the old image */
- if( ((gpr . gpr_Redraw) == GREDRAW_REDRAW) ||
- ((si -> si_OTopVert) != (si -> si_TopVert)) || ((si -> si_OTopHoriz) != (si -> si_TopHoriz)) )
- {
- struct IBox *domain;
-
- GetDTAttrs( o, DTA_Domain, (&domain), TAG_DONE );
-
- EraseRect( (gpr . gpr_RPort), (LONG)(domain -> Left),
- (LONG)(domain -> Top),
- (LONG)((domain -> Left) + (domain -> Width) - 1L),
- (LONG)((domain -> Top) + (domain -> Height) - 1L) );
- }
- }
-
- /* Redraw members */
- if( AttemptSemaphoreShared( (&(si -> si_Lock)) ) )
- {
- struct MinNode *worknode,
- *nextnode;
- struct TextFont *font;
-
- GetDTAttrs( o, DTA_TextFont, (&font), TAG_DONE );
-
- #if 0
- /* First let the superclass partake */
- retval = DoSuperMethodA( cl, o, (Msg)(&gpr) );
- #endif
-
- worknode = eid -> eid_VisibleMembers . mlh_Head;
-
- while( nextnode = worknode -> mln_Succ )
- {
- struct EmbedLine *work = VisibleLink2EmbedLine( worknode );
-
- if( work -> el_Object )
- {
- struct gpRender member_gpr = gpr; /* copy message, some old datatype classes modify the message
- * and does not restore the previous contents
- */
-
- member_gpr . gpr_Redraw = GREDRAW_REDRAW;
-
- if( (work -> el_ObjectCanClip) || ((work -> el_ObjectIsClipped) == FALSE) )
- {
- /* Let the member render itself */
- (void)DoMethodA( (work -> el_Object), (Msg)(&member_gpr) );
- }
- else
- {
- struct GadgetInfo *buffer_gi;
-
- if( buffer_gi = CreateGadgetInfoClipBuffer( cb, gi, work ) )
- {
- member_gpr . gpr_GInfo = buffer_gi;
-
- (void)DoMethodA( (work -> el_Object), (Msg)(&member_gpr) );
-
- member_gpr . gpr_GInfo = gi;
-
- SyncGadgetInfoClipBuffer( cb, gi, buffer_gi, work );
-
- FreeGadgetInfoClipBuffer( cb, buffer_gi );
- }
- }
-
- /* test test - sync with blitter (This is not neccesary, but I want to be sure that all is OK after this point) */
- WaitBlit();
-
- #ifdef DRAW_BOX_AROUND_OBJECT
- {
- struct IBox gbox;
-
- /* Draw a little box around the object */
- gbox = GetAbsGadgetBox( (&(gi -> gi_Domain)), EXTG( (work -> el_Object) ), FALSE );
-
- /* Restore real box (which was shrinked in CreateVisibleList to make space for this box) */
- gbox . Left -= 1;
- gbox . Top -= 1;
- gbox . Width += 2;
- gbox . Height += 2;
-
- /* draw a box with shadowcolor around the object */
- SetDrMd( (gpr . gpr_RPort), JAM1 );
- SetAPen( (gpr . gpr_RPort), (ULONG)(gpr . gpr_GInfo -> gi_DrInfo -> dri_Pens[ SHADOWPEN ]) );
- Move( (gpr . gpr_RPort), (LONG)(gbox . Left), (LONG)(gbox . Top) );
- Draw( (gpr . gpr_RPort), (LONG)(gbox . Left), (LONG)(gbox . Top) + (gbox . Height) );
- Draw( (gpr . gpr_RPort), (LONG)(gbox . Left) + (gbox . Width), (LONG)(gbox . Top) + (gbox . Height) );
- Draw( (gpr . gpr_RPort), (LONG)(gbox . Left) + (gbox . Width), (LONG)(gbox . Top) );
- Draw( (gpr . gpr_RPort), (LONG)(gbox . Left), (LONG)(gbox . Top) );
- }
- #endif /* DRAW_BOX_AROUND_OBJECT */
- }
- else
- {
- struct BitMap *bm;
-
- if( bm = AllocBitMap( ((ULONG)(work -> el_Line . ln_Width) + 16UL),
- ((ULONG)(work -> el_Line . ln_Height) + 16UL),
- (ULONG)(gpr . gpr_RPort -> BitMap -> Depth),
- (BMF_CLEAR | BMF_MINPLANES),
- (gpr . gpr_RPort -> BitMap) ) )
- {
- struct RastPort tmprp = { 0 };
-
- InitRastPort( (&tmprp) );
- tmprp . BitMap = bm;
-
- SetABPenDrMd( (&tmprp), (ULONG)(work -> el_Line . ln_FgPen), (ULONG)(work -> el_Line . ln_BgPen), JAM2 );
- Move( (&tmprp), 0, (LONG)(font -> tf_Baseline) );
- Text( (&tmprp), (work -> el_Line . ln_Text), (long)(work -> el_Line . ln_TextLen) );
-
- BltBitMapRastPort( bm, (long)(work -> el_TopHoriz), (long)(work -> el_TopVert),
- (gpr . gpr_RPort),
- (long)(work -> el_VisibleBox . Left),
- (long)(work -> el_VisibleBox . Top),
- (long)(work -> el_VisibleBox . Width),
- (long)(work -> el_VisibleBox . Height),
- 0xC0 );
-
- WaitBlit();
-
- FreeBitMap( bm );
- }
- }
-
- worknode = nextnode;
- }
-
- /* Store the drawn horiz/vert position */
- si -> si_OTopVert = si -> si_TopVert;
- si -> si_OTopHoriz = si -> si_TopHoriz;
-
- ReleaseSemaphore( (&(si -> si_Lock)) );
- }
- else
- {
- D( kprintf( "rendering rejected\n" ) );
- }
- }
- }
- break;
-
- case GM_LAYOUT:
- case DTM_PROCLAYOUT:
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *)(G( o ) -> SpecialInfo);
- struct GadgetInfo *gi = (((struct gpLayout *)msg) -> gpl_GInfo);
-
- eid = (struct EmbedInstData *)INST_DATA( cl, o );
-
- /* Set the layout flag.
- * This avoids rendering and other unwanted actions during the layout process.
- * (the flag will be cleared in layoutMethod function).
- */
- si -> si_Flags |= DTSIF_LAYOUT;
-
- ObtainSemaphore( (&(si -> si_Lock)) );
-
- /* Avoids that an embedded object like animation.datatype subclass would render during async layout */
- DestroyVisibleList( cb, o, eid );
-
- ReleaseSemaphore( (&(si -> si_Lock)) );
-
- /* Tell everyone that we are busy doing things */
- notifyAttrChanges( o, gi, 0UL,
- GA_ID, G( o ) -> GadgetID,
- DTA_Busy, TRUE,
- TAG_DONE );
-
- /* Let the super-class partake */
- retval = DoSuperMethodA( cl, o, msg );
-
- /* set layout flag again because text.datatype cleared it :-( */
- si -> si_Flags |= DTSIF_LAYOUT;
-
- /* Layout the text */
- retval += layoutMethod( cb, cl, o, (struct gpLayout *)msg );
- }
- break;
-
- case DTM_REMOVEDTOBJECT:
- {
- /* Get a pointer to our object data */
- eid = (struct EmbedInstData *)INST_DATA( cl, o );
-
- if( linelist = eid -> eid_LineList )
- {
- struct EmbedLine *worknode,
- *nextnode;
-
- /* Send msg to all gadgets */
- worknode = (struct EmbedLine *)(linelist -> mlh_Head);
-
- while( nextnode = (struct EmbedLine *)(worknode -> el_Line . ln_Link . mln_Succ) )
- {
- if( worknode -> el_Object )
- {
- (void)DoMethodA( (worknode -> el_Object), msg );
-
- (EXTG( (worknode -> el_Object) ) -> GadgetType) &= ~GTYP_REQGADGET;
-
- FreeBitMap( (worknode -> el_ObjectBitMap) );
- worknode -> el_ObjectBitMap = NULL;
- }
-
- worknode = nextnode;
- }
- }
-
- /* Let the superclass partake */
- retval = DoSuperMethodA( cl, o, msg );
- }
- break;
-
- case DTM_TRIGGER:
- {
- /* Get a pointer to our object data */
- eid = (struct EmbedInstData *)INST_DATA( cl, o );
-
- if( linelist = eid -> eid_LineList )
- {
- struct EmbedLine *worknode,
- *nextnode;
-
- /* Send msg to all gadgets */
- worknode = (struct EmbedLine *)(linelist -> mlh_Head);
-
- while( nextnode = (struct EmbedLine *)(worknode -> el_Line . ln_Link . mln_Succ) )
- {
- if( worknode -> el_Object )
- {
- retval += DoMethodA( (worknode -> el_Object), msg );
- }
-
- worknode = nextnode;
- }
- }
- }
- break;
-
- case OM_DISPOSE:
- {
- /* Get a pointer to our object data */
- eid = (struct EmbedInstData *)INST_DATA( cl, o );
-
- if( linelist = eid -> eid_LineList )
- {
- struct EmbedLine *worknode,
- *nextnode;
-
- worknode = (struct EmbedLine *)(linelist -> mlh_Head);
-
- while( nextnode = (struct EmbedLine *)(worknode -> el_Line . ln_Link . mln_Succ) )
- {
- if( worknode -> el_Object )
- {
- /* pass dispose msg to member/model */
- if( worknode -> el_IsDTObject )
- {
- DisposeDTObject( (worknode -> el_Object) );
- }
- else
- {
- DisposeObject( (worknode -> el_Object) );
- }
-
- DisposeObject( (worknode -> el_Model) );
- }
-
- worknode = nextnode;
- }
-
- /* Don't let the super class free the line list */
- NewList( (struct List *)linelist );
- }
-
- /* Delete the line pool */
- DeletePool( (eid -> eid_Pool) );
- }
- /* Let the superclass handle everything else */
- default:
- {
- retval = DoSuperMethodA( cl, o, msg );
- }
- break;
- }
-
- return( retval );
- }
-
- #define ECMD_REMARK (1UL)
- #define ECMD_DATATYPE (2UL)
- #define ECMD_CALENDAR (3UL)
- #define ECMD_PROPGADGET (4UL)
- #define ECMD_TRIGGER (5UL)
- #define ECMD_LINK (6UL)
-
- struct EmbedCommand
- {
- ULONG ec_ID;
- STRPTR ec_Command;
- };
-
- struct EmbedCommand embedcommands[] =
- {
- { ECMD_REMARK, "remark" },
- { ECMD_REMARK, "rem" },
- { ECMD_DATATYPE, "datatype" },
- { ECMD_CALENDAR, "calendar" },
- { ECMD_PROPGADGET, "propgadget" },
- { ECMD_TRIGGER, "trigger" },
- { ECMD_LINK, "link" },
- { 0UL, NULL }
- };
-
-
- ULONG parseMethod( struct ClassBase *cb, struct IClass *cl, Object *o )
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *)(G( o ) -> SpecialInfo);
- struct EmbedInstData *eid = (struct EmbedInstData *)INST_DATA( cl, o );
- ULONG totalh = 0UL,
- totalw = 0UL;
- struct RastPort trp = { 0 };
- ULONG hunit = 1UL;
-
- /* Switches */
- BOOL linefeed = FALSE;
- BOOL newseg = FALSE;
-
- /* Attributes obtained from super-class */
- struct TextFont *font;
- struct MinList *linelist;
- ULONG bufferlen = 0UL;
- STRPTR buffer = NULL;
-
- /* Line information */
- ULONG num,
- offset,
- swidth = 0UL,
- lineheight = 0UL;
- ULONG anchor = 0UL,
- newanchor = 0UL;
- ULONG style = FS_NORMAL;
- struct EmbedLine *line;
- ULONG yoffset = 0UL;
- UBYTE fgpen = 1UL; /* should be: (msg -> gpl_GInfo -> gi_DrInfo -> dri_Pens[ TEXTPEN ]); */
- UBYTE bgpen = 0UL; /* should be: (msg -> gpl_GInfo -> gi_DrInfo -> dri_Pens[ BACKGROUNDPEN ]); */
- ULONG i;
-
- BOOL command = FALSE;
-
- D( kprintf( "in parsing\n" ) );
-
- /* Get all the attributes that we are going to need for a successful layout */
- if( GetDTAttrs( o,
- DTA_TextFont, (&font),
- TDTA_Buffer, (&buffer),
- TDTA_BufferLen, (&bufferlen),
- TDTA_LineList, (&linelist),
- TAG_DONE ) == 4UL )
- {
- eid -> eid_LineList = linelist;
-
- /* Make sure we have a buffer */
- if( buffer )
- {
- /* Initialize the temporary RastPort (for layout calculations) */
- InitRastPort( (&trp) );
- SetFont( (&trp), font );
-
- /* Step through the text buffer */
- for( i = offset = num = 0UL ; (i <= bufferlen) ; i++ )
- {
- if( buffer[ i ] == '@' )
- {
- /* a directive must start at the begin of the line... */
- if( buffer[ i - 1 ] = '\n' )
- {
- command = TRUE;
- }
- }
-
- /* Check for end of line */
- if( buffer[ i ] == '\n' || (i == bufferlen) )
- {
- newseg = linefeed = TRUE;
- newanchor = i + 1;
- }
- /* Check for end of page */
- else if( buffer[ i ] == 12 )
- {
- newseg = linefeed = TRUE;
- newanchor = i + 1;
- }
- else
- {
- /* Compute the width of the line. */
- swidth = TextLength( &trp, &buffer[ anchor ], num + 1 );
-
- num++;
- }
-
- /* Time for a new text segment yet? */
- if( newseg )
- {
- /* Allocate a new line segment from our memory pool */
- if( line = (struct EmbedLine *)AllocPooled( (eid -> eid_Pool), sizeof( struct EmbedLine ) ) )
- {
- Object *image,
- *model;
- ULONG height;
-
- /* Does the line contain a command ? */
- if( command )
- {
- STRPTR cmd = &buffer[ anchor + 1 ],
- args = NULL;
- ULONG id = 0UL;
- ULONG ci = 0UL; /* command interator */
-
- command = FALSE;
- linefeed = FALSE;
-
- /* Which command ? */
- while( embedcommands[ ci ] . ec_Command )
- {
- ULONG len = (ULONG)strlen( (embedcommands[ ci ] . ec_Command) );
-
- if( !Strnicmp( cmd, (embedcommands[ ci ] . ec_Command), len ) )
- {
- args = cmd + len + 1;
- id = embedcommands[ ci ] . ec_ID;
-
- break;
- }
-
- ci++;
- }
-
- /* Extract arguments */
- if( args )
- {
- STRPTR s;
-
- if( s = (STRPTR)AllocVec( num, (MEMF_PUBLIC | MEMF_CLEAR) ) )
- {
- stccpy( s, args, (int)(num - (ULONG)(args - cmd)) );
- }
-
- args = s;
-
- D( kprintf( "args '%s'\n", args ) );
- }
-
- switch( id )
- {
- case ECMD_REMARK:
- {
- D( kprintf( "remark: %s", args ) );
- }
- break;
-
- case ECMD_DATATYPE:
- {
- if( image = NewDTObject( args, GA_GadgetHelp, TRUE, TAG_DONE ) )
- {
- line -> el_Object = image;
- line -> el_IsDTObject = TRUE;
- line -> el_ObjectCanClip = TRUE;
-
- if( model = NewObject( (cb -> cb_EmbedModel), NULL, EMBEDA_SyncObjectLine, line,
- ICA_TARGET, o,
- TAG_DONE ) )
- {
- line -> el_Model = model;
-
- /* Set model as target */
- SetDTAttrs( image, NULL, NULL, ICA_TARGET, model, TAG_DONE );
-
- D( kprintf( "dto %lx\n", image ) );
- }
- else
- {
- D( kprintf( "no model\n" ) );
- DisposeDTObject( image );
- }
- }
- else
- {
- D( kprintf( "------- dt error %ld\n", IoErr() ) );
- }
- }
- break;
-
- case ECMD_CALENDAR:
- {
- if( image = NewObject( NULL, "calendar.gadget", GA_GadgetHelp, TRUE, TAG_DONE ) )
- {
- line -> el_Object = image;
- line -> el_IsDTObject = FALSE;
- line -> el_ObjectCanClip = FALSE;
- line -> el_ObjectIsClipped = TRUE;
-
- if( model = NewObject( (cb -> cb_EmbedModel), NULL, EMBEDA_SyncObjectLine, line,
- ICA_TARGET, o,
- TAG_DONE ) )
- {
- /* Set model as target */
- SetDTAttrs( image, NULL, NULL, ICA_TARGET, model, TAG_DONE );
-
- D( kprintf( "calendar %lx\n", image ) );
-
- line -> el_Model = model;
- }
- else
- {
- D( kprintf( "no model\n" ) );
- DisposeDTObject( image );
- }
- }
- else
- {
- D( kprintf( "------- calendar error %ld\n", IoErr() ) );
- }
- }
- break;
-
- case ECMD_PROPGADGET:
- {
- if( image = NewObject( NULL, PROPGCLASS,
- PGA_Borderless, FALSE,
- PGA_NewLook, TRUE,
- PGA_Total, 100UL,
- PGA_Visible, 10UL,
- PGA_Top, 20UL,
- PGA_Freedom, FREEVERT,
- GA_GadgetHelp, TRUE,
- TAG_DONE ) )
- {
- line -> el_Object = image;
- line -> el_IsDTObject = FALSE;
- line -> el_ObjectCanClip = FALSE;
- line -> el_ObjectIsClipped = TRUE;
-
- if( model = NewObject( (cb -> cb_EmbedModel), NULL, EMBEDA_SyncObjectLine, line,
- ICA_TARGET, o,
- TAG_DONE ) )
- {
- /* Set model as target */
- SetDTAttrs( image, NULL, NULL, ICA_TARGET, model, TAG_DONE );
-
- D( kprintf( "prop %lx\n", image ) );
-
- line -> el_Model = model;
- }
- else
- {
- D( kprintf( "no model\n" ) );
- DisposeDTObject( image );
- }
- }
- else
- {
- D( kprintf( "------- prop error %ld\n", IoErr() ) );
- }
- }
- break;
-
- default:
- {
- D( kprintf( "unknown command %lu\n", id ) );
- }
- break;
- }
-
- if( args )
- {
- FreeVec( args );
- }
- }
-
- if( line -> el_Object )
- {
- if( line -> el_IsDTObject )
- {
- GetDTAttrs( (line -> el_Object), DTA_NominalVert, (&height),
- DTA_NominalHoriz, (&swidth),
- TAG_DONE );
- }
- else
- {
- struct gpDomain gpd = { 0 }; /* Clear all fields */
- ULONG success;
-
- /* Get the domain of the object */
- gpd . MethodID = GM_DOMAIN;
- gpd . gpd_Which = GDOMAIN_NOMINAL;
-
- if( (success = DoMethodA( o, (Msg)(&gpd) )) == 0UL )
- {
- kprintf( "can't get nominal box, I try now the minimum box\n" );
-
- gpd . gpd_Which = GDOMAIN_MINIMUM;
-
- success = DoMethodA( o, (Msg)(&gpd) );
- }
-
- if( success )
- {
- swidth = gpd . gpd_Domain . Width;
- height = gpd . gpd_Domain . Height;
- }
- else
- {
- /* Oh no ! - Use fixed width/height to fix the size problem
- * (e.g. fixed to topaz 8, but scale if a larger font is used):
- */
- swidth = (320UL * (font -> tf_XSize)) / 8UL;
- height = (200UL * (font -> tf_YSize)) / 8UL;
- }
- }
-
- /* Valid width/height ? */
- if( (height == 0UL) || (swidth == 0UL) )
- {
- LONG totvert = 0L,
- tothoriz = 0L,
- vertunit = 0L,
- horizunit = 0L;
-
- /* Calculate width/height manually... */
- GetDTAttrs( (line -> el_Object), DTA_TotalVert, (&totvert),
- DTA_TotalHoriz, (&tothoriz),
- DTA_VertUnit, (&vertunit),
- DTA_HorizUnit, (&horizunit),
- TAG_DONE );
-
- swidth = totvert * MAX( vertunit, 1L );
- height = tothoriz * MAX( horizunit, 1L );
-
- /* Valid width/height (2nd attempt) ? */
- if( (height == 0UL) || (swidth == 0UL) )
- {
- /* Oh no ! - Use fixed width/height to fix the size problem
- * (e.g. fixed to topaz 8, but scale if a larger font is used):
- */
- swidth = (320UL * (font -> tf_XSize)) / 8UL;
- height = (200UL * (font -> tf_YSize)) / 8UL;
- }
- }
- }
- else
- {
- swidth = TextLength( &trp, &buffer[ anchor ], num );
- height = font -> tf_YSize;
- }
-
- line -> el_Line . ln_Text = &buffer[ anchor ];
- line -> el_Line . ln_TextLen = num;
- line -> el_Line . ln_XOffset = offset;
- line -> el_Line . ln_YOffset = yoffset + (font -> tf_Baseline);
- line -> el_Line . ln_Width = swidth;
- line -> el_Line . ln_Height = height;
- line -> el_Line . ln_Flags = (linefeed)?(LNF_LF):(0UL);
- line -> el_Line . ln_FgPen = fgpen;
- line -> el_Line . ln_BgPen = bgpen;
- line -> el_Line . ln_Style = style;
- line -> el_Line . ln_Data = NULL;
-
- /* Fill in line box */
- line -> el_LineBox . Left = line -> el_Line . ln_XOffset;
- line -> el_LineBox . Top = line -> el_Line . ln_YOffset - (font -> tf_Baseline);
- line -> el_LineBox . Width = line -> el_Line . ln_Width;
- line -> el_LineBox . Height = line -> el_Line . ln_Height;
-
- D( kprintf( "new line box %lx %ld %ld %ld %ld\n", line, (line -> el_LineBox . Left),
- (line -> el_LineBox . Top),
- (line -> el_LineBox . Width),
- (line -> el_LineBox . Height) ) );
-
- /* Add the line to the list */
- AddTail( (struct List *)linelist, (struct Node *)(&(line -> el_Line . ln_Link)) );
-
- /* Increment the offset */
- offset += swidth;
-
- /* Bump line height */
- lineheight = MAX( height, lineheight );
-
- /* Increment the line count */
- if( linefeed )
- {
- yoffset += lineheight;
- totalw = MAX( totalw, offset );
- totalh += (lineheight + (font -> tf_YSize) - 1) / (font -> tf_YSize); /* pix_height / pix_per_unit, rounded */
-
- offset = 0UL;
- lineheight = 0UL;
- }
- }
-
- /* Clear the variables */
- newseg = linefeed = FALSE;
- anchor = newanchor;
- num = 0UL;
- }
- }
- }
- else
- {
- D( kprintf( "no buffer\n" ) );
- }
-
- SetDTAttrs( o, NULL, NULL, DTA_NominalVert, (totalh * (font -> tf_YSize)),
- DTA_NominalHoriz, (hunit * totalw),
- TAG_DONE );
-
-
- /* Compute the lines and columns type information */
- si -> si_VertUnit = font -> tf_YSize;
- si -> si_VisVert = 0L;
- si -> si_TotVert = totalh;
-
- si -> si_HorizUnit = hunit;
- si -> si_VisHoriz = 0L;
- si -> si_TotHoriz = totalw;
- }
- else
- {
- D( kprintf( "no args\n" ) );
- }
-
- return( totalh );
- }
-
-
- ULONG layoutMethod( struct ClassBase *cb, struct IClass *cl, Object *o, struct gpLayout *gpl )
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *)(G( o ) -> SpecialInfo);
- struct EmbedInstData *eid = (struct EmbedInstData *)INST_DATA( cl, o );
- ULONG visible,
- totalh = 0UL,
- totalw;
- ULONG hunit = si -> si_HorizUnit,
- vunit = si -> si_VertUnit;
- STRPTR title;
- BOOL busy = FALSE;
-
- /* Attributes obtained from super-class */
- struct MinList *linelist = eid -> eid_LineList;
- struct IBox *domain;
-
- /* Get all the attributes that we are going to need for a successful layout */
- if( GetDTAttrs( o,
- DTA_Domain, (&domain),
- DTA_ObjName, (&title),
- TAG_DONE) == 2UL )
- {
- struct gpLayout member_gpl;
- struct EmbedLine *worknode,
- *nextnode;
-
- /* Lock the global object data so that nobody else can manipulate it */
- ObtainSemaphore( (&(si -> si_Lock)) );
-
- DestroyVisibleList( cb, o, eid );
-
- /* No layout to perform */
- totalh = si -> si_TotVert;
- totalw = si -> si_TotHoriz;
-
- /* Compute the lines and columns type information */
- si -> si_VertUnit = vunit;
- si -> si_VisVert = visible = domain -> Height / vunit;
- si -> si_TotVert = totalh;
-
- si -> si_HorizUnit = hunit;
- si -> si_VisHoriz = (LONG) domain -> Width / hunit;
- si -> si_TotHoriz = totalw;
-
- /* Bump members */
- CreateVisibleList( cb, o, eid, domain, (gpl -> gpl_GInfo) );
-
- /* Layout members */
- member_gpl = *gpl;
- member_gpl . MethodID = GM_LAYOUT;
-
- worknode = (struct EmbedLine *)(linelist -> mlh_Head);
-
- while( nextnode = (struct EmbedLine *)(worknode -> el_Line . ln_Link . mln_Succ) )
- {
- if( worknode -> el_Object )
- {
- /* If this is the initial layout, we've to tell te member something abouts it's parent wid/req */
- if( gpl -> gpl_Initial )
- {
- if( (EXTG( o ) -> GadgetType) & GTYP_REQGADGET )
- {
- (EXTG( (worknode -> el_Object) ) -> GadgetType) |= GTYP_REQGADGET;
- }
- }
-
- /* pass msg to active member... */
- if( (worknode -> el_ObjectCanClip) || ((worknode -> el_ObjectIsClipped) == FALSE) )
- {
- (void)DoMethodA( (worknode -> el_Object), (Msg)(&member_gpl) );
- }
- else
- {
- struct GadgetInfo *buffer_gi;
-
- if( buffer_gi = CreateGadgetInfoClipBuffer( cb, (gpl -> gpl_GInfo), worknode ) )
- {
- member_gpl . gpl_GInfo = buffer_gi;
-
- (void)DoMethodA( (worknode -> el_Object), (Msg)(&member_gpl) );
-
- member_gpl . gpl_GInfo = (gpl -> gpl_GInfo);
-
- /* no rendering during GM_LAYOUT allowed ! */
- #ifdef COMMENTED_OUT
- SyncGadgetInfoClipBuffer( cb, (gpl -> gpl_GInfo), buffer_gi, worknode );
- #endif
-
- FreeGadgetInfoClipBuffer( cb, buffer_gi );
- }
- }
- }
-
- worknode = nextnode;
- }
-
- /* Release the global data lock */
- ReleaseSemaphore( (&(si -> si_Lock)) );
-
- /* Any member busy ? */
- worknode = (struct EmbedLine *)(linelist -> mlh_Head);
-
- while( nextnode = (struct EmbedLine *)(worknode -> el_Line . ln_Link . mln_Succ) )
- {
- if( worknode -> el_Model )
- {
- if( busy = IsModelBusy( cb, (worknode -> el_Model) ) )
- {
- break;
- }
- }
-
- worknode = nextnode;
- }
-
- /* Store parent's (window/req) domain box */
- eid -> eid_OldParentDomain = gpl -> gpl_GInfo -> gi_Domain;
-
- /* Clear the layout flag */
- si -> si_Flags &= ~DTSIF_LAYOUT;
-
- /* Not aborted, so tell the world of our newest attributes */
- notifyAttrChanges( o, (gpl -> gpl_GInfo), 0UL,
- GA_ID, G( o ) -> GadgetID,
-
- DTA_VisibleVert, visible,
- DTA_TotalVert, totalh,
- DTA_VertUnit, vunit,
-
- DTA_VisibleHoriz, (ULONG)(domain -> Width / hunit),
- DTA_TotalHoriz, totalw,
- DTA_HorizUnit, hunit,
-
- DTA_Title, title,
- DTA_Busy, busy,
- DTA_Sync, TRUE,
- TAG_DONE );
- }
- else
- {
- /* Clear the layout flag */
- si -> si_Flags &= ~DTSIF_LAYOUT;
-
- D( kprintf( "no args\n" ) );
- }
-
- return( totalh );
- }
-
-
- /* Notify attribute changes (OM_NOTIFY) */
- ULONG notifyAttrChanges( Object *o, struct GadgetInfo *ginfo, ULONG flags, Tag tag1, ... )
- {
- struct opUpdate opu;
-
- opu . MethodID = OM_NOTIFY;
- opu . opu_AttrList = (struct TagItem *)(&tag1);
- opu . opu_GInfo = ginfo;
- opu . opu_Flags = flags;
-
- return( DoMethodA( o, (Msg)(&opu) ) );
- }
-
-
- /* Destroy list of visible members and their domain boxes */
- void DestroyVisibleList( struct ClassBase *cb, Object *o, struct EmbedInstData *eid )
- {
- struct MinNode *worknode,
- *nextnode;
-
- worknode = eid -> eid_VisibleMembers . mlh_Head;
-
- while( nextnode = worknode -> mln_Succ )
- {
- struct EmbedLine *work = VisibleLink2EmbedLine( worknode );
-
- if( work -> el_Object )
- {
- struct IBox *domain = NULL;
-
- if( GetDTAttrs( (work -> el_Object), DTA_Domain, (&domain), TAG_DONE ) == 1UL )
- {
- if( domain )
- {
- /* destroy domain box that the member can draw anything during layout */
- domain -> Left = domain -> Top = SHRT_MAX;
- domain -> Width = domain -> Height = 0;
- }
- }
- }
-
- worknode = nextnode;
- }
-
- NewList( (struct List *)(&(eid -> eid_VisibleMembers)) );
- }
-
-
- /* Create list of currently visible members (gadgets) */
- void CreateVisibleList( struct ClassBase *cb, Object *o, struct EmbedInstData *eid, struct IBox *domain, struct GadgetInfo *gi )
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *)(G( o ) -> SpecialInfo);
- struct EmbedLine *worknode,
- *nextnode;
- ULONG offset_horiz = (si -> si_TopHoriz) * MAX( (si -> si_HorizUnit), 1L );
- ULONG offset_vert = (si -> si_TopVert) * MAX( (si -> si_VertUnit), 1L );
-
- /* Bump visiblebox of lines */
- worknode = (struct EmbedLine *)(eid -> eid_LineList -> mlh_Head);
-
- while( nextnode = (struct EmbedLine *)(worknode -> el_Line . ln_Link . mln_Succ) )
- {
- BOOL visible = TRUE;
- LONG topvert = 0L,
- tophoriz = 0L,
- totvert = 0L,
- tothoriz = 0L,
- vertunit = 0L,
- horizunit = 0L,
- vertpix,
- horizpix;
-
- if( (worknode -> el_Object) && (worknode -> el_IsDTObject) )
- {
- GetDTAttrs( (worknode -> el_Object), DTA_TopVert, (&topvert),
- DTA_TopHoriz, (&tophoriz),
- DTA_TotalVert, (&totvert),
- DTA_TotalHoriz, (&tothoriz),
- DTA_VertUnit, (&vertunit),
- DTA_HorizUnit, (&horizunit),
- TAG_DONE );
-
- #if 0
- vertpix = topvert * MAX( vertunit, 1L );
- horizpix = tophoriz * MAX( horizunit, 1L );
- #endif
- }
- else
- {
- vertunit = si -> si_VertUnit;
- horizunit = si -> si_HorizUnit;
- totvert = si -> si_TotVert;
- tothoriz = si -> si_TotHoriz;
- }
-
- worknode -> el_VisibleBox . Left = (worknode -> el_LineBox . Left) - offset_horiz + (domain -> Left);
- worknode -> el_VisibleBox . Top = (worknode -> el_LineBox . Top) - offset_vert + (domain -> Top);
- worknode -> el_VisibleBox . Width = worknode -> el_LineBox . Width;
- worknode -> el_VisibleBox . Height = worknode -> el_LineBox . Height;
-
- if( (worknode -> el_VisibleBox . Left) < (domain -> Left) )
- {
- horizpix = ((domain -> Left) - (worknode -> el_VisibleBox . Left)) * horizunit;
- worknode -> el_VisibleBox . Width -= (domain -> Left) - (worknode -> el_VisibleBox . Left);
- worknode -> el_VisibleBox . Left = domain -> Left;
- }
- else
- {
- horizpix = 0UL;
- }
-
- if( (worknode -> el_VisibleBox . Top) < (domain -> Top) )
- {
- vertpix = ((domain -> Top) - (worknode -> el_VisibleBox . Top)) * vertunit;
- worknode -> el_VisibleBox . Height -= (domain -> Top) - (worknode -> el_VisibleBox . Top);
- worknode -> el_VisibleBox . Top = domain -> Top;
- }
- else
- {
- vertpix = 0UL;
- }
-
- if( ((worknode -> el_VisibleBox . Left) >= ((domain -> Left) + (domain -> Width)) ) ||
- ((worknode -> el_VisibleBox . Top) >= ((domain -> Top) + (domain -> Height)) ) ||
- ((worknode -> el_VisibleBox . Left) < (domain -> Left) ) ||
- ((worknode -> el_VisibleBox . Top) < (domain -> Top) ) )
- {
- visible = FALSE;
- }
-
- if( ((worknode -> el_VisibleBox . Left) + (worknode -> el_VisibleBox . Width)) > ((domain -> Left) + (domain -> Width)) )
- {
- worknode -> el_VisibleBox . Width -= ((worknode -> el_VisibleBox . Left) + (worknode -> el_VisibleBox . Width)) - ((domain -> Left) + (domain -> Width));
- }
-
- if( ((worknode -> el_VisibleBox . Top) + (worknode -> el_VisibleBox . Height)) > ((domain -> Top) + (domain -> Height)) )
- {
- worknode -> el_VisibleBox . Height -= ((worknode -> el_VisibleBox . Top) + (worknode -> el_VisibleBox . Height)) - ((domain -> Top) + (domain -> Height));
- }
-
- /* Is visible, 2nd */
- if( ((worknode -> el_VisibleBox . Left) >= ((domain -> Left) + (domain -> Width)) ) ||
- ((worknode -> el_VisibleBox . Top) >= ((domain -> Top) + (domain -> Height)) ) ||
- ((worknode -> el_VisibleBox . Left) < (domain -> Left) ) ||
- ((worknode -> el_VisibleBox . Top) < (domain -> Top) ) )
- {
- visible = FALSE;
- }
-
- /* Is visible, 3rd */
- if( ((worknode -> el_VisibleBox . Left) < 0) || ((worknode -> el_VisibleBox . Top) < 0) ||
- ((worknode -> el_VisibleBox . Width) < 0) || ((worknode -> el_VisibleBox . Height) < 0) )
- {
- visible = FALSE;
- }
-
- if( visible )
- {
- #ifdef DRAW_BOX_AROUND_OBJECT
- if( worknode -> el_Object )
- {
- /* Reduce gadget box that the 0-color box fits around the object.
- * BUG: This causes problems because the domain box is now smaller than the wanted
- * optimum size.
- */
- worknode -> el_VisibleBox . Left += 1;
- worknode -> el_VisibleBox . Top += 1;
- worknode -> el_VisibleBox . Width -= 2;
- worknode -> el_VisibleBox . Height -= 2;
- }
- #endif /* DRAW_BOX_AROUND_OBJECT */
-
- AddTail( (struct List *)(&(eid -> eid_VisibleMembers)), (struct Node *)(&(worknode -> el_VisibleLink)) );
- }
- else
- {
- /* member has no box, move it out of the visible area... */
- worknode -> el_VisibleBox . Left = worknode -> el_VisibleBox . Top = SHRT_MAX;
- worknode -> el_VisibleBox . Width = worknode -> el_VisibleBox . Height = 0;
- }
-
- /* Recalculate current topvert/tophoriz */
- topvert = vertpix / MAX( vertunit, 1L );
- tophoriz = horizpix / MAX( horizunit, 1L );
-
- /* Check limits */
- topvert = MIN( topvert, totvert );
- tophoriz = MIN( tophoriz, tothoriz );
-
- /* Store... */
- worknode -> el_TopVert = topvert;
- worknode -> el_TopHoriz = tophoriz;
-
- if( worknode -> el_Object )
- {
- ULONG width = worknode -> el_VisibleBox . Width,
- height = worknode -> el_VisibleBox . Height;
-
- /* Restore flags (V40 bug workaround) */
- G( (worknode -> el_Object) ) -> Flags |= GFLG_RELSPECIAL;
-
- FreeBitMap( (worknode -> el_ObjectBitMap) );
- worknode -> el_ObjectBitMap = NULL;
-
- /* If the object can' clip, we don't reduce it's gadget box size here. Instead, the object
- * renders into a hidden bitmap which is copied into the visible area on demand
- */
- if( (worknode -> el_ObjectCanClip) == FALSE )
- {
- #ifdef DRAW_BOX_AROUND_OBJECT
- if( ((width + 2) < (worknode -> el_LineBox . Width)) ||
- ((height + 2) < (worknode -> el_LineBox . Height)) )
- #else
- if( (width < (worknode -> el_LineBox . Width)) ||
- (height < (worknode -> el_LineBox . Height)) )
- #endif /* DRAW_BOX_AROUND_OBJECT */
- {
- worknode -> el_ObjectIsClipped = TRUE;
-
- worknode -> el_ObjectBitMap = AllocBitMap( ((worknode -> el_LineBox . Width) + 16UL),
- ((worknode -> el_LineBox . Height) + 16UL),
- (ULONG)(gi -> gi_RastPort -> BitMap -> Depth),
- (BMF_CLEAR | BMF_MINPLANES), (gi -> gi_RastPort -> BitMap) );
-
- kprintf( "object is clipped tv %lu th %lu\n", (worknode -> el_TopVert), (worknode -> el_TopHoriz) );
- }
- else
- {
- worknode -> el_ObjectIsClipped = FALSE;
-
- kprintf( "object is not clipped\n" );
- }
-
- width = worknode -> el_LineBox . Width;
- height = worknode -> el_LineBox . Height;
- }
-
- if( worknode -> el_ObjectIsClipped )
- {
- /* Set new box (no gadgetinfo, the refresh/redraw is done later) */
- SetAttrs( (worknode -> el_Object), GA_Left, 0UL,
- GA_Top, 0UL,
- GA_Width, width,
- GA_Height, height,
- DTA_TopVert, (worknode -> el_TopVert),
- DTA_TopHoriz, (worknode -> el_TopHoriz),
- TAG_DONE );
- }
- else
- {
- /* Set new box (no gadgetinfo, the refresh/redraw is done later) */
- SetAttrs( (worknode -> el_Object), GA_Left, (worknode -> el_VisibleBox . Left),
- GA_Top, (worknode -> el_VisibleBox . Top),
- GA_Width, width,
- GA_Height, height,
- DTA_TopVert, (worknode -> el_TopVert),
- DTA_TopHoriz, (worknode -> el_TopHoriz),
- TAG_DONE );
- }
- }
-
- worknode = nextnode;
- }
- }
-
-
- DISPATCHERFLAGS
- ULONG DispatchModel( REGA0 struct IClass *cl, REGA2 Object *o, REGA1 Msg msg )
- {
- struct ClassBase *cb = (struct ClassBase *)(cl -> cl_UserData);
- struct EmbedModelInstData *emid;
- ULONG retval = 0UL;
-
- switch( msg -> MethodID )
- {
- case OM_NEW:
- {
- struct EmbedLine *el;
- Object *dt;
-
- if( el = (struct EmbedLine *)GetTagData( EMBEDA_SyncObjectLine, 0UL, (((struct opSet *)msg) -> ops_AttrList) ) )
- {
- dt = el -> el_Object;
-
- if( retval = DoSuperMethodA( cl, o, msg ) )
- {
- /* Get a pointer to the object data */
- emid = (struct EmbedModelInstData *)INST_DATA( cl, (Object *)retval );
-
- emid -> emid_ObjectLine = el;
- emid -> emid_Busy = IsKindOf( cb, dt, NULL, DATATYPESCLASS ); /* datatypesclass objects are "busy" at their
- * initial entry in the window and will tell
- * us about any change
- */
- emid -> emid_Sync = FALSE;
- }
- }
- }
- break;
-
- case OM_UPDATE:
- {
- /* Avoid OM_NOTIFY loops */
- if( DoMethod( o, ICM_CHECKLOOP ) )
- {
- break;
- }
- }
- case OM_SET:
- {
- struct TagItem *tstate,
- *ti;
- BOOL sync = FALSE;
-
- /* Get a pointer to the object data */
- emid = (struct EmbedModelInstData *)INST_DATA( cl, o );
-
- tstate = ((struct opSet *)msg) -> ops_AttrList;
-
- while( ti = NextTagItem( (&tstate) ) )
- {
- switch( ti -> ti_Tag )
- {
- case DTA_Sync:
- {
- emid -> emid_Sync = ti -> ti_Data;
- sync = TRUE;
- }
- break;
-
- case DTA_Busy:
- {
- emid -> emid_Busy = ti -> ti_Data;
- sync = TRUE;
- }
- break;
- }
- }
-
- if( sync )
- {
- notifyAttrChanges( o, (((struct opSet *)msg) -> ops_GInfo), 0UL,
- EMBEDA_Sync, (emid -> emid_Sync),
- EMBEDA_SyncObjectLine, (emid -> emid_ObjectLine),
- TAG_DONE );
- }
- }
- break;
-
- /* Let the superclass handle everything else */
- default:
- {
- retval = DoSuperMethodA( cl, o, msg );
- }
- break;
- }
-
- return( retval );
- }
-
-
- BOOL IsModelBusy( struct ClassBase *cb, Object *model )
- {
- if( model )
- {
- /* "hack way": Access model instance data like "white box" */
- struct EmbedModelInstData *emid = (struct EmbedModelInstData *)INST_DATA( (cb -> cb_EmbedModel), model );
-
- return( (emid -> emid_Busy) );
- }
-
- return( FALSE );
- }
-
-
- struct IBox GetRelGadgetBox( struct IBox *domain, struct ExtGadget *g, struct IBox *absbox )
- {
- struct IBox retbox = { 0, 0, 0, 0 };
-
- if( domain && g && absbox )
- {
- retbox = *absbox;
-
- if( (g -> Flags) & GFLG_RELBOTTOM )
- {
- (retbox . Top) -= ((domain -> Top) + (domain -> Height));
- }
-
- if( (g -> Flags) & GFLG_RELRIGHT )
- {
- (retbox . Left) -= ((domain -> Left) + (domain -> Width));
- }
-
- if( (g -> Flags) & GFLG_RELWIDTH )
- {
- (retbox . Width) -= (domain -> Width);
- }
-
- if( (g -> Flags) & GFLG_RELHEIGHT )
- {
- (retbox . Height) -= (domain -> Height);
- }
- }
-
- return( retbox );
- }
-
-
- struct IBox GetAbsGadgetBox( struct IBox *domain, struct ExtGadget *g, BOOL useBounds )
- {
- struct IBox retbox = { 0, 0, 0, 0 };
-
- if( domain && g )
- {
- if( ((g -> MoreFlags) & GMORE_BOUNDS) && useBounds )
- {
- retbox = *((struct IBox *)(&(g -> BoundsLeftEdge)));
- }
- else
- {
- retbox = *(GADGET_BOX( g ));
- }
-
- if( (g -> Flags) & GFLG_RELBOTTOM )
- {
- (retbox . Top) += ((domain -> Top) + (domain -> Height));
- }
-
- if( (g -> Flags) & GFLG_RELRIGHT )
- {
- (retbox . Left) += ((domain -> Left) + (domain -> Width));
- }
-
- if( (g -> Flags) & GFLG_RELWIDTH )
- {
- (retbox . Width) += (domain -> Width);
- }
-
- if( (g -> Flags) & GFLG_RELHEIGHT )
- {
- (retbox . Height) += (domain -> Height);
- }
- }
-
- return( retbox );
- }
-
-
- ULONG DoMemberHitTest( struct IBox *domain, Object *member, struct gpHitTest *gpht )
- {
- ULONG retval;
- struct IBox gbox;
- struct GadgetInfo *gi;
-
- retval = 0UL;
- gi = gpht -> gpht_GInfo;
-
- gbox = GetAbsGadgetBox( (&(gi -> gi_Domain)), EXTG( member ), (BOOL)((gpht -> MethodID) == GM_HELPTEST) );
-
- (gpht -> gpht_Mouse . X) -= ((gbox . Left) - (domain -> Left));
- (gpht -> gpht_Mouse . Y) -= ((gbox . Top) - (domain -> Top));
-
- /* Mouse coordinates must be inside members's select box */
- if( ((gpht -> gpht_Mouse . X) >= 0) &&
- ((gpht -> gpht_Mouse . Y) >= 0) &&
- ((gpht -> gpht_Mouse . X) <= (gbox . Width)) &&
- ((gpht -> gpht_Mouse . Y) <= (gbox . Height)) )
- {
- retval = DoMethodA( member, (Msg)gpht );
- }
-
- (gpht -> gpht_Mouse . X) += ((gbox . Left) - (domain -> Left));
- (gpht -> gpht_Mouse . Y) += ((gbox . Top) - (domain -> Top));
-
- return( retval );
- }
-
-
- BOOL BumpMembers( struct IClass *cl, Object *o, struct GadgetInfo *gi )
- {
- if( o && gi )
- {
- struct EmbedInstData *eid = (struct EmbedInstData *)INST_DATA( cl, o );
- struct DTSpecialInfo *si = (struct DTSpecialInfo *)(G( o ) -> SpecialInfo);
-
- /* Be sure that all members (gadgets) are on the right place when redrawing ! */
- if( ((si -> si_TopVert) != (eid -> eid_OldTopVert)) ||
- ((si -> si_TopHoriz) != (eid -> eid_OldTopHoriz)) ||
- ((gi -> gi_Domain) != (eid -> eid_OldParentDomain)) )
- {
- struct gpLayout gpl;
-
- if( (gi -> gi_Domain) != (eid -> eid_OldParentDomain) )
- {
- D( kprintf( "posted layout !?\n" ) );
- }
-
- eid -> eid_OldTopVert = si -> si_TopVert;
- eid -> eid_OldTopHoriz = si -> si_TopHoriz;
- eid -> eid_OldParentDomain = gi -> gi_Domain;
-
- /* Do "size" layout, which moves the members */
- gpl . MethodID = GM_LAYOUT;
- gpl . gpl_GInfo = gi;
- gpl . gpl_Initial = 0L;
-
- DoMethodA( o, (Msg)(&gpl) );
-
- return( TRUE );
- }
- }
-
- return( FALSE );
- }
-
-
- /* Create a copy from the given GadgetInfo with a HIDDEN bitmap.
- * "bounds" is the absoute gadget box in win/req. cooridnates
- */
- static
- struct GadgetInfo *CreateGadgetInfoClipBuffer( struct ClassBase *cb, struct GadgetInfo *gi, struct EmbedLine *el )
- {
- if( cb && gi && el )
- {
- struct GadgetInfo *ggi;
- ULONG size1,
- size;
-
- /* We merge'ed multiple AllocVec's to one below. size#? are the memory block
- * offsets in the allocated buffer, size the the total buffer length
- */
- size1 = sizeof( struct GadgetInfo ) + 8UL;
- size = size1 + sizeof( struct RastPort ) + 8UL;
-
- if( ggi = (struct GadgetInfo *)AllocVec( size, (MEMF_PUBLIC | MEMF_CLEAR) ) )
- {
- #if 0
- struct BitMap *srcbm = gi -> gi_RastPort -> BitMap,
- *bm;
- struct RastPort *rp;
- #endif
-
- struct RastPort *grp = (struct RastPort *)MEMORY_NAL_FOLLOWING( ggi, size1 );
-
- /* Init RastPort */
- InitRastPort( grp );
-
- if( grp -> BitMap = el -> el_ObjectBitMap )
- {
- #if 0
- if( rp = ObtainGIRPort( gi ) )
- {
- /* Copy front buffer into our tmp. bitmap */
- ClipBlit( rp,
- (long)(el -> el_VisibleBox . Left),
- (long)(el -> el_VisibleBox . Top),
- grp,
- (long)(el -> el_TopHoriz),
- (long)(el -> el_TopVert),
- (long)(el -> el_VisibleBox . Width),
- (long)(el -> el_VisibleBox . Height),
- 0xC0 );
-
- WaitBlit();
-
- ReleaseGIRPort( rp );
- }
- else
- {
- kprintf( "CreateGadgetInfoClipBuffer/ObtainGIRPort failed\n" );
- }
- #endif
-
- /* Init GadgetInfo */
- *ggi = *gi;
- ggi -> gi_RastPort = grp;
-
- return( ggi );
- }
-
- FreeVec( ggi );
- }
- else
- {
- kprintf( "CreateGadgetInfoClipBuffer AllocVec\n" );
- }
- }
- else
- {
- kprintf( "CreateGadgetInfoClipBuffer wrong args\n" );
- }
-
- return( NULL );
- }
-
-
- static
- void FreeGadgetInfoClipBuffer( struct ClassBase *cb, struct GadgetInfo *ggi )
- {
- if( cb && ggi )
- {
- FreeVec( ggi );
- }
- }
-
-
- static
- void SyncGadgetInfoClipBuffer( struct ClassBase *cb, struct GadgetInfo *gi, struct GadgetInfo *ggi, struct EmbedLine *el )
- {
- if( cb && gi && ggi && el )
- {
- struct RastPort *rp;
-
- if( rp = ObtainGIRPort( gi ) )
- {
- ClipBlit( (ggi -> gi_RastPort),
- (long)(el -> el_TopHoriz),
- (long)(el -> el_TopVert),
- rp,
- (long)(el -> el_VisibleBox . Left),
- (long)(el -> el_VisibleBox . Top),
- (long)(el -> el_VisibleBox . Width),
- (long)(el -> el_VisibleBox . Height),
- 0xC0 );
-
- WaitBlit();
-
- ReleaseGIRPort( rp );
- }
- else
- {
- kprintf( "SyncGadgetInfoClipBuffer/ObtainGIRPort failed\n" );
- }
- }
- else
- {
- kprintf( "SyncGadgetInfoClipBuffer wrong args\n" );
- }
- }
-
-
- /* offloaded from my objecttools.library */
- static
- BOOL IsKindOf( struct ClassBase *cb, Object *object, struct IClass *searchclass, ClassID searchclassID )
- {
- if( object && (searchclass || searchclassID) )
- {
- struct IClass *workclass,
- *superclass;
-
- workclass = OCLASS( object );
-
- if( searchclass )
- {
- /* Check for touch down at the rootclass,
- * (root of this class tree, ((workclass -> cl_Super) == NULL) ) => QUIT
- */
- while( superclass = workclass -> cl_Super )
- {
- /* Match this class searchclass ? */
- if( searchclass == workclass )
- {
- return( TRUE );
- }
-
- /* workclass = superclass of old workclass */
- workclass = superclass;
- }
- }
- else
- {
- if( searchclassID )
- {
- /* Check for touch down at the rootclass,
- * (root of this class tree, ((workclass -> cl_Super) == NULL) ) => QUIT
- */
- while( superclass = workclass -> cl_Super )
- {
- /* Match this classID searchclassID ? */
- if( !Stricmp( (workclass -> cl_ID), searchclassID ) )
- {
- return( TRUE );
- }
-
- /* workclass = superclass of old workclass */
- workclass = superclass;
- }
- }
- }
- }
- else
- {
- kprintf( "IsKindOf: wrong args %lx %lx %lx \"%s\"\n", object, searchclass, searchclassID, searchclassID );
- }
-
- return( FALSE );
- }
-
-
-
-