1 /***************************************************************************
3 TextEditor.mcc - Textediting MUI Custom Class
4 Copyright (C) 1997-2000 Allan Odgaard
5 Copyright (C) 2005-2014 TextEditor.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 TextEditor class Support Site: http://www.sf.net/projects/texteditor-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>
37 // the meta data of the pointer image/data
38 #define selectPointerWidth 7
39 #define selectPointerHeight 16
40 #define selectPointerXOffset -3
41 #define selectPointerYOffset -8
43 #if defined(__amigaos4__)
44 // a 32bit ARGB pointer image where we can define every color of the pixels
45 // on our own and put an alpha-channel information in it as well.
46 static const ULONG selectPointer
[] =
48 0xff6d6d6d, 0xff000000, 0x00000000, 0x00000000, 0xffbbbbbb, 0xff6d6d6d, 0xff000000, // +# :+#
49 0x00000000, 0xffbbbbbb, 0xff000000, 0xffbbbbbb, 0xff000000, 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, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
56 0x00000000, 0xffbbbbbb, 0xff000000, 0xff000000, 0xff000000, 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, 0x00000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, 0x00000000, // :#
62 0x00000000, 0xffbbbbbb, 0xff000000, 0xffbbbbbb, 0xff000000, 0x00000000, 0x00000000, // :#:#
63 0xff6d6d6d, 0xff000000, 0x00000000, 0x00000000, 0xffbbbbbb, 0xff6d6d6d, 0xff000000, // +# :+#
66 #ifndef POINTERA_ImageData
67 #define POINTERA_ImageData (POINTERA_Dummy + 0x07) // ARGB (width * height * sizeof(ULONG))
69 #ifndef POINTERA_Width
70 #define POINTERA_Width (POINTERA_Dummy + 0x08) // <= 64
72 #ifndef POINTERA_Height
73 #define POINTERA_Height (POINTERA_Dummy + 0x09) // <= 64
75 #ifndef WA_PointerType
76 #define WA_PointerType (WA_Dummy + 0x50)
78 #ifndef POINTERTYPE_TEXT
79 #define POINTERTYPE_TEXT 30
84 static const UWORD selectPointer
[] =
109 #endif // __amigaos4__
111 // Classic bitmap data for the pointer. These will be used for OS4 aswell,
112 // if the graphic card cannot handle 32bit pointers.
113 static const UWORD selectPointer_bp0
[] =
133 static const UWORD selectPointer_bp1
[] =
153 static const UWORD selectPointer_bp2
[] =
173 static struct BitMap selectPointerBitmap
=
176 { (PLANEPTR
)selectPointer_bp0
, (PLANEPTR
)selectPointer_bp1
, NULL
, NULL
, NULL
, NULL
, NULL
}
179 #if defined(__MORPHOS__)
180 #ifndef POINTERTYPE_SELECTTEXT
181 #define POINTERTYPE_SELECTTEXT 7
183 #ifndef WA_PointerType
184 #define WA_PointerType (WA_Dummy + 164)
188 /// IdentifyPointerColors()
189 static void IdentifyPointerColors(Object
*obj
)
200 // get the current screen's pointer colors (17 to 19)
201 GetRGB32(_window(obj
)->WScreen
->ViewPort
.ColorMap
, 17, 3, colors
);
209 // normalize the colors to 8 bit per gun as GetRGB32() returns
210 // 32bit left aligned values
211 colors
[i
*3+0] >>= 24;
212 colors
[i
*3+1] >>= 24;
213 colors
[i
*3+2] >>= 24;
215 // calculate the geometric difference to the color black (=0x00000000)
216 dr
= 0x00000000 - colors
[i
*3+0];
217 dg
= 0x00000000 - colors
[i
*3+1];
218 db
= 0x00000000 - colors
[i
*3+2];
219 blackDiff
[i
] = dr
* dr
+ dg
* dg
+ db
* db
;
221 // calculate the geometric difference to the color white (=0x000000ff)
222 dr
= 0x000000ff - colors
[i
*3+0];
223 dg
= 0x000000ff - colors
[i
*3+1];
224 db
= 0x000000ff - colors
[i
*3+2];
225 whiteDiff
[i
] = dr
* dr
+ dg
* dg
+ db
* db
;
228 // the smallest difference defines the color which is closest to black or
230 if(blackDiff
[0] > blackDiff
[1])
232 if(blackDiff
[1] > blackDiff
[2])
237 else if(blackDiff
[0] > blackDiff
[2])
242 // the smallest difference defines the color which is closest to white or
244 if(whiteDiff
[0] > whiteDiff
[1])
246 if(whiteDiff
[1] > whiteDiff
[2])
251 else if(whiteDiff
[0] > whiteDiff
[2])
256 // Here we expect the user to have set up quite "different" colors. That
257 // means the color closest to white will never be close to black and vice
258 // versa. According to these differences we spread the required bitplanes.
263 selectPointerBitmap
.Planes
[0] = (PLANEPTR
)selectPointer_bp0
;
264 selectPointerBitmap
.Planes
[1] = (PLANEPTR
)selectPointer_bp1
;
266 else // blackIndex == 19
268 selectPointerBitmap
.Planes
[0] = (PLANEPTR
)selectPointer_bp2
;
269 selectPointerBitmap
.Planes
[1] = (PLANEPTR
)selectPointer_bp1
;
272 else if(whiteIndex
== 18)
276 selectPointerBitmap
.Planes
[0] = (PLANEPTR
)selectPointer_bp1
;
277 selectPointerBitmap
.Planes
[1] = (PLANEPTR
)selectPointer_bp0
;
279 else // blackIndex == 19
281 selectPointerBitmap
.Planes
[0] = (PLANEPTR
)selectPointer_bp1
;
282 selectPointerBitmap
.Planes
[1] = (PLANEPTR
)selectPointer_bp2
;
285 else // whiteIndex == 19
289 selectPointerBitmap
.Planes
[0] = (PLANEPTR
)selectPointer_bp2
;
290 selectPointerBitmap
.Planes
[1] = (PLANEPTR
)selectPointer_bp0
;
292 else // blackIndex == 18
294 selectPointerBitmap
.Planes
[0] = (PLANEPTR
)selectPointer_bp0
;
295 selectPointerBitmap
.Planes
[1] = (PLANEPTR
)selectPointer_bp2
;
303 /// SetupSelectPointer()
304 void SetupSelectPointer(struct InstData
*data
)
308 #if defined(__amigaos4__)
309 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase
, 53, 40))
310 data
->PointerObj
= (APTR
)POINTERTYPE_TEXT
;
311 #elif defined(__MORPHOS__)
313 data
->PointerObj
= (APTR
)POINTERTYPE_SELECTTEXT
;
316 if(data
->PointerObj
== NULL
)
318 #if defined(__amigaos4__)
319 data
->PointerObj
= (Object
*)NewObject(NULL
, "pointerclass",
320 POINTERA_ImageData
, selectPointer
,
321 POINTERA_Width
, selectPointerWidth
,
322 POINTERA_Height
, selectPointerHeight
,
323 POINTERA_BitMap
, &selectPointerBitmap
,
324 POINTERA_WordWidth
, (ULONG
)1,
325 POINTERA_XResolution
, (ULONG
)POINTERXRESN_SCREENRES
,
326 POINTERA_YResolution
, (ULONG
)POINTERYRESN_SCREENRESASPECT
,
327 POINTERA_XOffset
, (LONG
)selectPointerXOffset
,
328 POINTERA_YOffset
, (LONG
)selectPointerYOffset
,
331 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase
, 39, 0))
333 data
->PointerObj
= (Object
*)NewObject(NULL
, (STRPTR
)"pointerclass",
334 POINTERA_BitMap
, (SIPTR
)&selectPointerBitmap
,
335 POINTERA_WordWidth
, (ULONG
)1,
336 POINTERA_XResolution
, (ULONG
)POINTERXRESN_SCREENRES
,
337 POINTERA_YResolution
, (ULONG
)POINTERYRESN_SCREENRESASPECT
,
338 POINTERA_XOffset
, (LONG
)selectPointerXOffset
,
339 POINTERA_YOffset
, (LONG
)selectPointerYOffset
,
344 if((data
->PointerObj
= (Object
*)AllocVec(sizeof(selectPointer
), MEMF_CHIP
|MEMF_PUBLIC
)) != NULL
)
345 memcpy(data
->PointerObj
, selectPointer
, sizeof(selectPointer
));
350 data
->activeSelectPointer
= FALSE
;
356 /// CleanupSelectPointer()
357 void CleanupSelectPointer(struct InstData
*data
)
361 #if defined(__amigaos4__)
362 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase
, 53, 40))
363 data
->PointerObj
= NULL
;
364 #elif defined(__MORPHOS__)
366 data
->PointerObj
= NULL
;
369 if(data
->PointerObj
!= NULL
)
372 if(data
->activeSelectPointer
== TRUE
)
373 E(DBF_ALWAYS
, "pointer was still active upon MUIM_Cleanup!!");
376 #if defined(__amigaos4__)
377 DisposeObject(data
->PointerObj
);
379 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase
, 39, 0))
381 DisposeObject(data
->PointerObj
);
385 FreeVec(data
->PointerObj
);
389 data
->PointerObj
= NULL
;
396 /// ShowSelectPointer()
397 void ShowSelectPointer(struct InstData
*data
, Object
*obj
)
401 // even if it seems to be a waste of performance, but
402 // we unfortunately have to always set the window pointer
403 // regardless of the point if it was previously set or not.
404 // This is required as any other gadget or process might
405 // reset the window pointer and as such we would end up
406 // with no custom pointer as well. So we only check the window
407 // sleep status here :(
408 if(data
->PointerObj
!= NULL
&&
409 xget(_win(obj
), MUIA_Window_Sleep
) == FALSE
)
411 // try to identify the black/white colors
412 // of the current screen colormap
413 if(data
->activeSelectPointer
== FALSE
)
414 IdentifyPointerColors(obj
);
416 // now we set the actual new custom window pointer. Please note
417 // that we can't unfortunately check for data->activeSelectPointer
418 // here because otherwise we might end up with the standard
419 // window pointer when quickly switching pointer TE.mcc
420 #if defined(__amigaos4__)
421 SetWindowPointer(_window(obj
), LIB_VERSION_IS_AT_LEAST(IntuitionBase
, 53, 407) ? WA_PointerType
: WA_Pointer
, data
->PointerObj
, TAG_DONE
);
422 #elif defined(__MORPHOS__)
423 SetWindowPointer(_window(obj
), IS_MORPHOS2
? WA_PointerType
: WA_Pointer
, data
->PointerObj
, TAG_DONE
);
425 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase
, 39, 0))
426 SetWindowPointer(_window(obj
), WA_Pointer
, data
->PointerObj
, TAG_DONE
);
428 SetPointer(_window(obj
), (APTR
)data
->PointerObj
, selectPointerHeight
,
430 selectPointerXOffset
,
431 selectPointerYOffset
);
434 data
->activeSelectPointer
= TRUE
;
441 /// HideSelectPointer()
442 void HideSelectPointer(struct InstData
*data
, Object
*obj
)
446 if(data
->activeSelectPointer
== TRUE
&&
447 data
->PointerObj
!= NULL
)
449 #if defined(__amigaos4__) || defined(__MORPHOS__)
450 SetWindowPointer(_window(obj
), TAG_DONE
);
452 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase
, 39, 0))
453 SetWindowPointer(_window(obj
), TAG_DONE
);
455 ClearPointer(_window(obj
));
458 data
->activeSelectPointer
= FALSE
;