Removed obsolete (and apparently unneeded) AM_C_PROTOTYPES line, which
[AROS.git] / rom / graphics / obtainpen.c
blob4b77fff9aa8a567c589996f9c6c38a1ee96a23ea
1 /*
2 Copyright © 1995-2007, 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
70 LONG retval = -1;
71 PalExtra_AllocList_Type index;
72 BOOL was_shared = FALSE;
74 Change the calculation of the color if the entries
75 in the colortable attached to the colormap structure
76 are changed
78 struct PaletteExtra * pe = cm->PalExtra;
80 ObtainSemaphore(&pe->pe_Semaphore);
82 /* pe_SharableColors is not the number of colors but the last color index! */
84 if (NULL != pe && (n <= pe->pe_SharableColors || -1 == n ))
86 if (-1 != n)
88 /* A specific color map entry is requested */
89 /* Does the user want shared or exclusive access ? */
91 if (0 != (flags & PENF_EXCLUSIVE))
93 /* EXCLUSIVE ACCESS to pen */
94 if (pe->pe_FirstFree == n)
96 /* it is the very first one of available pens */
97 retval = n;
99 pe->pe_NFree--;
101 if ((PalExtra_AllocList_Type)-1 == PALEXTRA_ALLOCLIST(pe, n))
102 pe->pe_FirstFree = (UWORD)-1;
103 else
104 pe->pe_FirstFree = PALEXTRA_ALLOCLIST(pe, n);
106 /* mark that entry as used */
107 PALEXTRA_ALLOCLIST(pe, n) = (PalExtra_AllocList_Type)-1;
109 } /* if (pe->pe_FirstFree == n) */
110 else
113 walk through the list of free entries and see whether
114 the requested one is still available.
116 index = (PalExtra_AllocList_Type)pe->pe_FirstFree;
118 while ((PalExtra_AllocList_Type)-1 != index)
120 if (n == PALEXTRA_ALLOCLIST(pe, index))
122 /* it's still free! So I allocate it */
123 retval = n;
124 PALEXTRA_ALLOCLIST(pe, index) = PALEXTRA_ALLOCLIST(pe, n);
125 PALEXTRA_ALLOCLIST(pe, n) = (PalExtra_AllocList_Type)-1;
126 pe->pe_NFree--;
127 break;
129 else
130 index = PALEXTRA_ALLOCLIST(pe, index);
132 } /* while */
134 } /* (pe->pe_FirstFree != n) */
136 } /* if (EXCLUSIVE access) */
137 else
139 /* SHARED ACCESS to pen */
141 the pen could already be shared or it can still be in
142 the free list.
143 I recognize that a pen is already shared by its entry
144 in pe_RefCnt being != 0.
146 if (PALEXTRA_REFCNT(pe, n) != 0)
149 this one is already in shared mode, so test
150 whether the color is the same.
151 ??? Is this necessary for a shared pen?
153 if (color_equal(cm,r,g,b,n))
155 /* increase the RefCnt */
156 PALEXTRA_REFCNT(pe, n)++;
157 was_shared = TRUE;
158 retval = n;
160 } /* if PALEXTRA_REFCNT(pe, n) != 0) */
161 else
164 ** The RefCnt is 0, so the pen is probably still in the
165 ** free list unless it is an exclusive pen.
167 if (pe->pe_FirstFree == n)
169 /* it is the very first one of available pens */
170 retval = n;
172 if ((PalExtra_AllocList_Type)-1 == PALEXTRA_ALLOCLIST(pe, n))
173 pe->pe_FirstFree = (UWORD)-1;
174 else
175 pe->pe_FirstFree = (UWORD)PALEXTRA_ALLOCLIST(pe, n);
176 /* mark that entry as shared */
178 } /* if (pe->pe_FirstFree == n) */
179 else
182 walk through the list of free entries and see whether
183 the requested one is still available
185 index = (PalExtra_AllocList_Type)pe->pe_FirstFree;
187 while ((PalExtra_AllocList_Type)-1 != index)
189 if ((PalExtra_AllocList_Type)n == PALEXTRA_ALLOCLIST(pe, index))
191 /* it's still free! So I allocate it */
192 retval = n;
193 PALEXTRA_ALLOCLIST(pe, index) = PALEXTRA_ALLOCLIST(pe, n);
195 break;
197 else
198 index = PALEXTRA_ALLOCLIST(pe, index);
200 } /* while */
202 } /* (pe->pe_FirstFree != n) */
204 if (-1 != retval)
206 PALEXTRA_ALLOCLIST(pe, n) = (PalExtra_AllocList_Type)pe->pe_FirstShared;
207 pe->pe_FirstShared = n;
208 pe->pe_NFree--;
209 pe->pe_NShared++;
210 PALEXTRA_REFCNT(pe, n) = 1;
213 } /* (PALEXTRA_REFCNT(pe, n) == 0) */
215 } /* shared access */
217 } /* n != -1 */
218 else
220 /* Any entry in the color table is fine */
222 /* Does the user want shared or exclusive access ? */
223 if (0 != (flags & PENF_EXCLUSIVE))
225 /* EXCLUSIVE ACCESS to pen */
227 ** Search for the very first entry that I can
228 ** give exclusive access to, if there are still
229 ** entries free
231 if (0 != pe->pe_NFree)
233 retval = pe->pe_FirstFree;
234 pe->pe_NFree--;
235 if (0 == pe->pe_NFree)
236 pe->pe_FirstFree = (UWORD)-1;
237 else
238 pe->pe_FirstFree = (UWORD)PALEXTRA_ALLOCLIST(pe, retval);
239 PALEXTRA_ALLOCLIST(pe, retval) = (PalExtra_AllocList_Type)-1;
240 PALEXTRA_REFCNT(pe, retval) = 0;
243 } /* if (0 != (flags & PENF_EXCLUSIVE)) */
244 else
246 /* SHARED ACCESS */
248 ** Search for the very first entry that I can give
249 ** shared access to. First search the list of shared
250 ** colors and look for matching colors and if nothing can
251 ** be found there then take an entry out of the
252 ** free list.
254 index = (PalExtra_AllocList_Type)pe->pe_FirstShared;
255 while ((PalExtra_AllocList_Type)-1 != index)
257 if (color_equal(cm,r,g,b,index))
259 /* That's a good one */
260 retval = index;
261 PALEXTRA_REFCNT(pe, retval)++;
262 was_shared = TRUE;
263 break;
265 index = PALEXTRA_ALLOCLIST(pe, index);
269 ** If nothing was found take an entry from the free list
271 if (-1 == retval && 0 != pe->pe_NFree)
273 retval = pe->pe_FirstFree;
274 pe->pe_NFree--;
275 if (0 == pe->pe_NFree)
276 pe->pe_FirstFree = (UWORD)-1;
277 else
278 pe->pe_FirstFree = (UWORD)PALEXTRA_ALLOCLIST(pe, retval);
280 PALEXTRA_ALLOCLIST(pe, retval) = (PalExtra_AllocList_Type)pe->pe_FirstShared;
281 pe->pe_FirstShared = retval;
282 PALEXTRA_REFCNT(pe, retval) = 1;
283 pe->pe_NShared++;
286 } /* shared access */
288 } /* n = -1 */
290 } /* if (NULL != pe && (n <= pe->pe_SharableColors || -1 == n )) */
292 if (-1 != retval && 0 == (flags & PENF_NO_SETCOLOR) && !was_shared)
294 /* Change the rgb values for the selected pen */
296 if (pe->pe_ViewPort)
298 SetRGB32(pe->pe_ViewPort, retval, r, g, b);
299 } else {
300 SetRGB32CM(cm, retval, r, g, b);
304 ReleaseSemaphore(&pe->pe_Semaphore);
306 return retval;
308 AROS_LIBFUNC_EXIT
309 } /* ObtainPen */