r4493@vps: verhaegs | 2007-04-19 14:44:00 -0400
[AROS.git] / rom / graphics / obtainpen.c
blob514bde556e6f6492cc890ce6b9affdeb0d9a2998
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Obtain a certain pen
6 Lang: english
7 */
8 #include "graphics_intern.h"
9 #include <graphics/view.h>
11 /*****************************************************************************
13 NAME */
14 #include <proto/graphics.h>
16 AROS_LH6(LONG, ObtainPen,
18 /* SYNOPSIS */
19 AROS_LHA(struct ColorMap *, cm , A0),
20 AROS_LHA(ULONG , n , D0),
21 AROS_LHA(ULONG , r , D1),
22 AROS_LHA(ULONG , g , D2),
23 AROS_LHA(ULONG , b , D3),
24 AROS_LHA(ULONG , flags, D4),
26 /* LOCATION */
27 struct GfxBase *, GfxBase, 159, Graphics)
29 /* FUNCTION
30 Attempt to allocate an entry in the colormap for exclusive
31 or shared use by the application. To deallocate the pen
32 ReleasePen() must be called.
34 INPUTS
35 cm - A pointer to a color map structure
36 n - index of the entry in the color map; if any entry is fine
37 pass -1
38 r - red value (left justified 32 bit fraction)
39 g - green value (left justified 32 bit fraction)
40 b - blue value (left justified 32 bit fraction)
41 flags - PEN_EXCLUSIVE - for exclusive access to a color register;
42 default is shared access
44 PEN_NO_SETCOLOR - will not change the RGB values
45 for the selected pen.
47 RESULT
48 n = allocated pen number, -1 for failure
50 NOTES
51 Shared palette entries should not be changed (via SetRGB??())
52 since other applications might use the same color.
53 A PaletteExtra structure must have been attached to the
54 ColorMap prior to calling this function (AttachPalExtra()).
56 EXAMPLE
58 BUGS
60 SEE ALSO
62 INTERNALS
64 HISTORY
66 *****************************************************************************/
68 AROS_LIBFUNC_INIT
69 AROS_LIBBASE_EXT_DECL(struct GfxBase *,GfxBase)
71 LONG retval = -1;
72 PalExtra_AllocList_Type index;
73 BOOL was_shared = FALSE;
75 Change the calculation of the color if the entries
76 in the colortable attached to the colormap structure
77 are changed
79 struct PaletteExtra * pe = cm->PalExtra;
81 ObtainSemaphore(&pe->pe_Semaphore);
83 /* pe_SharableColors is not the number of colors but the last color index! */
85 if (NULL != pe && (n <= pe->pe_SharableColors || -1 == n ))
87 if (-1 != n)
89 /* A specific color map entry is requested */
90 /* Does the user want shared or exclusive access ? */
92 if (0 != (flags & PENF_EXCLUSIVE))
94 /* EXCLUSIVE ACCESS to pen */
95 if (pe->pe_FirstFree == n)
97 /* it is the very first one of available pens */
98 retval = n;
100 pe->pe_NFree--;
102 if ((PalExtra_AllocList_Type)-1 == PALEXTRA_ALLOCLIST(pe, n))
103 pe->pe_FirstFree = (UWORD)-1;
104 else
105 pe->pe_FirstFree = PALEXTRA_ALLOCLIST(pe, n);
107 /* mark that entry as used */
108 PALEXTRA_ALLOCLIST(pe, n) = (PalExtra_AllocList_Type)-1;
110 } /* if (pe->pe_FirstFree == n) */
111 else
114 walk through the list of free entries and see whether
115 the requested one is still available.
117 index = (PalExtra_AllocList_Type)pe->pe_FirstFree;
119 while ((PalExtra_AllocList_Type)-1 != index)
121 if (n == PALEXTRA_ALLOCLIST(pe, index))
123 /* it's still free! So I allocate it */
124 retval = n;
125 PALEXTRA_ALLOCLIST(pe, index) = PALEXTRA_ALLOCLIST(pe, n);
126 PALEXTRA_ALLOCLIST(pe, n) = (PalExtra_AllocList_Type)-1;
127 pe->pe_NFree--;
128 break;
130 else
131 index = PALEXTRA_ALLOCLIST(pe, index);
133 } /* while */
135 } /* (pe->pe_FirstFree != n) */
137 } /* if (EXCLUSIVE access) */
138 else
140 /* SHARED ACCESS to pen */
142 the pen could already be shared or it can still be in
143 the free list.
144 I recognize that a pen is already shared by its entry
145 in pe_RefCnt being != 0.
147 if (PALEXTRA_REFCNT(pe, n) != 0)
150 this one is already in shared mode, so test
151 whether the color is the same.
152 ??? Is this necessary for a shared pen?
154 if (TRUE == color_equal(cm,r,g,b,n))
156 /* increase the RefCnt */
157 PALEXTRA_REFCNT(pe, n)++;
158 was_shared = TRUE;
159 retval = n;
161 } /* if PALEXTRA_REFCNT(pe, n) != 0) */
162 else
165 ** The RefCnt is 0, so the pen is probably still in the
166 ** free list unless it is an exclusive pen.
168 if (pe->pe_FirstFree == n)
170 /* it is the very first one of available pens */
171 retval = n;
173 if ((PalExtra_AllocList_Type)-1 == PALEXTRA_ALLOCLIST(pe, n))
174 pe->pe_FirstFree = (UWORD)-1;
175 else
176 pe->pe_FirstFree = (UWORD)PALEXTRA_ALLOCLIST(pe, n);
177 /* mark that entry as shared */
179 } /* if (pe->pe_FirstFree == n) */
180 else
183 walk through the list of free entries and see whether
184 the requested one is still available
186 index = (PalExtra_AllocList_Type)pe->pe_FirstFree;
188 while ((PalExtra_AllocList_Type)-1 != index)
190 if ((PalExtra_AllocList_Type)n == PALEXTRA_ALLOCLIST(pe, index))
192 /* it's still free! So I allocate it */
193 retval = n;
194 PALEXTRA_ALLOCLIST(pe, index) = PALEXTRA_ALLOCLIST(pe, n);
196 break;
198 else
199 index = PALEXTRA_ALLOCLIST(pe, index);
201 } /* while */
203 } /* (pe->pe_FirstFree != n) */
205 if (-1 != retval)
207 PALEXTRA_ALLOCLIST(pe, n) = (PalExtra_AllocList_Type)pe->pe_FirstShared;
208 pe->pe_FirstShared = n;
209 pe->pe_NFree--;
210 pe->pe_NShared++;
211 PALEXTRA_REFCNT(pe, n) = 1;
214 } /* (PALEXTRA_REFCNT(pe, n) == 0) */
216 } /* shared access */
218 } /* n != -1 */
219 else
221 /* Any entry in the color table is fine */
223 /* Does the user want shared or exclusive access ? */
224 if (0 != (flags & PENF_EXCLUSIVE))
226 /* EXCLUSIVE ACCESS to pen */
228 ** Search for the very first entry that I can
229 ** give exclusive access to, if there are still
230 ** entries free
232 if (0 != pe->pe_NFree)
234 retval = pe->pe_FirstFree;
235 pe->pe_NFree--;
236 if (0 == pe->pe_NFree)
237 pe->pe_FirstFree = (UWORD)-1;
238 else
239 pe->pe_FirstFree = (UWORD)PALEXTRA_ALLOCLIST(pe, retval);
240 PALEXTRA_ALLOCLIST(pe, retval) = (PalExtra_AllocList_Type)-1;
241 PALEXTRA_REFCNT(pe, retval) = 0;
244 } /* if (0 != (flags & PENF_EXCLUSIVE)) */
245 else
247 /* SHARED ACCESS */
249 ** Search for the very first entry that I can give
250 ** shared access to. First search the list of shared
251 ** colors and look for matching colors and if nothing can
252 ** be found there then take an entry out of the
253 ** free list.
255 index = (PalExtra_AllocList_Type)pe->pe_FirstShared;
256 while ((PalExtra_AllocList_Type)-1 != index)
258 if (TRUE == color_equal(cm,r,g,b,index))
260 /* That's a good one */
261 retval = index;
262 PALEXTRA_REFCNT(pe, retval)++;
263 was_shared = TRUE;
264 break;
266 index = PALEXTRA_ALLOCLIST(pe, index);
270 ** If nothing was found take an entry from the free list
272 if (-1 == retval && 0 != pe->pe_NFree)
274 retval = pe->pe_FirstFree;
275 pe->pe_NFree--;
276 if (0 == pe->pe_NFree)
277 pe->pe_FirstFree = (UWORD)-1;
278 else
279 pe->pe_FirstFree = (UWORD)PALEXTRA_ALLOCLIST(pe, retval);
281 PALEXTRA_ALLOCLIST(pe, retval) = (PalExtra_AllocList_Type)pe->pe_FirstShared;
282 pe->pe_FirstShared = retval;
283 PALEXTRA_REFCNT(pe, retval) = 1;
284 pe->pe_NShared++;
287 } /* shared access */
289 } /* n = -1 */
291 } /* if (NULL != pe && (n <= pe->pe_SharableColors || -1 == n )) */
293 if (-1 != retval && 0 == (flags & PENF_NO_SETCOLOR) && FALSE == was_shared)
295 /* Change the rgb values for the selected pen */
297 if (pe->pe_ViewPort)
299 SetRGB32(pe->pe_ViewPort, retval, r, g, b);
300 } else {
301 SetRGB32CM(cm, retval, r, g, b);
305 ReleaseSemaphore(&pe->pe_Semaphore);
307 return retval;
309 AROS_LIBFUNC_EXIT
310 } /* ObtainPen */