home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $PROJECT: binary.datatype
- **
- ** $VER: dispatch.c 39.6 (28.12.94)
- **
- ** by
- **
- ** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
- **
- ** (C) Copyright 1994
- ** All Rights Reserved !
- **
- ** $HISTORY:
- **
- ** 28.12.94 : 039.006 : now it's a base datatype and no async layout is needed
- ** 24.11.94 : 039.005 : memory handling improved, layout only performed if needed
- ** 18.11.94 : 039.004 : added PREFS file
- ** 16.11.94 : 039.003 : BDTDH_NONE now works
- ** 15.11.94 : 039.002 : added BDTA_BytesPerLine,BDTA_DisplayHex and BDTA_ShowASCII attrs
- ** 13.11.94 : 039.001 : initial
- */
-
- /* ------------------------------- include -------------------------------- */
-
- #include "classbase.h"
-
- /* ------------------------------- autodoc -------------------------------- */
-
- /*FS*/ /*"AutoDoc"*/
- /*GB*** binary.datatype/binary.datatype **************************************
- *
- * NAME
- * binary.datatype -- data type for any binary file
- *
- * FUNCTION
- * The binary data type, a base-class of all binary data, is used to
- * load any binary file and displays the contents of the file in hex
- * format.
- *
- * PREFS
- * The data type tries to load the prefs file "ENV:binary.prefs" on
- * each OM_NEW method to set up the attributes !
- * This prefs file has the following format :
- * line = NOASCII | - set BDTA_ShowASCII to FALSE
- * NOWRAP | - set BDTA_DisplayWrap to FALSE
- * NONE | - set BDTA_DisplayHex to BDTDH_NONE
- * BYTE | - set BDTA_DisplayHex to BDTDH_BYTE
- * WORD | - set BDTA_DisplayHex to BDTDH_WORD
- * LONG | - set BDTA_DisplayHex to BDTDH_LONG
- * BYTES <bpl> - set BDTA_BytesPerLine to <bpl> bytes
- *
- * METHODS
- * OM_NEW -- Create a new text object from a binary file in hex mode.
- *
- * OM_DISPOSE -- dispose a object
- *
- * OM_GET -- get a attribute of the object
- *
- * OM_SET -- set attributes of the object
- *
- * OM_UPDATE -- update some attributes of the object
- *
- * GM_LAYOUT -- Method to layout the hex text
- *
- * GM_RENDER -- draw the object
- *
- * DTM_WRITE -- DTWM_RAW mode is supported
- *
- * TAGS
- * BDTA_Buffer -- (UBYTE *) pointer to the buffer, which should be
- * displayed.
- * Applicability is (ISG).
- *
- * BDTA_BufferLen -- (ULONG) length of the buffer supplied with
- * BDTA_Buffer tag. This must be given if the buffer tag is
- * specified.
- * Applicability is (ISG).
- *
- * BDTA_BytesPerLine -- (UWORD) number of bytes per line.
- * If BDTA_DisplayHex is BDTDH_WORD it must be a multiply of 2,
- * if it is BDTDH_LONG it must be a multiply of 4 !
- * Default is 32.
- * Applicability is (ISGNU).
- *
- * BDTA_DisplayHex -- (UWORD) type of the display. The following types
- * are supported : BDTDH_NONE - displays no hex values
- * BDTDH_BYTE - displays each byte in hex ( 8 bit)
- * BDTDH_WORD - displays each word in hex (16 bit)
- * BDTDH_LONG - displays each long in hex (32 bit)
- * Default is BDTDH_LONG.
- * Applicability is (ISGNU).
- *
- * BDTA_ShowASCII -- (BOOL) display at the end of the line the
- * appropriate ASCII string !
- * Default is TRUE.
- * Applicability is (ISGNU).
- *
- * BDTA_DisplayWrap -- (BOOL) the BDTA_BytesPerLine are ignored and the
- * byte number is retrieved from the object width !
- * Default is TRUE.
- * Applicability is (ISGNU).
- *
- * BUGS
- * At the moment proportional fonts can't be handled.
- *
- * SEE ALSO
- * datatypesclass (where ?)
- *
- ******************************************************************************
- *
- */
- /*FE*/
-
- /* ------------------------------- defines -------------------------------- */
-
- #define G(o) ((struct Gadget *) (o))
- #define GPR(msg) ((struct gpRender *) (msg))
- #define SET(msg) ((struct opSet *) (msg))
- #define WRMSG(msg) ((struct dtWrite *) (msg))
-
-
- /* ---------------------------- instance data ----------------------------- */
-
- struct BinaryData
- {
- UBYTE *bd_Buffer;
- ULONG bd_BufferLen;
-
- UWORD bd_Flags;
- UWORD bd_BytesPerLine;
- UWORD bd_DisplayHex;
-
- UWORD bd_NumGroups;
- UWORD bd_LineBytes;
-
- UWORD bd_LineBufferLen;
- UBYTE *bd_LineBuffer;
-
- ULONG bd_OldX;
- ULONG bd_OldY;
-
- /* font support */
- struct TextFont *bd_Font;
- struct TextAttr bd_TextAttr;
- UBYTE bd_FontName[MAXFONTNAME];
-
- UBYTE bd_Name[256];
-
- /* list of gadget objects */
- struct List bd_ObjectList;
- };
-
- #define BDF_SHOWASCII (1<<0)
- #define BDF_ALLOCATED (1<<1)
- #define BDF_DISPLAYWRAP (1<<2)
-
- /* ---------------------------- constant data ----------------------------- */
-
- const ULONG methods[] = {
- OM_NEW,
- OM_DISPOSE,
- OM_GET,
- OM_SET,
- OM_UPDATE,
- GM_LAYOUT,
- GM_RENDER,
- DTM_WRITE,
- ~0};
-
- /* ------------------------------ init class ------------------------------ */
-
- /*FS*/ /*"LibCall Class *initClass(REGA6 struct ClassBase *cb)"*/
- LibCall Class *initClass(REGA6 struct ClassBase *cb)
- {
- Class *cl;
-
- D(bug("init binary.datatype !\n"));
-
- if((cl = MakeClass("binary.datatype","datatypesclass",NULL,sizeof(struct BinaryData),0)))
- {
- cl->cl_Dispatcher.h_Entry = (HOOKFUNC) dispatch;
- cl->cl_UserData = (ULONG) cb;
-
- AddClass(cl);
- }
-
- return(cl);
- }
- /*FE*/
-
- /* -------------------------- support functions --------------------------- */
-
- /*FS*/ ULONG notifyAttrChanges(Object * obj, void * ginfo, ULONG flags, ULONG tag1,...)
- {
- return(DoMethod(obj, OM_NOTIFY, &tag1, ginfo, flags));
- }
- /*FE*/
-
- /*FS*/ ULONG setSuperAttrs(Class *cl,Object * obj, void *ginfo,ULONG tag1,...)
- {
- return(DoSuperMethod(cl,obj, OM_SET, &tag1, ginfo));
- }
- /*FE*/
-
- /*FS*/ void readPrefs(struct ClassBase *cb,struct BinaryData *bd)
- {
- BPTR fh;
-
- ENTERING;
-
- if((fh = Open("ENV:binary.prefs",MODE_OLDFILE)))
- {
- UBYTE buf[100];
- STRPTR ptr;
-
- while((ptr = FGets(fh,buf,sizeof(buf)-1)))
- {
- if(!Strnicmp(ptr,"NOASCII",7))
- bd->bd_Flags &= ~BDF_SHOWASCII;
- else if(!Strnicmp(ptr,"NOWRAP",6))
- bd->bd_Flags &= ~BDF_DISPLAYWRAP;
- else if(!Strnicmp(ptr,"NONE",4))
- bd->bd_DisplayHex = BDTDH_NONE;
- else if(!Strnicmp(ptr,"WORD",4))
- bd->bd_DisplayHex = BDTDH_WORD;
- else if(!Strnicmp(ptr,"LONG",4))
- bd->bd_DisplayHex = BDTDH_LONG;
- else if(!Strnicmp(ptr,"BYTES",5))
- {
- LONG value = 32;
- ptr += 5;
- if(StrToLong(ptr,&value) > 0)
- bd->bd_BytesPerLine = value;
- } else if(!Strnicmp(ptr,"BYTE",4))
- bd->bd_DisplayHex = BDTDH_BYTE;
- }
- Close(fh);
- }
-
- LEAVING;
- }
- /*FE*/
-
- /*FS*/ void useDefaultFont(struct ClassBase *cb,struct BinaryData *bd)
- {
- struct TextFont *deffont;
-
- D(bug("using default font !\n"));
-
- #undef GfxBase
- deffont = ((struct GfxBase *) cb->cb_GfxBase)->DefaultFont;
- #define GfxBase cb->cb_GfxBase
-
- bd->bd_TextAttr.ta_YSize = deffont->tf_YSize;
- bd->bd_TextAttr.ta_Style = FS_NORMAL;
- bd->bd_TextAttr.ta_Flags = deffont->tf_Flags;
- bd->bd_TextAttr.ta_Name = bd->bd_FontName;
- strcpy(bd->bd_TextAttr.ta_Name,deffont->tf_Message.mn_Node.ln_Name);
-
- bd->bd_Font = OpenFont(&bd->bd_TextAttr);
- }
- /*FE*/
-
- /* --------------------------- class dispatcher --------------------------- */
-
- /*FS*/ ClassCall ULONG dispatch(REGA0 Class *cl,REGA2 Object *obj,REGA1 Msg msg)
- {
- struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
- struct BinaryData *bd;
- ULONG retval = 0;
-
- switch(msg->MethodID)
- {
- case OM_NEW:
- {
- Object *newobj;
- if((newobj = (Object *) DoSuperMethodA(cl,obj,msg)))
- {
- bd = INST_DATA(cl,newobj);
-
- /* set default setting */
- bd->bd_BytesPerLine = 32;
- bd->bd_DisplayHex = BDTDH_LONG;
- bd->bd_Flags = BDF_SHOWASCII | BDF_DISPLAYWRAP;
-
- NewList(&bd->bd_ObjectList);
-
- /* read default user settings */
- readPrefs(cb,bd);
-
- setattrs(cl,newobj,(struct opSet *) msg);
-
- /* use default textfont */
- if(!bd->bd_Font)
- useDefaultFont(cb,bd);
-
- /* if no buffer is provided , get the handle from the superclass
- and load the file in the buffer */
- if(!bd->bd_Buffer)
- {
- BPTR fh;
- ULONG type;
- LONG num;
-
- if(((num = GetDTAttrs((Object *) newobj,DTA_Handle ,&fh,
- DTA_SourceType ,&type,
- TAG_DONE)) == 2) && fh)
- {
- struct FileInfoBlock *fib;
-
- D(bug("type : %ld\n",type));
-
- switch(type)
- {
- case DTST_FILE:
- if((fib = AllocDosObject(DOS_FIB,NULL)))
- {
- if(ExamineFH(fh,fib) && fib->fib_Size > 0)
- {
- if((bd->bd_Buffer = AllocMem(fib->fib_Size,MEMF_ANY)))
- {
- bd->bd_Flags |= BDF_ALLOCATED;
- bd->bd_BufferLen = fib->fib_Size;
- Seek(fh,0,OFFSET_BEGINNING);
- Read(fh,bd->bd_Buffer,bd->bd_BufferLen);
- }
- }
- }
- FreeDosObject(DOS_FIB,fib);
- if(!NameFromFH(fh,bd->bd_Name,sizeof(bd->bd_Name)))
- strcpy(bd->bd_Name,"unknown");
- break;
- case DTST_RAM:
- strcpy(bd->bd_Name,"RAM");
- break;
- default:
- D(bug("not supported SourceType : %ld\n",type));
- }
-
- }
- }
-
- if(bd->bd_Buffer)
- {
- retval = (ULONG) newobj;
- ((struct ExtGadget *) newobj)->MoreFlags = GMORE_SCROLLRASTER;
- } else /* something was going wrong, thus dispose myself */
- {
- D(bug("binary.datatype error : %ld\n",IoErr()));
- CoerceMethod(cl,(Object *) retval,OM_DISPOSE);
- }
- }
- }
- break;
- case OM_DISPOSE:
- bd = INST_DATA(cl,obj);
-
- if(bd->bd_Buffer && (bd->bd_Flags & BDF_ALLOCATED))
- FreeMem(bd->bd_Buffer,bd->bd_BufferLen);
-
- if(bd->bd_LineBuffer && bd->bd_LineBufferLen)
- FreeMem(bd->bd_LineBuffer,bd->bd_LineBufferLen);
-
- if(bd->bd_Font)
- CloseFont(bd->bd_Font);
-
- #ifdef EXPERIMENTAL
- /* I don't know , how gadgets can be intergrated in a datatype ?
- * If there is anybody who knows ? Let me know , please !
- */
- {
- APTR gadobj;
- /* dispose all objects from the list c*/
- gadobj = bd->bd_ObjectList.lh_Head;
- while((gadobj = NextObject(&gadobj)))
- {
- DoMethod(gadobj,OM_REMOVE);
- if(G(gadobj)->GadgetRender)
- DoMethod(G(gadobj)->GadgetRender,OM_DISPOSE);
- DoMethod(gadobj,OM_DISPOSE);
- }
- }
- #endif
-
- retval = DoSuperMethodA(cl,obj,msg);
- break;
- case OM_UPDATE:
- case OM_SET:
- if((retval = setattrs(cl,obj,(struct opSet *) msg)))
- DoMethod(obj,GM_LAYOUT,((struct opSet *) msg)->ops_GInfo,TRUE);
-
- /* Pass the attributes to the super class and force a refresh
- * if we need it */
- if((retval += DoSuperMethodA (cl, obj, msg)) && (OCLASS (obj) == cl))
- {
- struct RastPort *rp;
-
- /* Get a pointer to the rastport */
- if((rp = ObtainGIRPort (((struct opSet *) msg)->ops_GInfo)))
- {
- struct gpRender gpr;
-
- /* Force a redraw */
- gpr.MethodID = GM_RENDER;
- gpr.gpr_GInfo = ((struct opSet *) msg)->ops_GInfo;
- gpr.gpr_RPort = rp;
- gpr.gpr_Redraw = GREDRAW_UPDATE;
- DoMethodA (obj, (Msg) &gpr);
-
- /* Release the temporary rastport */
- ReleaseGIRPort (rp);
- }
-
- retval = 0;
- }
- break;
- case OM_GET:
- if(!(retval = getattr(cl,obj,(struct opGet *) msg)))
- retval = DoSuperMethodA(cl,obj,msg);
- break;
- case GM_LAYOUT:
- /* Tell everyone that we are busy doing things */
- notifyAttrChanges (obj, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
- GA_ID, G(obj)->GadgetID,
- DTA_Busy, TRUE,
- TAG_DONE);
-
- /* Let the super-class partake */
- retval = DoSuperMethodA (cl, obj, msg);
-
- retval += layout(cb, cl, obj, (struct gpLayout *) msg);
-
- break;
-
- /* experimental code only for my test version */
- #ifdef EXPERIMENTAL
- case GM_GOACTIVE:
- {
- struct InputEvent *event = ((struct gpInput *) msg)->gpi_IEvent;
-
- if(event->ie_Class == IECLASS_RAWKEY)
- {
- D(bug("goactive->Class %08lx\n",event->ie_Class));
- }
- retval = DoSuperMethodA(cl,obj,msg);
- break;
- }
- case GM_HANDLEINPUT:
- {
- struct InputEvent *event = ((struct gpInput *) msg)->gpi_IEvent;
-
- switch(event->ie_Class)
- {
- case IECLASS_RAWKEY:
- D(bug("handleinput->event->ie_Code : %02lx\n",event->ie_Code));
- break;
- case IECLASS_RAWMOUSE:
- break;
- }
- retval = DoSuperMethodA(cl,obj,msg);
- }
- break;
- #endif
- case GM_RENDER:
- bd = INST_DATA(cl,obj);
-
- #ifdef EXPERIMENTAL
- {
- APTR gadobj;
-
- retval = DoSuperMethodA(cl,obj,msg);
-
- gadobj = bd->bd_ObjectList.lh_Head;
- D(bug("rport : %lx\n",GPR(msg)->gpr_RPort));
- D(bug("ginfo : %lx\n",GPR(msg)->gpr_GInfo));
- D(bug("redraw: %ld\n",GPR(msg)->gpr_Redraw));
- while((gadobj = NextObject(&gadobj)))
- {
- D(bug("rendering gadobj : %lx\n",gadobj));
- DoMethodA(gadobj,msg);
- }
- }
- #endif
-
- {
- struct RastPort *rp = GPR(msg)->gpr_RPort;
- struct DrawInfo *dri = GPR(msg)->gpr_GInfo->gi_DrInfo;
- struct Rectangle rect;
- struct IBox *domain;
- ULONG x,y;
- ULONG ux,uy;
- ULONG py,px,num,grp;
- ULONG topy,topx;
- LONG w,h;
- LONG dx,dy,height;
- LONG chrs;
-
- STRPTR lbuf = bd->bd_LineBuffer;
- STRPTR bptr;
- STRPTR ptr,ptr1;
- STRPTR end;
-
- UBYTE fgpen = (dri) ? dri->dri_Pens[TEXTPEN] : 1;
- UBYTE bgpen = (dri) ? dri->dri_Pens[BACKGROUNDPEN] : 0;
-
- D(bug("draw mode : %lx\n",GPR(msg)->gpr_Redraw));
-
- if(GetDTAttrs(obj,DTA_TopVert ,&y,
- DTA_TopHoriz ,&x,
- DTA_VisibleVert ,&h,
- DTA_VisibleHoriz,&w,
- DTA_VertUnit ,&uy,
- DTA_HorizUnit ,&ux,
- DTA_Domain ,&domain,
- TAG_DONE) == 7 && lbuf)
- {
- BOOL showascii = (bd->bd_Flags & BDF_SHOWASCII) ||
- (bd->bd_DisplayHex == BDTDH_NONE);
- UWORD numadd = (bd->bd_BufferLen > ((1<<16) - 1)) ? 10 : 6;
-
- topy = y;
- topx = x;
-
- height = (h-1) * uy;
-
- rect.MinX = domain->Left;
- rect.MinY = domain->Top;
- rect.MaxX = domain->Left + w * ux - 1;
- rect.MaxY = domain->Top + h * uy - 1;
-
- SetFont(GPR(msg)->gpr_RPort,bd->bd_Font);
- SetABPenDrMd(rp,fgpen,bgpen,JAM2);
-
- y *= uy;
- x *= ux;
-
- dx = (x - bd->bd_OldX);
- dy = (y - bd->bd_OldY);
-
- bd->bd_OldX = x;
- bd->bd_OldY = y;
-
- if(dx > domain->Width/2 || dx <-domain->Width/2)
- dx = 0;
-
- if(dy > height/2 || dy < -height/2)
- dy = 0;
-
- py = 0;
- px = 0;
-
- if(dx || dy)
- ScrollRasterBF(rp,dx,dy,
- rect.MinX,rect.MinY,rect.MaxX,rect.MaxY);
-
- D(bug("dx : %ld , dy : %ld\n",dx,dy));
-
- if(dx == 0)
- {
- if(dy < 0)
- height = -dy;
- else if(dy > 0)
- {
- py = height - dy;
- topy += ((domain->Height / uy) - dy/uy);
- }
- } else if(dx > 0)
- {
- px = w * ux - dx;
- topx += (w - (dx/ux));
- w = dx/ux;
- } else
- {
- w = (-dx/ux);
- }
-
- num = topy * bd->bd_BytesPerLine;
- ptr = &bd->bd_Buffer[num];
- end = &bd->bd_Buffer[bd->bd_BufferLen];
-
- D(bug("py : %ld , height : %ld\n",py,height));
-
- for(; py <= height ; py += rp->TxHeight)
- {
- bptr = ptr;
- ptr1 = lbuf;
-
- if(numadd == 10)
- sprintf(lbuf,"%08lx: ",num);
- else
- sprintf(lbuf,"%04lx: ",num);
- ptr1 += numadd;
-
- switch(bd->bd_DisplayHex)
- {
- case BDTDH_BYTE:
- for(grp = 0 ; grp < bd->bd_NumGroups && ptr < end ; grp++)
- {
- sprintf(ptr1,"%02lx ",*ptr);
- ptr++;
- ptr1 += 3;
- }
-
- while(grp < bd->bd_NumGroups)
- {
- strcpy(ptr1," ");
- ptr1 += 3;
- ptr++;
- grp++;
- }
- break;
- case BDTDH_WORD:
- for(grp = 0 ; grp < bd->bd_NumGroups && ptr < end ; grp++)
- {
- sprintf(ptr1,"%04lx ",*((UWORD *) ptr));
- ptr += sizeof(UWORD);
- ptr1 += 5;
- }
-
- while(grp < bd->bd_NumGroups)
- {
- strcpy(ptr1," ");
- ptr1 += 5;
- ptr += sizeof(UWORD);
- grp++;
- }
- break;
- case BDTDH_LONG:
- for(grp = 0 ; grp < bd->bd_NumGroups && ptr < end ; grp++)
- {
- sprintf(ptr1,"%08lx ",*((ULONG *) ptr));
- ptr += sizeof(ULONG);
- ptr1 += 9;
- }
-
- while(grp < bd->bd_NumGroups)
- {
- strcpy(ptr1," ");
- ptr1 += 9;
- ptr += sizeof(ULONG);
- grp++;
- }
- break;
- default:
- ptr += bd->bd_BytesPerLine;
- }
-
- /* write ASCII string */
- if(showascii)
- {
- while(bptr < ptr && bptr < end)
- {
- if(*bptr < 32)
- *ptr1 = '.';
- else
- *ptr1 = *bptr;
- ptr1++;
- bptr++;
- }
-
- while(bptr < ptr)
- {
- *ptr1++ = ' ';
- bptr++;
- }
- }
-
- chrs = MIN((ptr1 - lbuf) - topx,w);
- if(chrs > 0)
- {
- Move(rp,domain->Left + px,domain->Top + py + rp->TxBaseline);
- Text(rp,&lbuf[topx],chrs);
- }
-
- num += bd->bd_BytesPerLine;
- }
- }
- }
- retval = DoSuperMethodA(cl,obj,msg);
- break;
- case DTM_WRITE:
- bd = INST_DATA(cl,obj);
-
- switch(WRMSG(msg)->dtw_Mode)
- {
- case DTWM_RAW:
- D(bug("dtWrite Rawmode : filehandle %lx !\n",WRMSG(msg)->dtw_FileHandle));
- D(bug("attrs at : %lx\n",WRMSG(msg)->dtw_AttrList));
- D({
- struct TagItem *tstate = WRMSG(msg)->dtw_AttrList;
- struct TagItem *tag;
-
- while((tag = NextTagItem(&tstate)))
- bug("{%08lx,%ld}\n",tag->ti_Tag,tag->ti_Data);
- });
-
- Write(WRMSG(msg)->dtw_FileHandle,bd->bd_Buffer,bd->bd_BufferLen);
- retval = 1;
- break;
- default:
- retval = DoSuperMethodA(cl,obj,msg);
- }
- break;
- default:
- retval = DoSuperMethodA(cl,obj,msg);
- }
-
- return(retval);
- }
- /*FE*/
-
- /*FS*/ ULONG getattr(Class *cl,Object *obj,struct opGet *msg)
- {
- struct BinaryData *bd = INST_DATA(cl,obj);
- ULONG *storage = msg->opg_Storage;
-
- switch(msg->opg_AttrID)
- {
- case DTA_TextFont:
- *storage = (ULONG) bd->bd_Font;
- break;
- case DTA_TextAttr:
- *storage = (ULONG) &bd->bd_TextAttr;
- break;
- case DTA_Methods:
- *storage = (ULONG) methods;
- break;
- case BDTA_Buffer:
- *storage = (ULONG) bd->bd_Buffer;
- break;
- case BDTA_BufferLen:
- *storage = (ULONG) bd->bd_BufferLen;
- break;
- case BDTA_BytesPerLine:
- *storage = (ULONG) bd->bd_BytesPerLine;
- break;
- case BDTA_DisplayHex:
- *storage = (ULONG) bd->bd_DisplayHex;
- break;
- case BDTA_ShowASCII:
- *storage = (ULONG) ((bd->bd_Flags & BDF_SHOWASCII) == BDF_SHOWASCII);
- break;
- case BDTA_DisplayWrap:
- *storage = (ULONG) ((bd->bd_Flags & BDF_DISPLAYWRAP) == BDF_DISPLAYWRAP);
- break;
- default:
- return(0);
- }
- return(1);
- }
- /*FE*/
-
- /*FS*/ ULONG setattrs(Class *cl,Object *obj,struct opSet *msg)
- {
- struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
- struct BinaryData *bd = INST_DATA(cl,obj);
-
- struct TagItem *tstate = msg->ops_AttrList;
- struct TagItem *tag;
-
- ULONG retval = 0;
- ULONG tidata;
-
- while((tag = NextTagItem(&tstate)))
- {
- tidata = tag->ti_Data;
-
- retval++;
- switch(tag->ti_Tag)
- {
- case DTA_TextAttr:
- {
- struct TextFont *font;
-
- if((font = OpenFont((struct TextAttr *) tidata)))
- {
- /* only use fixed width fonts */
- if(font->tf_Flags & FPF_PROPORTIONAL)
- {
- CloseFont(font);
- useDefaultFont(cb,bd);
- } else
- {
- bd->bd_TextAttr = *((struct TextAttr *) tidata);
- bd->bd_TextAttr.ta_Name = bd->bd_FontName;
- strcpy(bd->bd_FontName,((struct TextAttr *) tidata)->ta_Name);
-
- if(bd->bd_Font)
- CloseFont(bd->bd_Font);
-
- bd->bd_Font = font;
- }
- } else
- retval--;
- }
- break;
- case BDTA_Buffer:
- {
- ULONG len = GetTagData(BDTA_BufferLen,0,msg->ops_AttrList);
-
- if(tidata && len)
- {
- if((bd->bd_Buffer) && (bd->bd_Flags & BDF_ALLOCATED))
- FreeMem(bd->bd_Buffer,bd->bd_BufferLen);
-
- bd->bd_Flags &= ~BDF_ALLOCATED;
-
- bd->bd_Buffer = (UBYTE *) tidata;
- bd->bd_BufferLen = len;
-
- retval++;
- } else
- retval--;
- }
- break;
- case BDTA_BytesPerLine:
- if(tag->ti_Data != bd->bd_BytesPerLine)
- bd->bd_BytesPerLine = (UWORD) tag->ti_Data;
- else
- retval--;
- break;
- case BDTA_DisplayHex:
- if(tag->ti_Data != bd->bd_DisplayHex)
- bd->bd_DisplayHex = (UWORD) tag->ti_Data;
- else
- retval--;
- break;
- case BDTA_ShowASCII:
- if(tag->ti_Data)
- bd->bd_Flags |= BDF_SHOWASCII;
- else
- bd->bd_Flags &= ~BDF_SHOWASCII;
- break;
- case BDTA_DisplayWrap:
- if(tag->ti_Data)
- bd->bd_Flags |= BDF_DISPLAYWRAP;
- else
- bd->bd_Flags &= ~BDF_DISPLAYWRAP;
- break;
- default:
- retval--;
- }
- }
-
- return(retval);
- }
- /*FE*/
-
- /*FS*/ GetA4 ULONG layout(struct ClassBase *cb, Class * cl, Object * obj, struct gpLayout * gpl)
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *) G(obj)->SpecialInfo;
- struct BinaryData *bd = INST_DATA(cl,obj);
-
- /* Attributes obtained from super-class */
-
- struct TextFont *font = bd->bd_Font;
- struct IBox *domain;
-
- ULONG retval = 0;
-
- ENTERING;
-
- /* Get all the attributes that we are going to need for a successful layout */
- if((GetDTAttrs(obj,DTA_Domain, (ULONG) &domain,
- TAG_DONE) == 1))
- {
- /* Lock the global object data so that nobody else can manipulate it */
- ObtainSemaphore (&(si->si_Lock));
-
- #ifdef EXPERIMENTAL
- {
- APTR gadobj;
- /* dispose all objects from the list c*/
- gadobj = bd->bd_ObjectList.lh_Head;
- while((gadobj = NextObject(&gadobj)))
- {
- DoMethod(gadobj,OM_REMOVE);
- if(G(gadobj)->GadgetRender)
- DoMethod(G(gadobj)->GadgetRender,OM_DISPOSE);
- DoMethod(gadobj,OM_DISPOSE);
- }
-
- {
- Object *image;
- if((image = NewObject(NULL,"frameiclass",IA_Left ,20 /* domain->Left + 4 */,
- IA_Top ,20 /* domain->Top + 1 */,
- IA_Width ,100 /* domain->Width - 8 */,
- IA_Height ,10 /* font->tf_YSize + 4 */,
- IA_FrameType,FRAME_BUTTON,
- TAG_DONE)))
- if((gadobj = NewObject(NULL,"gadgetclass",GA_Left ,20 /* domain->Left + 4 */,
- GA_Top ,20 /* domain->Top + 1 */,
- GA_Width ,100 /* domain->Width - 8 */,
- GA_Height ,10 /* font->tf_YSize + 4 */,
- GA_ID , 1,
- GA_Image ,image,
- TAG_DONE)))
- {
- DoMethod(gadobj,GM_LAYOUT,gpl->gpl_GInfo,TRUE);
- DoMethod(gadobj,OM_ADDTAIL,&bd->bd_ObjectList);
- } else
- DoMethod(image,OM_DISPOSE);
- }
- }
- #endif
-
- retval = si->si_TotVert;
-
- /* We only need to perform layout if we are doing word wrap, or this
- * is the initial layout call */
- if(gpl->gpl_Initial || (bd->bd_Flags & BDF_DISPLAYWRAP))
- {
- const UBYTE displayhexbytes[] = {0,3,5,9};
- const UBYTE displayasciibytes[] = {1,1,2,4};
-
- ULONG numgroups;
- ULONG bytesperline;
- ULONG lines;
- ULONG displayaddr = (bd->bd_BufferLen >= (1<<16)) ? 10 : 6;
- ULONG showascii;
-
- showascii = ((bd->bd_Flags & BDF_SHOWASCII) || bd->bd_DisplayHex == BDTDH_NONE) ? 1 : 0;
-
- numgroups =
- bytesperline = bd->bd_BytesPerLine;
-
- if(bd->bd_DisplayHex)
- numgroups >>= (bd->bd_DisplayHex - 1);
-
- /* Note this wrap function doesn't work right with proportional fonts !* */
- if(bd->bd_Flags & BDF_DISPLAYWRAP)
- {
- ULONG chars = domain->Width / bd->bd_Font->tf_XSize;
-
- D(bug("object width : %ld\n",domain->Width));
- D(bug("font width : %ld\n",font->tf_XSize));
- D(bug("chars : %ld\n",chars));
-
- bytesperline =
- numgroups = (chars - displayaddr - showascii) / (displayhexbytes[bd->bd_DisplayHex] +
- ((showascii) ? displayasciibytes[bd->bd_DisplayHex] : 0));
-
- if(bd->bd_DisplayHex)
- bytesperline = (numgroups) << (bd->bd_DisplayHex - 1);
- }
-
- if(bytesperline < 4)
- {
- bytesperline = 4;
- numgroups = bytesperline / displayasciibytes[bd->bd_DisplayHex];
- }
-
-
- lines = (bd->bd_BufferLen / bytesperline) + ((bd->bd_BufferLen % bytesperline) ? 1 : 0) - 1;
-
- bd->bd_LineBytes = displayaddr + numgroups * displayhexbytes[bd->bd_DisplayHex] +
- ((showascii) ? bytesperline : 0) + 1;
- bd->bd_NumGroups = numgroups;
- bd->bd_BytesPerLine = bytesperline;
-
- if(bd->bd_LineBuffer && bd->bd_LineBytes > bd->bd_LineBufferLen)
- {
- FreeMem(bd->bd_LineBuffer,bd->bd_LineBufferLen);
- bd->bd_LineBuffer = NULL;
- }
-
- if(!bd->bd_LineBuffer)
- {
- bd->bd_LineBufferLen = bd->bd_LineBytes;
- bd->bd_LineBuffer = AllocMem(bd->bd_LineBufferLen,MEMF_ANY);
- }
-
- /* Compute the lines and columns type information */
- si->si_VertUnit = font->tf_YSize;
- si->si_VisVert = domain->Height / si->si_VertUnit;
- si->si_TotVert = lines;
-
- si->si_HorizUnit = font->tf_XSize;
- si->si_VisHoriz = domain->Width / font->tf_XSize;
- si->si_TotHoriz = bd->bd_LineBytes;
-
- /* Release the global data lock */
- ReleaseSemaphore(&si->si_Lock);
-
- retval = lines;
-
- if(gpl->gpl_Initial)
- {
- struct RastPort *rp;
-
- /* Get a pointer to the rastport */
- if((rp = ObtainGIRPort (gpl->gpl_GInfo)))
- {
- struct gpRender gpr;
-
- /* Force a redraw */
- gpr.MethodID = GM_RENDER;
- gpr.gpr_GInfo = gpl->gpl_GInfo;
- gpr.gpr_RPort = rp;
- gpr.gpr_Redraw = GREDRAW_REDRAW;
- DoMethodA (obj, (Msg) &gpr);
-
- /* Release the temporary rastport */
- ReleaseGIRPort (rp);
- }
- }
- }
- /* Not aborted, so tell the world of our newest attributes */
- notifyAttrChanges (obj, gpl->gpl_GInfo, NULL,
- GA_ID, G(obj)->GadgetID,
-
- DTA_VisibleVert, domain->Height / font->tf_YSize,
- DTA_TotalVert, retval,
- DTA_NominalVert, font->tf_YSize * 25,
- DTA_VertUnit, font->tf_YSize,
-
- DTA_VisibleHoriz, domain->Width / font->tf_XSize,
- DTA_TotalHoriz, bd->bd_LineBytes,
- DTA_NominalHoriz, font->tf_XSize * 80,
- DTA_HorizUnit, font->tf_XSize,
-
- DTA_Title, bd->bd_Name,
- DTA_Busy, FALSE,
- DTA_Sync, TRUE,
- TAG_DONE);
-
- }
-
- LEAVING;
-
- return(retval);
- }
- /*FE*/
-
-