7 * (C) Copyright 1998 Manuel Lemos.
8 * (C) Copyright 1996-1997 Ian J. Einman.
9 * (C) Copyright 1993-1996 Jaba Development.
10 * (C) Copyright 1993-1996 Jan van den Baard.
11 * All Rights Reserved.
14 * Revision 42.13 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.12 2003/01/18 19:10:01 chodorowski
18 * Instead of using the _AROS or __AROS preprocessor symbols, use __AROS__.
20 * Revision 42.11 2001/01/28 04:53:21 bergers
21 * Fixed some compiler complaints (some casts were missing.).
23 * Revision 42.10 2000/08/09 14:54:19 stegerg
24 * fixed a bug which was introduced by one of us AROS guys and which caused
25 * enforcer hits on Amiga.
27 * Revision 42.9 2000/08/09 11:45:57 chodorowski
28 * Removed a lot of #ifdefs that disabled the AROS_LIB* macros when not building on AROS. This is now handled in contrib/bgui/include/bgui_compilerspecific.h.
30 * Revision 42.8 2000/08/08 18:16:12 stegerg
31 * bug fix in BGUI_FreePoolMem/FreePoolMemDebug.
33 * Revision 42.7 2000/08/08 14:17:30 chodorowski
34 * Fixes to compile on Amiga. There was some wrongly nested #ifdefs here,
35 * around the BGUI_FreePooled and BGUI_FreePooledDebug functions.
36 * Now it compiles, but I'm a bit dubiuos if it works as it should.
37 * Could someone have a look please?
39 * Revision 42.6 2000/07/06 16:44:03 stegerg
40 * AddTaskMember can now be called. Problem was Cli()->cli_CommandName
41 * which BGUI expected to be a BSTR with size in first byte.
43 * Revision 42.5 2000/06/01 01:41:37 bergers
44 * Only 2 linker problems left: stch_l & stcu_d. Somebody might want to replace them (embraced by #ifdef __AROS__), please.
46 * Revision 42.4 2000/05/31 01:23:10 bergers
47 * Changes to make BGUI compilable and linkable.
49 * Revision 42.3 2000/05/29 00:40:24 bergers
50 * Update to compile with AROS now. Should also still compile with SASC etc since I only made changes that test the define __AROS__. The compilation is still very noisy but it does the trick for the main directory. Maybe members of the BGUI team should also have a look at the compiler warnings because some could also cause problems on other systems... (Comparison always TRUE due to datatype (or something like that)). And please compile it on an Amiga to see whether it still works... Thanks.
52 * Revision 42.2 2000/05/15 19:27:02 stegerg
53 * another hundreds of REG() macro replacements in func headers/protos.
55 * Revision 42.1 2000/05/14 23:32:48 stegerg
56 * changed over 200 function headers which all use register
57 * parameters (oh boy ...), because the simple REG() macro
58 * doesn't work with AROS. And there are still hundreds
59 * of headers left to be fixed :(
61 * Many of these functions would also work with stack
62 * params, but since i have fixed every single one
63 * I encountered up to now, I guess will have to do
64 * the same for the rest.
66 * Revision 42.0 2000/05/09 22:10:28 mlemos
67 * Bumped to revision 42.0 before handing BGUI to AROS team
69 * Revision 41.11 2000/05/09 19:55:18 mlemos
70 * Merged with the branch Manuel_Lemos_fixes.
72 * Revision 41.10.2.10 1998/12/07 14:47:28 mlemos
73 * Made font tracking code use a copy of the TextFont structure to allow the
74 * opened fonts be properly tracked.
76 * Revision 41.10.2.9 1998/12/07 04:30:04 mlemos
77 * Made the code that lists all unclosed fonts to list all probable source
78 * locations where the fonts were opened.
80 * Revision 41.10.2.8 1998/12/07 03:04:37 mlemos
81 * Added conditional debug code to track fonts opened by BGUI classes.
83 * Revision 41.10.2.7 1998/06/18 22:06:36 mlemos
84 * Made BGUI fetch the preferences from the appropriate file when running from
87 * Revision 41.10.2.6 1998/03/02 03:14:39 mlemos
88 * Corrected the display of the memory leak address.
90 * Revision 41.10.2.5 1998/03/01 23:09:19 mlemos
91 * Added code to trash memory allocations before being freed.
92 * Added code to warn when a NULL pointer is passed to memory release.
94 * Revision 41.10.2.4 1998/03/01 18:42:45 mlemos
95 * Corrected memory wall address verifications.
97 * Revision 41.10.2.3 1998/03/01 18:25:00 mlemos
98 * Added support to track memory overwriting outside the allocated space.
100 * Revision 41.10.2.2 1998/03/01 04:25:23 mlemos
101 * Added support to track memory freeing mismatches and memory leaks.
103 * Revision 41.10.2.1 1998/03/01 02:23:56 mlemos
104 * Added new memory allocation debugging functions to the library
106 * Revision 41.10 1998/02/25 21:13:21 mlemos
109 * Revision 1.1 1998/02/25 17:09:56 mlemos
115 #define NO_MEMORY_ALLOCATION_DEBUG_ALIASING
117 #include "include/classdefs.h"
123 makeproto TL TaskList
; /* List of openers. */
124 makeproto
struct SignalSemaphore TaskLock
; /* For exclusive task-list access. */
126 static APTR MemPool
= NULL
;
128 static void LoadPrefs(UBYTE
*name
);
129 static void DefPrefs(void);
133 static struct BlockHeader
135 struct BlockHeader
*NextBlock
;
147 long int LongInteger
;
148 long double LongDouble
;
150 void (*FunctionPointer
)(void);
153 #define AlignMemory(offset) (((offset)+sizeof(union TypesUnion)-1)/sizeof(union TypesUnion))*sizeof(union TypesUnion)
155 #define MEMORY_WALL_SIZE 8
157 #define MEMORY_WALL_TRASH 'W'
158 #define MEMORY_FREE_TRASH 'Y'
160 #define BLOCK_HEADER_OFFSET AlignMemory(sizeof(struct BlockHeader)+MEMORY_WALL_SIZE)
162 #define TrashMemory(memory,size,character) memset(memory,character,size)
164 static ASM VOID
FreeVecMemDebug(REG(a0
) APTR pool
, REG(a1
) APTR memptr
, REG(a2
) STRPTR file
, REG(d0
) ULONG line
);
166 static ASM APTR
AllocVecMemDebug(REG(a0
) APTR mempool
, REG(d0
) ULONG size
,REG(a1
) STRPTR file
, REG(d1
) ULONG line
);
168 #define AllocVecMem(mempool,size) AllocVecMemDebug(mempool,size,__FILE__,__LINE__)
169 #define FreeVecMem(pool,memptr) FreeVecMemDebug(pool,memptr,__FILE__,__LINE__)
171 static BOOL
VerifyMemoryWall(char *memory
)
175 for(size
=MEMORY_WALL_SIZE
;size
;size
--,memory
++)
177 if(*memory
!=MEMORY_WALL_TRASH
)
184 static ASM APTR
AllocVecMem(REG(a0
) APTR mempool
, REG(d0
) ULONG size
);
186 static ASM VOID
FreeVecMem(REG(a0
) APTR pool
, REG(a1
) APTR memptr
);
189 static SAVEDS ASM APTR
BGUI_CreatePool(REG(d0
) ULONG memFlags
, REG(d1
) ULONG puddleSize
, REG(d2
) ULONG threshSize
);
191 static SAVEDS ASM VOID
BGUI_DeletePool(REG(a0
) APTR poolHeader
);
194 * Initialize task list.
196 makeproto
void InitTaskList(void)
199 * Initialize task-list.
201 NewList((struct List
*)&TaskList
);
206 NewList((struct List
*)&TaskList
.tl_WindowList
);
209 * Initialize task-list access semaphore.
211 InitSemaphore(&TaskLock
);
214 * Create memory pool.
216 MemPool
= BGUI_CreatePool(MEMF_PUBLIC
| MEMF_CLEAR
, 4096, 4096);
221 static struct FontEntry
223 struct FontEntry
*NextFont
;
224 struct TextFont
*Font
;
228 struct TextFont Copy
;
232 static void BGUI_CloseAllFonts(void)
234 struct FontEntry
*font_entry
;
236 for(font_entry
=FontEntries
;font_entry
;font_entry
=font_entry
->NextFont
)
238 if(font_entry
->Closed
==FALSE
)
240 D(bug("***Font leak (%lx) \"%s\" %s,%lu:\n",font_entry
->Font
,font_entry
->Font
->tf_Message
.mn_Node
.ln_Name
? font_entry
->Font
->tf_Message
.mn_Node
.ln_Name
: "Unnamed font",font_entry
->File
? font_entry
->File
: (STRPTR
)"Unknown source",font_entry
->Line
));
241 CloseFont(font_entry
->Font
);
242 font_entry
->Closed
=TRUE
;
245 while((font_entry
=FontEntries
))
247 FontEntries
=font_entry
->NextFont
;
248 BGUI_FreePoolMemDebug(font_entry
,__FILE__
,__LINE__
);
252 makeproto
struct TextFont
*BGUI_OpenFontDebug(struct TextAttr
*textAttr
,STRPTR file
,ULONG line
)
254 struct TextFont
*font
;
256 if((font
=OpenFont(textAttr
)))
258 struct FontEntry
*font_entry
;
260 if((font_entry
=BGUI_AllocPoolMemDebug(sizeof(*font_entry
),__FILE__
,__LINE__
)))
262 font_entry
->Font
=font
;
263 font_entry
->Closed
=FALSE
;
264 font_entry
->File
=file
;
265 font_entry
->Line
=line
;
266 font_entry
->Copy
= *font
;
267 ObtainSemaphore(&TaskLock
);
268 font_entry
->NextFont
=FontEntries
;
269 FontEntries
=font_entry
;
270 ReleaseSemaphore(&TaskLock
);
271 font
= &font_entry
->Copy
;
282 makeproto
void BGUI_CloseFontDebug(struct TextFont
*font
,STRPTR file
,ULONG line
)
284 struct FontEntry
**font_entry
,*free_font_entry
;
288 D(bug("***Attempt to close an NULL font (%s,%lu)\n",file
? file
: (STRPTR
)"Unknown source",line
));
291 ObtainSemaphore(&TaskLock
);
292 for(font_entry
=&FontEntries
;*font_entry
&& (&((*font_entry
)->Copy
)!=font
|| (*font_entry
)->Closed
);font_entry
=&(*font_entry
)->NextFont
);
293 if((free_font_entry
=*font_entry
)
294 && &free_font_entry
->Copy
==font
)
296 CloseFont(free_font_entry
->Font
);
297 free_font_entry
->Closed
=TRUE
;
300 D(bug("***Attempt to close an unknown font (%lx) \"%s\" (%s,%lu)\n",font
,font
->tf_Message
.mn_Node
.ln_Name
? font
->tf_Message
.mn_Node
.ln_Name
: "Unnamed font",file
? file
: (STRPTR
)"Unknown source",line
));
301 ReleaseSemaphore(&TaskLock
);
305 #define BGUI_CloseAllFonts()
311 makeproto
void FreeTaskList(void)
313 BGUI_CloseAllFonts();
315 * Delete memory pool.
317 BGUI_DeletePool(MemPool
);
321 * Find a task member.
323 * Changes made by T.Herold:
325 * InternalFindTaskMember searches for a certain task in
326 * the tasklist. FindTaskMember does this with FindTask(NULL)
327 * as a parameter (just the way it always did). This keeps
328 * changes to other functions to a minimum.
330 * Only AddIDReport will use InternalFind...
333 makeproto TM
*FindTaskMember(void)
335 return InternalFindTaskMember(FindTask(NULL
));
338 makeproto TM
*InternalFindTaskMember(struct Task
*task
)
343 * Look through the list for the member.
345 for (tm
= TaskList
.tl_First
; tm
->tm_Next
; tm
= tm
->tm_Next
)
347 if (tm
->tm_TaskAddr
== task
) return tm
;
354 * Add a task member to the list.
356 makeproto UWORD
AddTaskMember(void)
359 UWORD rc
= TASK_FAILED
;
365 ObtainSemaphore(&TaskLock
);
368 * Does this task already have the
371 if ((tm
= FindTaskMember()))
374 * Yes. Increase open counter,
375 * unlock the semaphore and
379 ReleaseSemaphore(&TaskLock
);
380 return TASK_REOPENED
;
384 * Allocate a task member structure.
386 if ((tm
= AllocVecMem(MemPool
, sizeof(TM
))))
389 * Setup task address and counter.
391 tm
->tm_TaskAddr
= FindTask(NULL
);
397 NewList((struct List
*)&tm
->tm_Windows
);
398 NewList((struct List
*)&tm
->tm_Prefs
);
399 NewList((struct List
*)&tm
->tm_RID
);
402 * Append it to the list.
404 AddTail((struct List
*)&TaskList
, (struct Node
*)tm
);
407 sprintf(buffer
, "ENV:BGUI/%s.prefs", "Default");
411 STRPTR command_name
,insert
;
415 command_name
=BADDR(Cli()->cli_CommandName
);
416 strcpy(buffer
,"ENV:BGUI/");
417 insert
=buffer
+sizeof("ENV:BGUI/")-1;
419 strcpy(insert
,command_name
);
420 command_len
= strlen(command_name
);
422 memcpy(insert
,command_name
+1,*command_name
);
423 command_len
= *command_name
;
424 *(insert
+ command_len
)='\0';
426 if((offset
=FilePart(insert
)-insert
)!=0)
427 memcpy(insert
,command_name
+1+offset
,command_len
-offset
);
428 insert
+= command_len
-offset
;
429 strcpy(insert
,".prefs");
432 sprintf(buffer
, "ENV:BGUI/%s.prefs", FilePart(((struct Node
*)(tm
->tm_TaskAddr
))->ln_Name
));
441 ReleaseSemaphore(&TaskLock
);
447 static void FreeTL_PI(PI
*pi
)
449 FreeTagItems(pi
->pi_Defaults
);
450 FreeVecMem(MemPool
, pi
);
452 static void FreeTL_WI(WI
*wi
)
454 FreeVecMem(MemPool
, wi
);
456 static void FreeTL_RID(RID
*rid
)
458 FreeVecMem(MemPool
, rid
);
464 makeproto BOOL
FreeTaskMember( void )
474 ObtainSemaphore(&TaskLock
);
477 * Find the task member.
479 if ((tm
= FindTaskMember()))
484 if (--tm
->tm_Counter
)
487 * No. release the semaphore and exit.
489 ReleaseSemaphore(&TaskLock
);
494 * Remove it from the list.
496 Remove((struct Node
*)tm
);
499 * Remove and delete window/id stuff.
501 while ((pi
= (PI
*)RemHead((struct List
*)&tm
->tm_Prefs
))) FreeTL_PI(pi
);
502 while ((wi
= (WI
*)RemHead((struct List
*)&tm
->tm_Windows
))) FreeTL_WI(wi
);
503 while ((rid
= (RID
*)RemHead((struct List
*)&tm
->tm_RID
))) FreeTL_RID(rid
);
505 FreeVecMem(MemPool
, tm
);
511 ReleaseSemaphore(&TaskLock
);
519 STATIC WI
*FindWindowInfo(ULONG id
, WL
*wl
)
524 * Scan the window list.
526 for (wi
= wl
->wl_First
; wi
->wi_Next
; wi
= wi
->wi_Next
)
528 if (id
== wi
->wi_WinID
)
535 * Obtain the window bounds.
537 makeproto BOOL
GetWindowBounds(ULONG windowID
, struct IBox
*dest
)
550 * Gain exclusive access.
552 ObtainSemaphore( &TaskLock
);
555 * Look up the task member.
557 if ((tm
= FindTaskMember()))
560 * Window already in the list?
562 if ((wi
= FindWindowInfo(windowID
, &tm
->tm_Windows
)))
565 * Copy the data to dest.
567 *dest
= wi
->wi_Bounds
;
573 * Allocate and append a new one.
575 if ((wi
= (WI
*)AllocVecMem(MemPool
, sizeof(WI
))))
577 wi
->wi_WinID
= windowID
;
578 AddTail((struct List
*)&tm
->tm_Windows
, (struct Node
*)wi
);
586 ReleaseSemaphore(&TaskLock
);
592 * Set the window bounds.
594 makeproto VOID
SetWindowBounds(ULONG windowID
, struct IBox
*set
)
606 * Gain exclusive access.
608 ObtainSemaphore(&TaskLock
);
611 * Look up the task member.
613 if ((tm
= FindTaskMember()))
616 * Window in the list?
618 if ((wi
= FindWindowInfo(windowID
, &tm
->tm_Windows
)))
623 wi
->wi_Bounds
= *set
;
630 ReleaseSemaphore( &TaskLock
);
634 * Asm stubs for the pool routines.
636 extern ASM APTR
AsmCreatePool ( REG(d0
) ULONG
, REG(d1
) ULONG
, REG(d2
) ULONG
, REG(a6
) struct ExecBase
* );
638 extern ASM APTR
AsmAllocPooled ( REG(a0
) APTR
, REG(d0
) ULONG
, REG(a6
) struct ExecBase
* );
640 extern ASM APTR
AsmFreePooled ( REG(a0
) APTR
, REG(a1
) APTR
, REG(d0
) ULONG
, REG(a6
) struct ExecBase
* );
642 extern ASM APTR
AsmDeletePool ( REG(a0
) APTR
, REG(a6
) struct ExecBase
* );
645 * Create a memory pool.
647 static SAVEDS ASM APTR
BGUI_CreatePool(REG(d0
) ULONG memFlags
, REG(d1
) ULONG puddleSize
, REG(d2
) ULONG threshSize
)
653 return CreatePool(memFlags
, puddleSize
, threshSize
);
659 return AsmCreatePool(memFlags
, puddleSize
, threshSize
, SysBase
);
665 * Delete a memory pool.
667 static SAVEDS ASM VOID
BGUI_DeletePool(REG(a0
) APTR poolHeader
)
670 struct BlockHeader
**header
;
672 for(header
= &MemoryBlocks
;*header
;)
674 if((*header
)->PoolHeader
==poolHeader
)
676 D(bug("***Memory leak (%lx) (%s,%lu)\n",(*header
)->Address
,(*header
)->File
? (*header
)->File
: (STRPTR
)"Unknown file", (*header
)->Line
));
677 *header
=(*header
)->NextBlock
;
680 header
= &(*header
)->NextBlock
;
687 DeletePool(poolHeader
);
693 AsmDeletePool(poolHeader
, SysBase
);
699 * Allocate pooled memory.
703 static SAVEDS ASM APTR
BGUI_AllocPooledDebug(REG(a0
) APTR poolHeader
, REG(d0
) ULONG memSize
,REG(a1
) STRPTR file
,REG(d1
) ULONG line
)
705 static SAVEDS ASM APTR
BGUI_AllocPooled(REG(a0
) APTR poolHeader
, REG(d0
) ULONG memSize
)
713 memSize
=AlignMemory(memSize
+BLOCK_HEADER_OFFSET
+MEMORY_WALL_SIZE
);
719 memory
=AllocPooled(poolHeader
, memSize
);
725 memory
=AsmAllocPooled(poolHeader
, memSize
, SysBase
);
732 struct BlockHeader
*header
=memory
;
734 memory
=((char *)memory
)+BLOCK_HEADER_OFFSET
;
735 header
->NextBlock
=MemoryBlocks
;
736 header
->Address
=memory
;
738 header
->PoolHeader
=poolHeader
;
742 TrashMemory(((char *)memory
)-MEMORY_WALL_SIZE
,MEMORY_WALL_SIZE
,MEMORY_WALL_TRASH
);
743 TrashMemory(((char *)memory
)+size
,MEMORY_WALL_SIZE
,MEMORY_WALL_TRASH
);
750 * Free pooled memory.
753 static SAVEDS ASM VOID
BGUI_FreePooledDebug(REG(a0
) APTR poolHeader
, REG(a1
) APTR memory
, REG(d1
) ULONG memSize
,REG(a2
) STRPTR file
,REG(d2
) ULONG line
)
755 static SAVEDS ASM VOID
BGUI_FreePooled(REG(a0
) APTR poolHeader
, REG(a1
) APTR memory
, REG(d1
) ULONG memSize
)
759 struct BlockHeader
**header
;
761 for(header
= &MemoryBlocks
;*header
;header
= &(*header
)->NextBlock
)
763 if((*header
)->Address
==memory
)
768 D(bug("***Attempt to free an unknown memory block (%s,%lu)\n",file
? file
: (STRPTR
)"Unknown file", line
));
773 if((*header
)->PoolHeader
!=poolHeader
)
775 D(bug("***Attempt to free a memory block from a wrong memory pool (%lx) (%s,%lu)\n",poolHeader
,file
? file
: (STRPTR
)"Unknown file", line
));
776 D(bug("***The original memory pool was (%lx) (%s,%lu)\n",(*header
)->PoolHeader
,(*header
)->File
? (*header
)->File
: (STRPTR
)"Unknown file", (*header
)->Line
));
778 if(!VerifyMemoryWall(((char *)(*header
)->Address
)-MEMORY_WALL_SIZE
))
780 D(bug("***Lower memory wall violation (%s,%lu)\n",file
? file
: (STRPTR
)"Unknown file", line
));
781 D(bug("***Memory originally allocated from (%s,%lu)\n",(*header
)->File
? (*header
)->File
: (STRPTR
)"Unknown file", (*header
)->Line
));
783 if(!VerifyMemoryWall(((char *)(*header
)->Address
)+(*header
)->Size
))
785 D(bug("***Upper memory wall violation (%s,%lu)\n",file
? file
: (STRPTR
)"Unknown file", line
));
786 D(bug("***Memory originally allocated from (%s,%lu)\n",(*header
)->File
? (*header
)->File
: (STRPTR
)"Unknown file", (*header
)->Line
));
791 block_size
=(*header
)->BlockSize
;
793 *header
=(*header
)->NextBlock
;
794 TrashMemory(memory
,block_size
,MEMORY_FREE_TRASH
);
802 FreePooled(poolHeader
, memory
, memSize
);
808 AsmFreePooled(poolHeader
, memory
, memSize
, SysBase
);
817 static ASM APTR
AllocVecMemDebug(REG(a0
) APTR mempool
, REG(d0
) ULONG size
,REG(a1
) STRPTR file
, REG(d1
) ULONG line
)
819 static ASM APTR
AllocVecMem(REG(a0
) APTR mempool
, REG(d0
) ULONG size
)
829 size
+= sizeof(ULONG
);
831 * Allocate memory from the pool.
834 if ((mem
= (ULONG
*)BGUI_AllocPooledDebug(mempool
, size
,file
,line
)))
836 if ((mem
= (ULONG
*)BGUI_AllocPooled(mempool
, size
)))
846 * Normal system allocation.
848 mem
= (ULONG
*)AllocVec(size
, MEMF_PUBLIC
| MEMF_CLEAR
);
857 static ASM VOID
FreeVecMemDebug(REG(a0
) APTR pool
, REG(a1
) APTR memptr
, REG(a2
) STRPTR file
, REG(d0
) ULONG line
)
859 static ASM VOID
FreeVecMem(REG(a0
) APTR pool
, REG(a1
) APTR memptr
)
862 ULONG
*mem
= (ULONG
*)memptr
;
870 * Retrieve original allocation and size.
874 BGUI_FreePooledDebug(pool
, (APTR
)mem
, *mem
,file
,line
);
876 BGUI_FreePooled(pool
, (APTR
)mem
, *mem
);
880 * Normal system de-allocation.
886 * Allocate memory from the pool.
890 AROS_LH1(APTR
, BGUI_AllocPoolMem
,
891 AROS_LHA(ULONG
, size
, D0
),
892 struct Library
*, BGUIBase
, 12, BGUI
)
894 SAVEDS ASM APTR
BGUI_AllocPoolMem(REG(d0
) ULONG size
)
899 D(bug("BGUI_AllocPoolMem is being called from unknown location\n"));
900 return(BGUI_AllocPoolMemDebug(size
,__FILE__
,__LINE__
));
907 AROS_LH3(APTR
, BGUI_AllocPoolMemDebug
,
908 AROS_LHA(ULONG
, size
, D0
),
909 AROS_LHA(STRPTR
, file
, A0
),
910 AROS_LHA(ULONG
, line
, D1
),
911 struct Library
*BGUIBase
, 31, BGUI
)
913 makeproto SAVEDS ASM APTR
BGUI_AllocPoolMemDebug(REG(d0
) ULONG size
, REG(a0
) STRPTR file
, REG(d1
) ULONG line
)
920 AROS_LH3(APTR
, BGUI_AllocPoolMemDebug
,
921 AROS_LHA(ULONG
, size
, D0
),
922 AROS_LHA(STRPTR
, file
, A0
),
923 AROS_LHA(ULONG
, line
, D1
),
924 struct Library
*, BGUIBase
, 31, BGUI
)
926 SAVEDS ASM APTR
BGUI_AllocPoolMemDebug(REG(d0
) ULONG size
, REG(a0
) STRPTR file
, REG(d1
) ULONG line
)
931 bug("BGUI_AllocPoolMemDebug is being called from (%s,%lu)\n",file
? file
: (STRPTR
)"unknown",line
);
932 return(BGUI_AllocPoolMem(size
));
939 AROS_LH1(APTR
, BGUI_AllocPoolMem
,
940 AROS_LHA(ULONG
, size
, D0
),
941 struct Library
*, BGUIBase
, 12, BGUI
)
943 makeproto SAVEDS ASM APTR
BGUI_AllocPoolMem(REG(d0
) ULONG size
)
955 ObtainSemaphore(&TaskLock
);
961 memPtr
= AllocVecMemDebug(MemPool
, size
, file
, line
);
963 memPtr
= AllocVecMem(MemPool
, size
);
969 ReleaseSemaphore(&TaskLock
);
977 * Free memory from the pool.
981 AROS_LH1(VOID
, BGUI_FreePoolMem
,
982 AROS_LHA(APTR
, memPtr
, A0
),
983 struct Library
*, BGUIBase
, 13, BGUI
)
985 SAVEDS ASM VOID
BGUI_FreePoolMem(REG(a0
) APTR memPtr
)
990 D(bug("BGUI_FreePoolMem is being called from unknown location\n"));
991 BGUI_FreePoolMemDebug(memPtr
,__FILE__
,__LINE__
);
998 AROS_LH3(VOID
, BGUI_FreePoolMemDebug
,
999 AROS_LHA(APTR
, memPtr
, A0
),
1000 AROS_LHA(STRPTR
, file
, A1
),
1001 AROS_LHA(ULONG
, line
, D0
),
1002 struct Library
*, BGUIBase
, 32, BGUI
)
1004 makeproto SAVEDS ASM VOID
BGUI_FreePoolMemDebug(REG(a0
) APTR memPtr
, REG(a1
) STRPTR file
, REG(d0
) ULONG line
)
1011 AROS_LH3(VOID
, BGUI_FreePoolMemDebug
,
1012 AROS_LHA(APTR
, memPtr
, A0
),
1013 AROS_LHA(STRPTR
, file
, A1
),
1014 AROS_LHA(ULONG
, line
, D0
),
1015 struct Library
*, BGUIBase
, 32, BGUI
)
1017 makeproto SAVEDS ASM VOID
BGUI_FreePoolMemDebug(REG(a0
) APTR memPtr
, REG(a1
) STRPTR file
, REG(d0
) ULONG line
)
1022 bug("BGUI_FreePoolMemDebug is being called from (%s,%lu)\n",file
? file
: (STRPTR
)"unknown",line
);
1023 BGUI_FreePoolMem(memPtr
);
1030 AROS_LH1(VOID
, BGUI_FreePoolMem
,
1031 AROS_LHA(APTR
, memPtr
, A0
),
1032 struct Library
*, BGUIBase
, 13, BGUI
)
1034 makeproto SAVEDS ASM VOID
BGUI_FreePoolMem(REG(a0
) APTR memPtr
)
1047 ObtainSemaphore(&TaskLock
);
1053 FreeVecMemDebug(MemPool
, memPtr
, file
, line
);
1055 FreeVecMem(MemPool
, memPtr
);
1061 ReleaseSemaphore(&TaskLock
);
1065 D(bug("*** Attempt to free memory with a NULL pointer\n"));
1072 * Add an ID to the list.
1074 * Changes made by T.Herold
1076 * - Added reg(a1) Task param
1077 * - Uses InternalFindTaskMember to find destination task.
1080 makeproto ASM BOOL
AddIDReport(REG(a0
) struct Window
*window
, REG(d0
) ULONG id
, REG(a1
) struct Task
*task
)
1087 * Lock the task list.
1089 ObtainSemaphore(&TaskLock
);
1094 if ((tm
= InternalFindTaskMember(task
)))
1099 if ((rid
= (RID
*)AllocVecMem(MemPool
, sizeof(RID
))))
1105 rid
->rid_Window
= window
;
1106 AddTail((struct List
*)&tm
->tm_RID
, (struct Node
*)rid
);
1112 * Release the task list.
1114 ReleaseSemaphore(&TaskLock
);
1120 * Get next ID for the window.
1122 makeproto ASM ULONG
GetIDReport(REG(a0
) struct Window
*window
)
1129 * Lock the task list.
1131 ObtainSemaphore(&TaskLock
);
1136 if ((tm
= FindTaskMember()))
1139 * See if an ID for the window
1142 for (rid
= tm
->tm_RID
.ril_First
; rid
->rid_Next
; rid
= rid
->rid_Next
)
1147 if (rid
->rid_Window
== window
)
1150 * Yes. Get the ID and remove it.
1153 Remove((struct Node
*)rid
);
1161 * Release the task list.
1163 ReleaseSemaphore(&TaskLock
);
1169 * Get the window of the first
1172 makeproto
struct Window
*GetFirstIDReportWindow(void)
1175 struct Window
*win
= NULL
;
1178 * Lock the task list.
1180 ObtainSemaphore(&TaskLock
);
1185 if ((tm
= FindTaskMember()))
1188 * Are there any ID's?
1190 if (tm
->tm_RID
.ril_First
->rid_Next
)
1191 win
= tm
->tm_RID
.ril_First
->rid_Window
;
1195 * Release the task list.
1197 ReleaseSemaphore(&TaskLock
);
1203 * Remove all ID's of this window.
1205 makeproto ASM VOID
RemoveIDReport(REG(a0
) struct Window
*window
)
1213 ObtainSemaphore(&TaskLock
);
1218 if ((tm
= FindTaskMember()))
1220 rid
= tm
->tm_RID
.ril_First
;
1221 while ((succ
= rid
->rid_Next
))
1223 if (rid
->rid_Window
== window
)
1225 Remove((struct Node
*)rid
);
1233 * Release the task list.
1235 ReleaseSemaphore(&TaskLock
);
1239 * Add an open window to the list.
1241 makeproto ASM VOID
AddWindow(REG(a0
) Object
*wo
, REG(a1
) struct Window
*win
)
1248 ObtainSemaphore(&TaskLock
);
1253 if ((wn
= (WNODE
*)AllocVecMem(MemPool
, sizeof(WNODE
))))
1258 wn
->wn_WindowObject
= wo
;
1259 wn
->wn_Window
= win
;
1262 * Add it to the list.
1264 AddTail((struct List
*)&TaskList
.tl_WindowList
, (struct Node
*)wn
);
1270 ReleaseSemaphore(&TaskLock
);
1274 * Remove a window from the list.
1276 makeproto ASM VOID
RemWindow(REG(a0
) Object
*wo
)
1283 ObtainSemaphore(&TaskLock
);
1288 for (wn
= TaskList
.tl_WindowList
.wnl_First
; wn
->wn_Next
; wn
= wn
->wn_Next
)
1293 if (wn
->wn_WindowObject
== wo
)
1296 * Yes. Remove and deallocate it.
1298 Remove((struct Node
*)wn
);
1299 FreeVecMem(MemPool
, wn
);
1302 * We're done here...
1311 ReleaseSemaphore(&TaskLock
);
1315 * Find the window located under the mouse.
1317 makeproto ASM Object
*WhichWindow(REG(a0
) struct Screen
*screen
)
1320 struct Layer
*layer
;
1326 ObtainSemaphore(&TaskLock
);
1329 * Find out the layer under the mouse pointer.
1331 if ((layer
= WhichLayer(&screen
->LayerInfo
, screen
->MouseX
, screen
->MouseY
)))
1333 for (wn
= TaskList
.tl_WindowList
.wnl_First
; wn
->wn_Next
; wn
= wn
->wn_Next
)
1338 if (wn
->wn_Window
== layer
->Window
)
1341 * Setup return code and exit loop.
1343 win
= wn
->wn_WindowObject
;
1352 ReleaseSemaphore(&TaskLock
);
1357 static PI
*FindPrefInfo(TM
*tm
, ULONG id
)
1359 PRL
*pl
= &tm
->tm_Prefs
;
1362 for (pi
= pl
->pl_First
; pi
->pi_Next
; pi
= pi
->pi_Next
)
1364 if (id
== pi
->pi_PrefID
)
1372 #define TAG_PREFID (TAG_USER - 1)
1374 static void NewPrefInfo(TM
*tm
, ULONG id
, struct TagItem
*tags
)
1376 PRL
*pl
= &tm
->tm_Prefs
;
1377 PI
*pi
= FindPrefInfo(tm
, id
);
1381 if ((pi
= AllocVecMem(MemPool
, sizeof(PI
))))
1384 pi
->pi_Defaults
= NULL
;
1385 AddTail((struct List
*)pl
, (struct Node
*)pi
);
1390 tags
= BGUI_MergeTagItems(pi
->pi_Defaults
, tags
);
1391 pi
->pi_Defaults
= BGUI_CleanTagItems(tags
, 1);
1395 static void DefPrefs(void)
1398 struct TagItem
*t1
, *t2
;
1401 static struct TagItem deftags
[] =
1403 { TAG_PREFID
, BGUI_AREA_GADGET
},
1404 { ICA_TARGET
, ICTARGET_IDCMP
},
1405 { FRM_EdgesOnly
, TRUE
},
1407 { TAG_PREFID
, BGUI_BUTTON_GADGET
},
1408 { FRM_Type
, FRTYPE_BUTTON
},
1410 { TAG_PREFID
, BGUI_CHECKBOX_GADGET
},
1411 { LAB_NoPlaceIn
, TRUE
},
1412 { BT_NoRecessed
, TRUE
},
1413 { BUTTON_ScaleMinWidth
, 14 },
1414 { BUTTON_ScaleMinHeight
, 8 },
1416 { TAG_PREFID
, BGUI_CYCLE_GADGET
},
1417 { LAB_NoPlaceIn
, TRUE
},
1418 { FRM_Type
, FRTYPE_BUTTON
},
1420 { TAG_PREFID
, BGUI_GROUP_GADGET
},
1421 { LAB_NoPlaceIn
, TRUE
},
1422 { FRM_DefaultType
, FRTYPE_NEXT
},
1423 { GROUP_DefHSpaceNarrow
, 2 },
1424 { GROUP_DefHSpaceNormal
, 4 },
1425 { GROUP_DefHSpaceWide
, 8 },
1426 { GROUP_DefVSpaceNarrow
, 2 },
1427 { GROUP_DefVSpaceNormal
, 4 },
1428 { GROUP_DefVSpaceWide
, 8 },
1430 { TAG_PREFID
, BGUI_INDICATOR_GADGET
},
1431 { BT_Buffer
, TRUE
},
1432 { FRM_DefaultType
, FRTYPE_BUTTON
},
1433 { FRM_Recessed
, TRUE
},
1435 { TAG_PREFID
, BGUI_INFO_GADGET
},
1436 { LAB_NoPlaceIn
, TRUE
},
1437 { BT_Buffer
, TRUE
},
1438 { FRM_DefaultType
, FRTYPE_BUTTON
},
1439 { FRM_Recessed
, TRUE
},
1441 { TAG_PREFID
, BGUI_LISTVIEW_GADGET
},
1442 { LAB_NoPlaceIn
, TRUE
},
1443 { FRM_Type
, FRTYPE_BUTTON
},
1445 { TAG_PREFID
, BGUI_MX_GADGET
},
1446 { LAB_NoPlaceIn
, TRUE
},
1447 { LAB_Place
, PLACE_ABOVE
},
1448 { MX_Spacing
, GRSPACE_NARROW
},
1449 { MX_LabelPlace
, PLACE_RIGHT
},
1451 { TAG_PREFID
, BGUI_PAGE_GADGET
},
1452 { LAB_NoPlaceIn
, TRUE
},
1453 { FRM_Type
, FRTYPE_NONE
},
1454 { BT_Buffer
, TRUE
},
1456 { TAG_PREFID
, BGUI_PROGRESS_GADGET
},
1457 { LAB_NoPlaceIn
, TRUE
},
1458 { FRM_Type
, FRTYPE_BUTTON
},
1459 { FRM_Recessed
, TRUE
},
1460 { BT_LeftOffset
, 1 },
1461 { BT_RightOffset
, 1 },
1462 { BT_TopOffset
, 1 },
1463 { BT_BottomOffset
, 1 },
1465 { TAG_PREFID
, BGUI_PROP_GADGET
},
1466 { LAB_NoPlaceIn
, TRUE
},
1467 { FRM_Type
, FRTYPE_BUTTON
},
1469 { TAG_PREFID
, BGUI_RADIOBUTTON_GADGET
},
1470 { LAB_NoPlaceIn
, TRUE
},
1471 { FRM_Type
, FRTYPE_RADIOBUTTON
},
1472 { BUTTON_ScaleMinWidth
, 8 },
1473 { BUTTON_ScaleMinHeight
, 8 },
1474 { BUTTON_SelectOnly
, TRUE
},
1476 { TAG_PREFID
, BGUI_SLIDER_GADGET
},
1477 { PGA_Slider
, TRUE
},
1479 { TAG_PREFID
, BGUI_STRING_GADGET
},
1480 { LAB_NoPlaceIn
, TRUE
},
1481 { FRM_Type
, FRTYPE_RIDGE
},
1482 { BT_LeftOffset
, 1 },
1483 { BT_RightOffset
, 1 },
1484 { BT_TopOffset
, 1 },
1485 { BT_BottomOffset
, 1 },
1487 { TAG_PREFID
, BGUI_VIEW_GADGET
},
1488 { LAB_NoPlaceIn
, TRUE
},
1489 { FRM_Type
, FRTYPE_BUTTON
},
1490 { FRM_Recessed
, TRUE
},
1491 { BT_LeftOffset
, 1 },
1492 { BT_RightOffset
, 1 },
1493 { BT_TopOffset
, 1 },
1494 { BT_BottomOffset
, 1 },
1496 { TAG_PREFID
, BGUI_WINDOW_OBJECT
},
1497 { WINDOW_ToolTicks
, 10 },
1498 { WINDOW_PreBufferRP
, FALSE
},
1500 { TAG_PREFID
, BGUI_FILEREQ_OBJECT
},
1501 { ASLREQ_Type
, ASL_FileRequest
},
1503 { TAG_PREFID
, BGUI_FONTREQ_OBJECT
},
1504 { ASLREQ_Type
, ASL_FontRequest
},
1506 { TAG_PREFID
, BGUI_SCREENREQ_OBJECT
},
1507 { ASLREQ_Type
, ASL_ScreenModeRequest
},
1512 ObtainSemaphore(&TaskLock
);
1513 if ((tm
= FindTaskMember()))
1520 while (t2
->ti_Tag
& TAG_USER
) t2
++;
1523 t2
->ti_Tag
= TAG_DONE
;
1525 NewPrefInfo(tm
, id
, t1
);
1529 } while (type
== TAG_PREFID
);
1531 ReleaseSemaphore(&TaskLock
);
1534 static void LoadPrefs(UBYTE
*name
)
1536 struct IFFHandle
*iff
;
1537 struct CollectionItem
*ci
;
1541 if ((tm
= FindTaskMember()))
1543 if ((iff
= AllocIFF()))
1545 if ((iff
->iff_Stream
= (IPTR
)Open((char *)name
, MODE_OLDFILE
)))
1548 if (OpenIFF(iff
, IFFF_READ
) == 0)
1550 CollectionChunk(iff
, ID_BGUI
, ID_DTAG
);
1551 StopOnExit(iff
, ID_BGUI
, ID_FORM
);
1552 ParseIFF(iff
, IFFPARSE_SCAN
);
1554 ci
= FindCollection(iff
, ID_BGUI
, ID_DTAG
);
1559 NewPrefInfo(tm
, type
, (struct TagItem
*)data
);
1564 Close((BPTR
)iff
->iff_Stream
);
1571 makeproto
struct TagItem
*DefTagList(ULONG id
, struct TagItem
*tags
)
1573 struct TagItem
*deftags
, *newtags
, *t
, *tag
;
1574 struct TagItem
*tstate1
, *tstate2
;
1579 if ((deftags
= BGUI_GetDefaultTags(id
)))
1581 tstate1
= deftags
, tstate2
= tags
;
1583 n1
= BGUI_CountTagItems(deftags
);
1584 n2
= BGUI_CountTagItems(tags
);
1586 if ((newtags
= AllocVec((n1
+ n2
+ 1) * sizeof(struct TagItem
), 0)))
1590 while ((tag
= NextTagItem(&tstate1
)))
1592 if (FindTagItem(tag
->ti_Tag
, tags
))
1595 if (tag
->ti_Tag
== FRM_DefaultType
)
1597 fr_deftype
= tag
->ti_Data
;
1603 while ((tag
= NextTagItem(&tstate2
)))
1605 if (fr_deftype
&& (tag
->ti_Tag
== FRM_Type
) && (tag
->ti_Data
== FRTYPE_DEFAULT
))
1607 tag
->ti_Data
= fr_deftype
;
1612 t
->ti_Tag
= TAG_DONE
;
1614 tags
= CloneTagItems(newtags
);
1621 return CloneTagItems(tags
);
1624 makeproto SAVEDS ASM ULONG
BGUI_CountTagItems(REG(a0
) struct TagItem
*tags
)
1626 struct TagItem
*tstate
= tags
;
1629 while (NextTagItem(&tstate
)) n
++;
1634 makeproto SAVEDS ASM
struct TagItem
*BGUI_MergeTagItems(REG(a0
) struct TagItem
*tags1
, REG(a1
) struct TagItem
*tags2
)
1636 struct TagItem
*tags
, *t
, *tag
;
1637 struct TagItem
*tstate1
= tags1
, *tstate2
= tags2
;
1639 int n1
= BGUI_CountTagItems(tags1
);
1640 int n2
= BGUI_CountTagItems(tags2
);
1642 if ((tags
= AllocVec((n1
+ n2
+ 1) * sizeof(struct TagItem
), 0)))
1646 while ((tag
= NextTagItem(&tstate1
))) *t
++ = *tag
;
1647 while ((tag
= NextTagItem(&tstate2
))) *t
++ = *tag
;
1648 t
->ti_Tag
= TAG_DONE
;
1650 t
= CloneTagItems(tags
);
1659 makeproto SAVEDS ASM
struct TagItem
*BGUI_CleanTagItems(REG(a0
) struct TagItem
*tags
, REG(d0
) LONG dir
)
1661 struct TagItem
*tag
, *tag2
;
1662 struct TagItem
*tstate
= tags
;
1666 while ((tag
= NextTagItem(&tstate
)))
1668 while ((tag2
= FindTagItem(tag
->ti_Tag
, tag
+ 1)))
1672 tag
->ti_Tag
= TAG_IGNORE
;
1677 tag2
->ti_Tag
= TAG_IGNORE
;
1682 tag
= CloneTagItems(tags
);
1689 AROS_LH1(struct TagItem
*, BGUI_GetDefaultTags
,
1690 AROS_LHA(ULONG
, id
, D0
),
1691 struct Library
*, BGUIBase
, 28, BGUI
)
1693 makeproto SAVEDS ASM
struct TagItem
*BGUI_GetDefaultTags(REG(d0
) ULONG id
)
1700 struct TagItem
*tags
= NULL
;
1705 ObtainSemaphore(&TaskLock
);
1707 if ((tm
= FindTaskMember()))
1709 if ((pi
= FindPrefInfo(tm
, id
)))
1710 tags
= pi
->pi_Defaults
;
1716 ReleaseSemaphore(&TaskLock
);
1725 AROS_LH0(VOID
, BGUI_DefaultPrefs
,
1726 struct Library
*, BGUIBase
, 29, BGUI
)
1728 makeproto SAVEDS ASM VOID
BGUI_DefaultPrefs(VOID
)
1736 ObtainSemaphore(&TaskLock
);
1737 if ((tm
= FindTaskMember()))
1739 while ((pi
= (PI
*)RemHead((struct List
*)&tm
->tm_Prefs
)))
1742 ReleaseSemaphore(&TaskLock
);
1751 AROS_LH1(VOID
, BGUI_LoadPrefs
,
1752 AROS_LHA(UBYTE
*, name
, A0
),
1753 struct Library
*, BGUIBase
, 30, BGUI
)
1755 makeproto SAVEDS ASM VOID
BGUI_LoadPrefs(REG(a0
) UBYTE
*name
)
1760 BGUI_DefaultPrefs();