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/
21 ***************************************************************************/
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>
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))
68 #ifndef POINTERA_Width
69 #define POINTERA_Width (POINTERA_Dummy + 0x08) // <= 64
71 #ifndef POINTERA_Height
72 #define POINTERA_Height (POINTERA_Dummy + 0x09) // <= 64
74 #ifndef WA_PointerType
75 #define WA_PointerType (WA_Dummy + 0x50)
77 #ifndef POINTERTYPE_TEXT
78 #define POINTERTYPE_TEXT 30
83 static const UWORD selectPointer
[] =
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
[] =
132 static const UWORD selectPointer_bp1
[] =
152 static const UWORD selectPointer_bp2
[] =
172 static struct BitMap selectPointerBitmap
=
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
182 #ifndef WA_PointerType
183 #define WA_PointerType (WA_Dummy + 164)
187 static void IdentifyPointerColors(Object
*obj
)
198 // get the current screen's pointer colors (17 to 19)
199 GetRGB32(_window(obj
)->WScreen
->ViewPort
.ColorMap
, 17, 3, colors
);
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
228 if(blackDiff
[0] > blackDiff
[1])
230 if(blackDiff
[1] > blackDiff
[2])
235 else if(blackDiff
[0] > blackDiff
[2])
240 // the smallest difference defines the color which is closest to white or
242 if(whiteDiff
[0] > whiteDiff
[1])
244 if(whiteDiff
[1] > whiteDiff
[2])
249 else if(whiteDiff
[0] > whiteDiff
[2])
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.
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)
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
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
;
300 void SetupSelectPointer(struct InstData
*data
)
304 #if defined(__amigaos4__)
305 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase
, 53, 40))
306 data
->PointerObj
= (APTR
)POINTERTYPE_TEXT
;
307 #elif defined(__MORPHOS__)
309 data
->PointerObj
= (APTR
)POINTERTYPE_SELECTTEXT
;
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
,
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
,
340 if((data
->PointerObj
= (Object
*)AllocVec(sizeof(selectPointer
), MEMF_CHIP
|MEMF_PUBLIC
)) != NULL
)
341 memcpy(data
->PointerObj
, selectPointer
, sizeof(selectPointer
));
346 data
->activeSelectPointer
= FALSE
;
351 void CleanupSelectPointer(struct InstData
*data
)
355 #if defined(__amigaos4__)
356 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase
, 53, 40))
357 data
->PointerObj
= NULL
;
358 #elif defined(__MORPHOS__)
360 data
->PointerObj
= NULL
;
363 if(data
->PointerObj
!= NULL
)
366 if(data
->activeSelectPointer
== TRUE
)
367 E(DBF_ALWAYS
, "pointer was still active upon MUIM_Cleanup!!");
370 #if defined(__amigaos4__) || defined(__MORPHOS__)
371 DisposeObject(data
->PointerObj
);
373 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase
, 39, 0))
375 DisposeObject(data
->PointerObj
);
379 FreeVec(data
->PointerObj
);
383 data
->PointerObj
= NULL
;
389 void ShowSelectPointer(Object
*obj
, struct InstData
*data
)
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
);
419 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase
, 39, 0))
420 SetWindowPointer(_window(obj
), WA_Pointer
, data
->PointerObj
, TAG_DONE
);
422 SetPointer(_window(obj
), (APTR
)data
->PointerObj
, selectPointerHeight
,
424 selectPointerXOffset
,
425 selectPointerYOffset
);
428 data
->activeSelectPointer
= TRUE
;
434 void HideSelectPointer(Object
*obj
, struct InstData
*data
)
438 if(data
->activeSelectPointer
== TRUE
&&
439 data
->PointerObj
!= NULL
)
441 #if defined(__amigaos4__) || defined(__MORPHOS__) || defined(__AROS__)
442 SetWindowPointer(_window(obj
), TAG_DONE
);
444 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase
, 39, 0))
445 SetWindowPointer(_window(obj
), TAG_DONE
);
447 ClearPointer(_window(obj
));
450 data
->activeSelectPointer
= FALSE
;