revert between 56095 -> 55830 in arch
[AROS.git] / workbench / classes / zune / texteditor / mcc / Pointer.c
blob55b22f850244d09494a625191624ab4b0a7aa2e5
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
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"
35 #include "Debug.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))
68 #endif
69 #ifndef POINTERA_Width
70 #define POINTERA_Width (POINTERA_Dummy + 0x08) // <= 64
71 #endif
72 #ifndef POINTERA_Height
73 #define POINTERA_Height (POINTERA_Dummy + 0x09) // <= 64
74 #endif
75 #ifndef WA_PointerType
76 #define WA_PointerType (WA_Dummy + 0x50)
77 #endif
78 #ifndef POINTERTYPE_TEXT
79 #define POINTERTYPE_TEXT 30
80 #endif
82 #else // __amigaos4__
84 static const UWORD selectPointer[] =
86 //plane1 plane2
87 0x0000, 0x0000,
89 0x8800, 0x4600,
90 0x5000, 0x2800,
91 0x2000, 0x1000,
92 0x2000, 0x1000,
93 0x2000, 0x1000,
94 0x2000, 0x1000,
95 0x2000, 0x1000,
96 0x2000, 0x1000,
97 0x4000, 0x3800,
98 0x2000, 0x1000,
99 0x2000, 0x1000,
100 0x2000, 0x1000,
101 0x2000, 0x1000,
102 0x2000, 0x1000,
103 0x5000, 0x2800,
104 0x8800, 0x4600,
106 0x0000, 0x0000
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[] =
115 0x8800, // #...#..
116 0x5000, // .#.#...
117 0x2000, // ..#....
118 0x2000, // ..#....
119 0x2000, // ..#....
120 0x2000, // ..#....
121 0x2000, // ..#....
122 0x2000, // ..#....
123 0x4000, // .#.....
124 0x2000, // ..#....
125 0x2000, // ..#....
126 0x2000, // ..#....
127 0x2000, // ..#....
128 0x2000, // ..#....
129 0x5000, // .#.#...
130 0x8800, // #...#..
133 static const UWORD selectPointer_bp1[] =
135 0x4600, // .#...##
136 0x2800, // ..#.#..
137 0x1000, // ...#...
138 0x1000, // ...#...
139 0x1000, // ...#...
140 0x1000, // ...#...
141 0x1000, // ...#...
142 0x1000, // ...#...
143 0x3800, // ..###..
144 0x1000, // ...#...
145 0x1000, // ...#...
146 0x1000, // ...#...
147 0x1000, // ...#...
148 0x1000, // ...#...
149 0x2800, // ..#.#..
150 0x4600, // .#...##
153 static const UWORD selectPointer_bp2[] =
155 0xce00, // %#..%##
156 0x7800, // .%#%#..
157 0x3000, // ..%#...
158 0x3000, // ..%#...
159 0x3000, // ..%#...
160 0x3000, // ..%#...
161 0x3000, // ..%#...
162 0x3000, // ..%#...
163 0x7800, // .%%%#..
164 0x3000, // ..%#...
165 0x3000, // ..%#...
166 0x3000, // ..%#...
167 0x3000, // ..%#...
168 0x3000, // ..%#...
169 0x7800, // .%#%#..
170 0xce00, // %#..%##
173 static struct BitMap selectPointerBitmap =
175 2, 16, 0, 2, 0,
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
182 #endif
183 #ifndef WA_PointerType
184 #define WA_PointerType (WA_Dummy + 164)
185 #endif
186 #endif
188 /// IdentifyPointerColors()
189 static void IdentifyPointerColors(Object *obj)
191 int i;
192 ULONG colors[3*3];
193 LONG blackDiff[3];
194 LONG whiteDiff[3];
195 LONG blackIndex;
196 LONG whiteIndex;
198 ENTER();
200 // get the current screen's pointer colors (17 to 19)
201 GetRGB32(_window(obj)->WScreen->ViewPort.ColorMap, 17, 3, colors);
203 for(i=0; i < 3; i++)
205 LONG dr;
206 LONG dg;
207 LONG db;
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
229 // equal to black
230 if(blackDiff[0] > blackDiff[1])
232 if(blackDiff[1] > blackDiff[2])
233 blackIndex = 19;
234 else
235 blackIndex = 18;
237 else if(blackDiff[0] > blackDiff[2])
238 blackIndex = 19;
239 else
240 blackIndex = 17;
242 // the smallest difference defines the color which is closest to white or
243 // equal to white
244 if(whiteDiff[0] > whiteDiff[1])
246 if(whiteDiff[1] > whiteDiff[2])
247 whiteIndex = 19;
248 else
249 whiteIndex = 18;
251 else if(whiteDiff[0] > whiteDiff[2])
252 whiteIndex = 19;
253 else
254 whiteIndex = 17;
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.
259 if(whiteIndex == 17)
261 if(blackIndex == 18)
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)
274 if(blackIndex == 17)
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
287 if(blackIndex == 17)
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;
299 LEAVE();
303 /// SetupSelectPointer()
304 void SetupSelectPointer(struct InstData *data)
306 ENTER();
308 #if defined(__amigaos4__)
309 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase, 53, 40))
310 data->PointerObj = (APTR)POINTERTYPE_TEXT;
311 #elif defined(__MORPHOS__)
312 if(IS_MORPHOS2)
313 data->PointerObj = (APTR)POINTERTYPE_SELECTTEXT;
314 #endif
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,
329 TAG_DONE);
330 #else
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,
340 TAG_DONE);
342 else
344 if((data->PointerObj = (Object *)AllocVec(sizeof(selectPointer), MEMF_CHIP|MEMF_PUBLIC)) != NULL)
345 memcpy(data->PointerObj, selectPointer, sizeof(selectPointer));
347 #endif
350 data->activeSelectPointer = FALSE;
352 LEAVE();
356 /// CleanupSelectPointer()
357 void CleanupSelectPointer(struct InstData *data)
359 ENTER();
361 #if defined(__amigaos4__)
362 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase, 53, 40))
363 data->PointerObj = NULL;
364 #elif defined(__MORPHOS__)
365 if (IS_MORPHOS2)
366 data->PointerObj = NULL;
367 #endif
369 if(data->PointerObj != NULL)
371 #if defined(DEBUG)
372 if(data->activeSelectPointer == TRUE)
373 E(DBF_ALWAYS, "pointer was still active upon MUIM_Cleanup!!");
374 #endif
376 #if defined(__amigaos4__)
377 DisposeObject(data->PointerObj);
378 #else
379 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase, 39, 0))
381 DisposeObject(data->PointerObj);
383 else
385 FreeVec(data->PointerObj);
387 #endif
389 data->PointerObj = NULL;
392 LEAVE();
396 /// ShowSelectPointer()
397 void ShowSelectPointer(struct InstData *data, Object *obj)
399 ENTER();
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);
424 #else
425 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase, 39, 0))
426 SetWindowPointer(_window(obj), WA_Pointer, data->PointerObj, TAG_DONE);
427 else
428 SetPointer(_window(obj), (APTR)data->PointerObj, selectPointerHeight,
429 selectPointerWidth,
430 selectPointerXOffset,
431 selectPointerYOffset);
432 #endif
434 data->activeSelectPointer = TRUE;
437 LEAVE();
441 /// HideSelectPointer()
442 void HideSelectPointer(struct InstData *data, Object *obj)
444 ENTER();
446 if(data->activeSelectPointer == TRUE &&
447 data->PointerObj != NULL)
449 #if defined(__amigaos4__) || defined(__MORPHOS__)
450 SetWindowPointer(_window(obj), TAG_DONE);
451 #else
452 if(LIB_VERSION_IS_AT_LEAST(IntuitionBase, 39, 0))
453 SetWindowPointer(_window(obj), TAG_DONE);
454 else
455 ClearPointer(_window(obj));
456 #endif
458 data->activeSelectPointer = FALSE;
461 LEAVE();