grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / classes / zune / betterstring / mcc / Pointer.c
blob15cae208eb9fb797d04b247bb0f4d0ce2a9e321e
1 /***************************************************************************
3 BetterString.mcc - A better String gadget MUI Custom Class
4 Copyright (C) 1997-2000 Allan Odgaard
5 Copyright (C) 2005-2013 by BetterString.mcc Open Source Team
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 BetterString class Support Site: http://www.sf.net/projects/bstring-mcc/
19 $Id$
21 ***************************************************************************/
23 #include <string.h>
25 #include <clib/alib_protos.h>
27 #include <intuition/pointerclass.h>
29 #include <proto/utility.h>
30 #include <proto/intuition.h>
31 #include <proto/exec.h>
32 #include <proto/graphics.h>
34 #include "private.h"
36 // the meta data of the pointer image/data
37 #define selectPointerWidth 7
38 #define selectPointerHeight 16
39 #define selectPointerXOffset -3
40 #define selectPointerYOffset -8
42 #if defined(__amigaos4__)
43 // a 32bit ARGB pointer image where we can define every color of the pixels
44 // on our own and put an alpha-channel information in it as well.
45 static const ULONG selectPointer[] =
47 0xff6d6d6d, 0xff000000, 0x00000000, 0x00000000, 0xffbbbbbb, 0xff6d6d6d, 0xff000000, // +# :+#
48 0x00000000, 0xffbbbbbb, 0xff000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, // :#:#
49 0x00000000, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
50 0x00000000, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
51 0x00000000, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
52 0x00000000, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
53 0x00000000, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
54 0x00000000, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
55 0x00000000, 0xffbbbbbb, 0xff000000, 0xff000000, 0xff000000, 0x00000000, 0x00000000, // :###
56 0x00000000, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
57 0x00000000, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
58 0x00000000, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
59 0x00000000, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
60 0x00000000, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
61 0x00000000, 0xffbbbbbb, 0xff000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, // :#:#
62 0xff6d6d6d, 0xff000000, 0x00000000, 0x00000000, 0xffbbbbbb, 0xff6d6d6d, 0xff000000, // +# :+#
65 #ifndef POINTERA_ImageData
66 #define POINTERA_ImageData (POINTERA_Dummy + 0x07) // ARGB (width * height * sizeof(ULONG))
67 #endif
68 #ifndef POINTERA_Width
69 #define POINTERA_Width (POINTERA_Dummy + 0x08) // <= 64
70 #endif
71 #ifndef POINTERA_Height
72 #define POINTERA_Height (POINTERA_Dummy + 0x09) // <= 64
73 #endif
74 #ifndef WA_PointerType
75 #define WA_PointerType (WA_Dummy + 0x50)
76 #endif
77 #ifndef POINTERTYPE_TEXT
78 #define POINTERTYPE_TEXT 30
79 #endif
81 #else // __amigaos4__
83 static const UWORD selectPointer[] =
85 //plane1 plane2
86 0x0000, 0x0000,
88 0x8800, 0x4600,
89 0x5000, 0x2800,
90 0x2000, 0x1000,
91 0x2000, 0x1000,
92 0x2000, 0x1000,
93 0x2000, 0x1000,
94 0x2000, 0x1000,
95 0x2000, 0x1000,
96 0x4000, 0x3800,
97 0x2000, 0x1000,
98 0x2000, 0x1000,
99 0x2000, 0x1000,
100 0x2000, 0x1000,
101 0x2000, 0x1000,
102 0x5000, 0x2800,
103 0x8800, 0x4600,
105 0x0000, 0x0000
108 #endif // __amigaos4__
110 // Classic bitmap data for the pointer. These will be used for OS4 aswell,
111 // if the graphic card cannot handle 32bit pointers.
112 static const UWORD selectPointer_bp0[] =
114 0x8800, // #...#..
115 0x5000, // .#.#...
116 0x2000, // ..#....
117 0x2000, // ..#....
118 0x2000, // ..#....
119 0x2000, // ..#....
120 0x2000, // ..#....
121 0x2000, // ..#....
122 0x4000, // .#.....
123 0x2000, // ..#....
124 0x2000, // ..#....
125 0x2000, // ..#....
126 0x2000, // ..#....
127 0x2000, // ..#....
128 0x5000, // .#.#...
129 0x8800, // #...#..
132 static const UWORD selectPointer_bp1[] =
134 0x4600, // .#...##
135 0x2800, // ..#.#..
136 0x1000, // ...#...
137 0x1000, // ...#...
138 0x1000, // ...#...
139 0x1000, // ...#...
140 0x1000, // ...#...
141 0x1000, // ...#...
142 0x3800, // ..###..
143 0x1000, // ...#...
144 0x1000, // ...#...
145 0x1000, // ...#...
146 0x1000, // ...#...
147 0x1000, // ...#...
148 0x2800, // ..#.#..
149 0x4600, // .#...##
152 static const UWORD selectPointer_bp2[] =
154 0xce00, // %#..%##
155 0x7800, // .%#%#..
156 0x3000, // ..%#...
157 0x3000, // ..%#...
158 0x3000, // ..%#...
159 0x3000, // ..%#...
160 0x3000, // ..%#...
161 0x3000, // ..%#...
162 0x7800, // .%%%#..
163 0x3000, // ..%#...
164 0x3000, // ..%#...
165 0x3000, // ..%#...
166 0x3000, // ..%#...
167 0x3000, // ..%#...
168 0x7800, // .%#%#..
169 0xce00, // %#..%##
172 static struct BitMap selectPointerBitmap =
174 2, 16, 0, 2, 0,
175 { (PLANEPTR)selectPointer_bp0, (PLANEPTR)selectPointer_bp1, NULL, NULL, NULL, NULL, NULL }
178 #if defined(__MORPHOS__)
179 #ifndef POINTERTYPE_SELECTTEXT
180 #define POINTERTYPE_SELECTTEXT 7
181 #endif
182 #ifndef WA_PointerType
183 #define WA_PointerType (WA_Dummy + 164)
184 #endif
185 #endif
187 static void IdentifyPointerColors(Object *obj)
189 int i;
190 ULONG colors[3*3];
191 LONG blackDiff[3];
192 LONG whiteDiff[3];
193 LONG blackIndex;
194 LONG whiteIndex;
196 ENTER();
198 // get the current screen's pointer colors (17 to 19)
199 GetRGB32(_window(obj)->WScreen->ViewPort.ColorMap, 17, 3, colors);
201 for(i=0; i < 3; i++)
203 LONG dr;
204 LONG dg;
205 LONG db;
207 // normalize the colors to 8 bit per gun as GetRGB32() returns
208 // 32bit left aligned values
209 colors[i*3+0] >>= 24;
210 colors[i*3+1] >>= 24;
211 colors[i*3+2] >>= 24;
213 // calculate the geometric difference to the color black (=0x00000000)
214 dr = 0x00000000 - colors[i*3+0];
215 dg = 0x00000000 - colors[i*3+1];
216 db = 0x00000000 - colors[i*3+2];
217 blackDiff[i] = dr * dr + dg * dg + db * db;
219 // calculate the geometric difference to the color white (=0x000000ff)
220 dr = 0x000000ff - colors[i*3+0];
221 dg = 0x000000ff - colors[i*3+1];
222 db = 0x000000ff - colors[i*3+2];
223 whiteDiff[i] = dr * dr + dg * dg + db * db;
226 // the smallest difference defines the color which is closest to black or
227 // equal to black
228 if(blackDiff[0] > blackDiff[1])
230 if(blackDiff[1] > blackDiff[2])
231 blackIndex = 19;
232 else
233 blackIndex = 18;
235 else if(blackDiff[0] > blackDiff[2])
236 blackIndex = 19;
237 else
238 blackIndex = 17;
240 // the smallest difference defines the color which is closest to white or
241 // equal to white
242 if(whiteDiff[0] > whiteDiff[1])
244 if(whiteDiff[1] > whiteDiff[2])
245 whiteIndex = 19;
246 else
247 whiteIndex = 18;
249 else if(whiteDiff[0] > whiteDiff[2])
250 whiteIndex = 19;
251 else
252 whiteIndex = 17;
254 // Here we expect the user to have set up quite "different" colors. That
255 // means the color closest to white will never be close to black and vice
256 // versa. According to these differences we spread the required bitplanes.
257 if(whiteIndex == 17)
259 if(blackIndex == 18)
261 selectPointerBitmap.Planes[0] = (PLANEPTR)selectPointer_bp0;
262 selectPointerBitmap.Planes[1] = (PLANEPTR)selectPointer_bp1;
264 else // blackIndex == 19
266 selectPointerBitmap.Planes[0] = (PLANEPTR)selectPointer_bp2;
267 selectPointerBitmap.Planes[1] = (PLANEPTR)selectPointer_bp1;
270 else if(whiteIndex == 18)
272 if(blackIndex == 17)
274 selectPointerBitmap.Planes[0] = (PLANEPTR)selectPointer_bp1;
275 selectPointerBitmap.Planes[1] = (PLANEPTR)selectPointer_bp0;
277 else // blackIndex == 19
279 selectPointerBitmap.Planes[0] = (PLANEPTR)selectPointer_bp1;
280 selectPointerBitmap.Planes[1] = (PLANEPTR)selectPointer_bp2;
283 else // whiteIndex == 19
285 if(blackIndex == 17)
287 selectPointerBitmap.Planes[0] = (PLANEPTR)selectPointer_bp2;
288 selectPointerBitmap.Planes[1] = (PLANEPTR)selectPointer_bp0;
290 else // blackIndex == 18
292 selectPointerBitmap.Planes[0] = (PLANEPTR)selectPointer_bp0;
293 selectPointerBitmap.Planes[1] = (PLANEPTR)selectPointer_bp2;
297 LEAVE();
300 void SetupSelectPointer(struct InstData *data)
302 ENTER();
304 #if defined(__amigaos4__)
305 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase, 53, 40))
306 data->PointerObj = (APTR)POINTERTYPE_TEXT;
307 #elif defined(__MORPHOS__)
308 if(IS_MORPHOS2)
309 data->PointerObj = (APTR)POINTERTYPE_SELECTTEXT;
310 #endif
312 if(data->PointerObj == NULL)
314 #if defined(__amigaos4__)
315 data->PointerObj = (Object *)NewObject(NULL, "pointerclass",
316 POINTERA_ImageData, selectPointer,
317 POINTERA_Width, selectPointerWidth,
318 POINTERA_Height, selectPointerHeight,
319 POINTERA_BitMap, &selectPointerBitmap,
320 POINTERA_WordWidth, (ULONG)1,
321 POINTERA_XResolution, (ULONG)POINTERXRESN_SCREENRES,
322 POINTERA_YResolution, (ULONG)POINTERYRESN_SCREENRESASPECT,
323 POINTERA_XOffset, (LONG)selectPointerXOffset,
324 POINTERA_YOffset, (LONG)selectPointerYOffset,
325 TAG_DONE);
326 #else
327 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase, 39, 0))
329 data->PointerObj = (Object *)NewObject(NULL, (STRPTR)"pointerclass",
330 POINTERA_BitMap, (SIPTR)&selectPointerBitmap,
331 POINTERA_WordWidth, (ULONG)1,
332 POINTERA_XResolution, (ULONG)POINTERXRESN_SCREENRES,
333 POINTERA_YResolution, (ULONG)POINTERYRESN_SCREENRESASPECT,
334 POINTERA_XOffset, (LONG)selectPointerXOffset,
335 POINTERA_YOffset, (LONG)selectPointerYOffset,
336 TAG_DONE);
338 else
340 if((data->PointerObj = (Object *)AllocVec(sizeof(selectPointer), MEMF_CHIP|MEMF_PUBLIC)) != NULL)
341 memcpy(data->PointerObj, selectPointer, sizeof(selectPointer));
343 #endif
346 data->activeSelectPointer = FALSE;
348 LEAVE();
351 void CleanupSelectPointer(struct InstData *data)
353 ENTER();
355 #if defined(__amigaos4__)
356 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase, 53, 40))
357 data->PointerObj = NULL;
358 #elif defined(__MORPHOS__)
359 if (IS_MORPHOS2)
360 data->PointerObj = NULL;
361 #endif
363 if(data->PointerObj != NULL)
365 #if defined(DEBUG)
366 if(data->activeSelectPointer == TRUE)
367 E(DBF_ALWAYS, "pointer was still active upon MUIM_Cleanup!!");
368 #endif
370 #if defined(__amigaos4__) || defined(__MORPHOS__)
371 DisposeObject(data->PointerObj);
372 #else
373 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase, 39, 0))
375 DisposeObject(data->PointerObj);
377 else
379 FreeVec(data->PointerObj);
381 #endif
383 data->PointerObj = NULL;
386 LEAVE();
389 void ShowSelectPointer(Object *obj, struct InstData *data)
391 ENTER();
393 // even if it seems to be a waste of performance, but
394 // we unfortunately have to always set the window pointer
395 // regardless of the point if it was previously set or not.
396 // This is required as any other gadget or process might
397 // reset the window pointer and as such we would end up
398 // with no custom pointer as well. So we only check the window
399 // sleep status here :(
400 if(data->PointerObj != NULL &&
401 xget(_win(obj), MUIA_Window_Sleep) == FALSE)
403 // try to identify the black/white colors
404 // of the current screen colormap
405 if(data->activeSelectPointer == FALSE)
406 IdentifyPointerColors(obj);
408 // now we set the actual new custom window pointer. Please note
409 // that we can't unfortunately check for data->activeSelectPointer
410 // here because otherwise we might end up with the standard
411 // window pointer when quickly switching pointer TE.mcc
412 #if defined(__amigaos4__)
413 SetWindowPointer(_window(obj), LIB_VERSION_IS_AT_LEAST(IntuitionBase, 53, 40) ? WA_PointerType : WA_Pointer, data->PointerObj, TAG_DONE);
414 #elif defined(__AROS__)
415 SetWindowPointer(_window(obj), WA_Pointer, data->PointerObj, TAG_DONE);
416 #elif defined(__MORPHOS__)
417 SetWindowPointer(_window(obj), IS_MORPHOS2 ? WA_PointerType : WA_Pointer, data->PointerObj, TAG_DONE);
418 #else
419 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase, 39, 0))
420 SetWindowPointer(_window(obj), WA_Pointer, data->PointerObj, TAG_DONE);
421 else
422 SetPointer(_window(obj), (APTR)data->PointerObj, selectPointerHeight,
423 selectPointerWidth,
424 selectPointerXOffset,
425 selectPointerYOffset);
426 #endif
428 data->activeSelectPointer = TRUE;
431 LEAVE();
434 void HideSelectPointer(Object *obj, struct InstData *data)
436 ENTER();
438 if(data->activeSelectPointer == TRUE &&
439 data->PointerObj != NULL)
441 #if defined(__amigaos4__) || defined(__MORPHOS__) || defined(__AROS__)
442 SetWindowPointer(_window(obj), TAG_DONE);
443 #else
444 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase, 39, 0))
445 SetWindowPointer(_window(obj), TAG_DONE);
446 else
447 ClearPointer(_window(obj));
448 #endif
450 data->activeSelectPointer = FALSE;
453 LEAVE();