2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
5 Desc: Obtain a certain pen
8 #include "graphics_intern.h"
9 #include <graphics/view.h>
11 /*****************************************************************************
14 #include <proto/graphics.h>
16 AROS_LH6(LONG
, ObtainPen
,
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
),
27 struct GfxBase
*, GfxBase
, 159, Graphics
)
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.
35 cm - A pointer to a color map structure
36 n - index of the entry in the color map; if any entry is fine
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
48 n = allocated pen number, -1 for failure
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()).
66 *****************************************************************************/
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
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
))
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 */
101 if ((PalExtra_AllocList_Type
)-1 == PALEXTRA_ALLOCLIST(pe
, n
))
102 pe
->pe_FirstFree
= (UWORD
)-1;
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) */
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 */
124 PALEXTRA_ALLOCLIST(pe
, index
) = PALEXTRA_ALLOCLIST(pe
, n
);
125 PALEXTRA_ALLOCLIST(pe
, n
) = (PalExtra_AllocList_Type
)-1;
130 index
= PALEXTRA_ALLOCLIST(pe
, index
);
134 } /* (pe->pe_FirstFree != n) */
136 } /* if (EXCLUSIVE access) */
139 /* SHARED ACCESS to pen */
141 the pen could already be shared or it can still be in
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
)++;
160 } /* if PALEXTRA_REFCNT(pe, n) != 0) */
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 */
172 if ((PalExtra_AllocList_Type
)-1 == PALEXTRA_ALLOCLIST(pe
, n
))
173 pe
->pe_FirstFree
= (UWORD
)-1;
175 pe
->pe_FirstFree
= (UWORD
)PALEXTRA_ALLOCLIST(pe
, n
);
176 /* mark that entry as shared */
178 } /* if (pe->pe_FirstFree == n) */
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 */
193 PALEXTRA_ALLOCLIST(pe
, index
) = PALEXTRA_ALLOCLIST(pe
, n
);
198 index
= PALEXTRA_ALLOCLIST(pe
, index
);
202 } /* (pe->pe_FirstFree != n) */
206 PALEXTRA_ALLOCLIST(pe
, n
) = (PalExtra_AllocList_Type
)pe
->pe_FirstShared
;
207 pe
->pe_FirstShared
= n
;
210 PALEXTRA_REFCNT(pe
, n
) = 1;
213 } /* (PALEXTRA_REFCNT(pe, n) == 0) */
215 } /* shared access */
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
231 if (0 != pe
->pe_NFree
)
233 retval
= pe
->pe_FirstFree
;
235 if (0 == pe
->pe_NFree
)
236 pe
->pe_FirstFree
= (UWORD
)-1;
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)) */
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
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 */
261 PALEXTRA_REFCNT(pe
, retval
)++;
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
;
275 if (0 == pe
->pe_NFree
)
276 pe
->pe_FirstFree
= (UWORD
)-1;
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;
286 } /* shared access */
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 */
298 SetRGB32(pe
->pe_ViewPort
, retval
, r
, g
, b
);
300 SetRGB32CM(cm
, retval
, r
, g
, b
);
304 ReleaseSemaphore(&pe
->pe_Semaphore
);