2 Copyright © 1995-2001, 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 = allocted pen number, -1 for failure
51 Shared palette entries should not be changed (via SetRGB??())
52 since other aapplications might use the same color.
53 A PaletteExtra structure must have been attached to the
54 ColorMap prior to calling this function (AttachPalExtra()).
66 *****************************************************************************/
69 AROS_LIBBASE_EXT_DECL(struct GfxBase
*,GfxBase
)
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
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
))
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 */
102 if ((PalExtra_AllocList_Type
)-1 == PALEXTRA_ALLOCLIST(pe
, n
))
103 pe
->pe_FirstFree
= (UWORD
)-1;
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) */
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 */
125 PALEXTRA_ALLOCLIST(pe
, index
) = PALEXTRA_ALLOCLIST(pe
, n
);
126 PALEXTRA_ALLOCLIST(pe
, n
) = (PalExtra_AllocList_Type
)-1;
131 index
= PALEXTRA_ALLOCLIST(pe
, index
);
135 } /* (pe->pe_FirstFree != n) */
137 } /* if (EXCLUSIVE access) */
140 /* SHARED ACCESS to pen */
142 the pen could already be shared or it can still be in
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
)++;
161 } /* if PALEXTRA_REFCNT(pe, n) != 0) */
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 */
173 if ((PalExtra_AllocList_Type
)-1 == PALEXTRA_ALLOCLIST(pe
, n
))
174 pe
->pe_FirstFree
= (UWORD
)-1;
176 pe
->pe_FirstFree
= (UWORD
)PALEXTRA_ALLOCLIST(pe
, n
);
177 /* mark that entry as shared */
179 } /* if (pe->pe_FirstFree == n) */
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 */
194 PALEXTRA_ALLOCLIST(pe
, index
) = PALEXTRA_ALLOCLIST(pe
, n
);
199 index
= PALEXTRA_ALLOCLIST(pe
, index
);
203 } /* (pe->pe_FirstFree != n) */
207 PALEXTRA_ALLOCLIST(pe
, n
) = (PalExtra_AllocList_Type
)pe
->pe_FirstShared
;
208 pe
->pe_FirstShared
= n
;
211 PALEXTRA_REFCNT(pe
, n
) = 1;
214 } /* (PALEXTRA_REFCNT(pe, n) == 0) */
216 } /* shared access */
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
232 if (0 != pe
->pe_NFree
)
234 retval
= pe
->pe_FirstFree
;
236 if (0 == pe
->pe_NFree
)
237 pe
->pe_FirstFree
= (UWORD
)-1;
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)) */
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
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 */
262 PALEXTRA_REFCNT(pe
, retval
)++;
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
;
276 if (0 == pe
->pe_NFree
)
277 pe
->pe_FirstFree
= (UWORD
)-1;
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;
287 } /* shared access */
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 */
299 SetRGB32(pe
->pe_ViewPort
, retval
, r
, g
, b
);
301 SetRGB32CM(cm
, retval
, r
, g
, b
);
305 ReleaseSemaphore(&pe
->pe_Semaphore
);