2 Copyright © 2002-2019, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
7 #include <aros/debug.h>
8 #include <aros/macros.h>
9 #include <exec/memory.h>
10 #include <graphics/rastport.h>
11 #include <intuition/pointerclass.h>
12 #include <prefs/pointer.h>
13 #include <proto/exec.h>
14 #include <proto/graphics.h>
15 #include <proto/intuition.h>
17 #include "intuition_intern.h"
18 #include "inputhandler.h"
19 #include "inputhandler_support.h"
20 #include "monitorclass_private.h"
22 void MySetPointerPos(struct IntuitionBase
*IntuitionBase
)
24 struct IntIntuitionBase
*_intuitionBase
= GetPrivIBase(IntuitionBase
);
25 Object
*mon
= _intuitionBase
->ActiveMonitor
;
28 DoMethod(mon
, MM_SetPointerPos
, IntuitionBase
->MouseX
, IntuitionBase
->MouseY
);
31 BOOL
ResetPointer(struct IntuitionBase
*IntuitionBase
)
33 struct IntIntuitionBase
*_intuitionBase
= GetPrivIBase(IntuitionBase
);
35 struct SharedPointer
*pointer
= NULL
;
36 Object
*obj
= _intuitionBase
->DefaultPointer
;
40 GetAttr(POINTERA_SharedPointer
, obj
, (IPTR
*)&pointer
);
41 D(bug("[ResetPointer] Default pointer is 0x%p\n", pointer
));
45 ObtainSemaphoreShared(&_intuitionBase
->MonitorListSem
);
47 ForeachNode(&_intuitionBase
->MonitorList
, mon
) {
48 if (!FindFirstScreen(mon
, IntuitionBase
)) {
49 D(bug("[ResetPointer] Setting default pointer for monitor 0x%p\n", mon
));
50 if (!DoMethod(mon
, MM_SetPointerShape
, pointer
))
55 ReleaseSemaphore(&_intuitionBase
->MonitorListSem
);
57 D(bug("[ResetPointer] Returning %d\n", res
));
61 void ActivateMonitor(Object
*newmonitor
, WORD x
, WORD y
, struct IntuitionBase
*IntuitionBase
)
63 struct IntIntuitionBase
*_intuitionBase
= GetPrivIBase(IntuitionBase
);
64 Object
*oldmonitor
= _intuitionBase
->ActiveMonitor
;
66 D(bug("ActivateMonitor(0x%p), old monitor 0x%p\n", newmonitor
, oldmonitor
));
67 /* Do not bother if switching to the same monitor */
68 if (newmonitor
== oldmonitor
)
72 SetAttrs(oldmonitor
, MA_PointerVisible
, FALSE
, TAG_DONE
);
74 _intuitionBase
->ActiveMonitor
= newmonitor
;
76 struct Screen
*scr
= FindFirstScreen(newmonitor
, IntuitionBase
);
77 UWORD DWidth
, DHeight
;
80 x
= IntuitionBase
->MouseX
;
82 y
= IntuitionBase
->MouseY
;
84 /* A crude copy from inputhandler.c. We should really handle this in monitorclass */
87 DWidth
= scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MaxX
- scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MinX
;
88 DHeight
= scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MaxY
- scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MinY
;
92 /* If there's no active screen, we take 160x160 as a limit */
101 D(bug("[ActivateMonitor] Mouse pointer coordinates: (%d, %d)\n", x
, y
));
102 IntuitionBase
->MouseX
= x
;
103 IntuitionBase
->MouseY
= y
;
105 SetAttrs(newmonitor
, MA_PointerVisible
, TRUE
, TAG_DONE
);
106 MySetPointerPos(IntuitionBase
);
107 notify_mousemove_screensandwindows(IntuitionBase
);
109 D(bug("[ActivateMonitor] Done\n"));
112 struct Screen
*FindFirstScreen(Object
*monitor
, struct IntuitionBase
*IntuitionBase
)
116 for (scr
= IntuitionBase
->FirstScreen
; scr
; scr
= scr
->NextScreen
) {
117 if (GetPrivScreen(scr
)->IMonitorNode
== monitor
)
123 struct RastPort
*MyCreateRastPort(struct IntuitionBase
*IntuitionBase
)
125 struct IntIntuitionBase
*_intuitionBase
= GetPrivIBase(IntuitionBase
);
126 struct GfxBase
*GfxBase
= _intuitionBase
->GfxBase
;
127 struct RastPort
*newrp
= AllocMem(sizeof(*newrp
), MEMF_PUBLIC
);
137 struct RastPort
*MyCloneRastPort(struct IntuitionBase
*IntuitionBase
, struct RastPort
*rp
)
139 struct RastPort
*newrp
= NULL
;
143 newrp
= AllocMem(sizeof(*newrp
), MEMF_PUBLIC
);
146 CopyMem(rp
, newrp
, sizeof(struct RastPort
));
153 void MyFreeRastPort(struct IntuitionBase
*IntuitionBase
, struct RastPort
*rp
)
157 /* Just in case... What if someone plays with ClipRects? */
158 FreeVec(rp
->RP_Extra
);
161 FreeMem(rp
, sizeof(*rp
));
166 BOOL
IsLayerHiddenBySibling(struct Layer
*layer
, BOOL xx
)
168 struct Window
*win
= layer
->Window
;
170 /* skip requesters attached to the same window. */
171 while (layer
->front
&& layer
->front
->Window
== win
)
173 layer
= layer
->front
;
176 /* jDc: we need to care for layers that are on
177 ** front of our layer, but don't cover it*/
183 for (lay
= layer
->front
; lay
; lay
= lay
->front
)
185 struct Window
*lwin
= lay
->Window
;
189 if (lwin
->LeftEdge
> win
->LeftEdge
+ win
->Width
- 1) continue;
190 if (lwin
->LeftEdge
+ lwin
->Width
- 1 < win
->LeftEdge
) continue;
191 if (lwin
->TopEdge
> win
->TopEdge
+ win
->Height
- 1) continue;
192 if (lwin
->TopEdge
+ lwin
->Height
- 1 < win
->TopEdge
) continue;
203 struct TextFont
*SafeReopenFont(struct IntuitionBase
*IntuitionBase
,
204 struct TextFont
**fontptr
)
206 struct IntIntuitionBase
*_intuitionBase
= GetPrivIBase(IntuitionBase
);
207 struct GfxBase
*GfxBase
= _intuitionBase
->GfxBase
;
208 struct TextFont
*ret
= NULL
, *font
;
210 /* Atomically lock the font before, so it can't go away
219 font
->tf_Accessors
++;
222 /* Now really open it
224 ta
.ta_Name
= font
->tf_Message
.mn_Node
.ln_Name
;
225 ta
.ta_YSize
= font
->tf_YSize
;
226 ta
.ta_Style
= font
->tf_Style
;
227 ta
.ta_Flags
= font
->tf_Flags
;
234 font
->tf_Accessors
--;
242 Object
*MakePointerFromData(struct IntuitionBase
*IntuitionBase
,
243 const UWORD
*source
, int xOffset
, int yOffset
, int width
, int height
)
245 struct IntIntuitionBase
*_intuitionBase
= GetPrivIBase(IntuitionBase
);
246 struct TagItem pointertags
[] = {
247 {POINTERA_BitMap
, (IPTR
)source
},
248 {POINTERA_XOffset
, xOffset
},
249 {POINTERA_YOffset
, yOffset
},
250 {SPRITEA_OldDataFormat
, TRUE
},
251 {SPRITEA_Width
, width
},
252 {SPRITEA_OutputHeight
, height
},
256 return NewObjectA(_intuitionBase
->pointerclass
, NULL
, pointertags
);
259 Object
*MakePointerFromPrefs(struct IntuitionBase
*IntuitionBase
, struct Preferences
*prefs
)
261 SetPointerColors(IntuitionBase
);
263 return MakePointerFromData(IntuitionBase
, prefs
->PointerMatrix
, prefs
->XOffset
, prefs
->YOffset
, 16, 16);
266 void InstallPointer(struct IntuitionBase
*IntuitionBase
, UWORD which
, Object
**old
, Object
*pointer
)
268 struct IntScreen
*scr
;
270 struct SharedPointer
*oldpointer
;
271 struct SharedPointer
*newpointer
;
274 DEBUG_POINTER(dprintf("InstallPointer(0x%p)\n", pointer
);)
276 ULONG lock
= LockIBase(0);
278 GetAttr(POINTERA_SharedPointer
, *old
, (IPTR
*)&oldpointer
);
279 GetAttr(POINTERA_SharedPointer
, pointer
, (IPTR
*)&newpointer
);
281 for (scr
= GetPrivScreen(IntuitionBase
->FirstScreen
); scr
; scr
= GetPrivScreen(scr
->Screen
.NextScreen
))
283 for (win
= scr
->Screen
.FirstWindow
; win
; win
= win
->NextWindow
)
285 if (((struct IntWindow
*)win
)->pointer
== *old
)
287 win
->XOffset
= newpointer
->xoffset
;
288 win
->YOffset
= newpointer
->yoffset
;
292 if (scr
->Pointer
== oldpointer
)
294 DEBUG_POINTER(dprintf("InstallPointer: scr 0x%lx pointer 0x%lx sprite 0x%lx\n",
295 scr
, pointer
, newpointer
->sprite
));
296 if (DoMethod(scr
->IMonitorNode
, MM_SetPointerShape
, newpointer
))
298 ObtainSharedPointer(newpointer
, IntuitionBase
);
299 ReleaseSharedPointer(oldpointer
, IntuitionBase
);
300 scr
->Pointer
= newpointer
;
304 DEBUG_POINTER(dprintf("InstallPointer: can't change pointer.\n"));
311 /* Set new normal pointer image on all empty displays */
312 if (which
== WBP_NORMAL
)
313 ResetPointer(IntuitionBase
);
314 /* Dispose old pointer only after setting new one */
315 DisposeObject(oldobject
);
320 void SetPointerColors(struct IntuitionBase
*IntuitionBase
)
322 struct IntIntuitionBase
*_intuitionBase
= GetPrivIBase(IntuitionBase
);
323 struct GfxBase
*GfxBase
= _intuitionBase
->GfxBase
;
326 ULONG lock
= LockIBase(0);
327 /* Probably this should apply to Workbench screen and not to currently active one? */
328 struct Screen
*scr
= IntuitionBase
->ActiveScreen
;
330 DEBUG_POINTER(dprintf("SetPointerColors()\n");)
332 p
= _intuitionBase
->Colors
;
336 #ifndef ALWAYS_ALLOCATE_SPRITE_COLORS
337 if (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_DEPTH
) < 9)
340 UWORD firstcol
= scr
->ViewPort
.ColorMap
->SpriteBase_Even
;
342 /* Translate bank number and offset to color number - see graphics/getcolormap.c */
343 firstcol
= (firstcol
<< 4) | (firstcol
>> 8);
344 for (k
= 1; k
< 4; ++k
, ++p
) {
345 DEBUG_POINTER(dprintf("Color %u: R %08lx G %08lx B %08lx\n", p
[k
+7].red
, p
[k
+7].green
, p
[k
+7].blue
);)
346 SetRGB32(&scr
->ViewPort
, k
+ firstcol
, p
[k
+7].red
, p
[k
+7].green
, p
[k
+7].blue
);
353 DEBUG_POINTER(dprintf("SetPointerColors() done\n");)
357 struct SharedPointer
*CreateSharedPointer(struct ExtSprite
*sprite
, int x
, int y
,
358 struct IntuitionBase
*IntuitionBase
)
360 struct SharedPointer
*pointer
;
362 pointer
= AllocMem(sizeof(*pointer
), MEMF_PUBLIC
);
365 pointer
->sprite
= sprite
;
366 pointer
->xoffset
= x
;
367 pointer
->yoffset
= y
;
368 pointer
->ref_count
= 1;
374 void ObtainSharedPointer(struct SharedPointer
*pointer
,
375 struct IntuitionBase
*IntuitionBase
)
377 ULONG lock
= LockIBase(0);
378 ++pointer
->ref_count
;
382 void ReleaseSharedPointer(struct SharedPointer
*pointer
,
383 struct IntuitionBase
*IntuitionBase
)
385 struct IntIntuitionBase
*_intuitionBase
= GetPrivIBase(IntuitionBase
);
386 struct GfxBase
*GfxBase
= _intuitionBase
->GfxBase
;
387 ULONG lock
= LockIBase(0);
388 if (--pointer
->ref_count
== 0)
390 FreeSpriteData(pointer
->sprite
);
391 FreeMem(pointer
, sizeof(*pointer
));