Set ERROR_NO_FREE_STORE upon failure if called from a process (this is
[tangerine.git] / rom / graphics / releasepen.c
blob49508cb29cb5d6aa45c7b29195c203a01aa68155
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Release a pen previously allocated.
6 Lang: english
7 */
8 #include "graphics_intern.h"
9 #include <graphics/view.h>
10 #ifdef DEBUG
11 #undef DEBUG
12 #endif
13 #define DEBUG 0
14 #include <aros/debug.h>
16 /*****************************************************************************
18 NAME */
19 #include <clib/graphics_protos.h>
21 AROS_LH2(void, ReleasePen,
23 /* SYNOPSIS */
24 AROS_LHA(struct ColorMap *, cm, A0),
25 AROS_LHA(ULONG , n , D0),
27 /* LOCATION */
28 struct GfxBase *, GfxBase, 158, Graphics)
30 /* FUNCTION
31 Release a pen that was previously allocated as an exclusive
32 or shared pen by the application. Any other application can
33 then obtain this pen and make changes to the color register
34 entries.
37 INPUTS
38 cm - ColorMap structure where the pen was allocated
39 n - The number of the pen
41 RESULT
42 An exclusive pen is deallocated for other applications to use.
43 A shared pen is only completely deallocated if no other
44 application is using it anymore.
46 NOTES
48 EXAMPLE
50 BUGS
52 SEE ALSO
54 INTERNALS
56 HISTORY
58 *****************************************************************************/
60 AROS_LIBFUNC_INIT
62 if (NULL != cm && n < cm->Count)
64 struct PaletteExtra * pe = cm->PalExtra;
65 PalExtra_AllocList_Type index;
67 ObtainSemaphore(&pe->pe_Semaphore);
68 /* First I check whether this pen is somewhere in the
69 free list already...
72 index = pe->pe_FirstFree;
73 while ((PalExtra_AllocList_Type)-1 != index)
75 if (index == (PalExtra_AllocList_Type)n)
76 goto exit;
78 index = PALEXTRA_ALLOCLIST(pe, index);
82 ** It is not in the free list.
83 ** If it is a shared pen, then I can recognize this
84 ** by its value in the RefCnt
87 if (0 != PALEXTRA_REFCNT(pe,n))
89 /*
90 ** A SHARED pen
92 PALEXTRA_REFCNT(pe, n)--;
93 if (0 == PALEXTRA_REFCNT(pe, n))
95 BOOL found = FALSE;
96 /*
97 ** I can take this out if the list of shared pens
98 ** since this was the last application that used
99 ** this pen.
101 index = pe->pe_FirstShared;
102 if ((PalExtra_AllocList_Type)n == index)
104 found = TRUE;
106 ** it's the very first one.
109 ** Take it out of the list of entries in
110 ** the shared list...
112 if ((PalExtra_AllocList_Type)-1 == PALEXTRA_ALLOCLIST(pe,n))
113 pe->pe_FirstShared = (WORD)-1;
114 else
115 pe->pe_FirstShared = (WORD)PALEXTRA_ALLOCLIST(pe,n);
117 pe->pe_NShared--;
120 ** ... and make it available in the list of free
121 ** entries.
123 PALEXTRA_ALLOCLIST(pe,n) = (PalExtra_AllocList_Type)pe->pe_FirstFree;
124 pe->pe_FirstFree = n;
125 pe->pe_NFree++;
127 else
131 if ((PalExtra_AllocList_Type)n == PALEXTRA_ALLOCLIST(pe, index))
133 found = TRUE;
136 ** Take it out of the list of shared entries
138 PALEXTRA_ALLOCLIST(pe, index) = PALEXTRA_ALLOCLIST(pe, n);
139 pe->pe_NShared--;
142 ** ... and make it available in the list of free
143 ** entries.
145 PALEXTRA_ALLOCLIST(pe, n) = (PalExtra_AllocList_Type)pe->pe_FirstFree;
146 pe->pe_FirstFree = n;
147 pe->pe_NFree++;
148 break;
150 else
151 index = PALEXTRA_ALLOCLIST(pe, index);
153 while ((PalExtra_AllocList_Type)-1 != index);
156 #if DEBUG
157 if (!found)
158 D(bug("Error in ReleasePen() pen = %d!\n",n));
159 #endif
161 } /* if (no further app needs this pen) */
163 } /* if (0 != PALEXTRA_REFCNT(pe,n)) */
164 else
166 /* releasing an EXCLUSIVE pen */
167 D(bug("Releasing (exclusive) pen %d\n"));
169 PALEXTRA_ALLOCLIST(pe, n) = pe->pe_FirstFree;
170 pe->pe_FirstFree = n;
171 pe->pe_NFree++;
173 exit:
174 ReleaseSemaphore(&pe->pe_Semaphore);
176 } /* if (NULL != cm && n < cm->Count) */
178 AROS_LIBFUNC_EXIT
180 } /* ReleasePen */