2 Copyright © 2002-2011, 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 Object
*mon
= GetPrivIBase(IntuitionBase
)->ActiveMonitor
;
27 DoMethod(mon
, MM_SetPointerPos
, IntuitionBase
->MouseX
, IntuitionBase
->MouseY
);
30 BOOL
ResetPointer(struct IntuitionBase
*IntuitionBase
)
34 struct SharedPointer
*pointer
= NULL
;
35 Object
*obj
= GetPrivIBase(IntuitionBase
)->DefaultPointer
;
39 GetAttr(POINTERA_SharedPointer
, obj
, (IPTR
*)&pointer
);
40 D(bug("[ResetPointer] Default pointer is 0x%p\n", pointer
));
44 ObtainSemaphoreShared(&GetPrivIBase(IntuitionBase
)->MonitorListSem
);
46 ForeachNode(&GetPrivIBase(IntuitionBase
)->MonitorList
, mon
) {
47 if (!FindFirstScreen(mon
, IntuitionBase
)) {
48 D(bug("[ResetPointer] Setting default pointer for monitor 0x%p\n", mon
));
49 if (!DoMethod(mon
, MM_SetPointerShape
, pointer
))
54 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MonitorListSem
);
56 D(bug("[ResetPointer] Returning %d\n", res
));
60 void ActivateMonitor(Object
*newmonitor
, WORD x
, WORD y
, struct IntuitionBase
*IntuitionBase
)
62 Object
*oldmonitor
= GetPrivIBase(IntuitionBase
)->ActiveMonitor
;
64 D(bug("ActivateMonitor(0x%p), old monitor 0x%p\n", newmonitor
, oldmonitor
));
65 /* Do not bother if switching to the same monitor */
66 if (newmonitor
== oldmonitor
)
70 SetAttrs(oldmonitor
, MA_PointerVisible
, FALSE
, TAG_DONE
);
72 GetPrivIBase(IntuitionBase
)->ActiveMonitor
= newmonitor
;
74 struct Screen
*scr
= FindFirstScreen(newmonitor
, IntuitionBase
);
75 UWORD DWidth
, DHeight
;
78 x
= IntuitionBase
->MouseX
;
80 y
= IntuitionBase
->MouseY
;
82 /* A crude copy from inputhandler.c. We should really handle this in monitorclass */
85 DWidth
= scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MaxX
- scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MinX
;
86 DHeight
= scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MaxY
- scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MinY
;
90 /* If there's no active screen, we take 160x160 as a limit */
99 D(bug("[ActivateMonitor] Mouse pointer coordinates: (%d, %d)\n", x
, y
));
100 IntuitionBase
->MouseX
= x
;
101 IntuitionBase
->MouseY
= y
;
103 SetAttrs(newmonitor
, MA_PointerVisible
, TRUE
, TAG_DONE
);
104 MySetPointerPos(IntuitionBase
);
105 notify_mousemove_screensandwindows(IntuitionBase
);
107 D(bug("[ActivateMonitor] Done\n"));
110 struct Screen
*FindFirstScreen(Object
*monitor
, struct IntuitionBase
*IntuitionBase
)
114 for (scr
= IntuitionBase
->FirstScreen
; scr
; scr
= scr
->NextScreen
) {
115 if (GetPrivScreen(scr
)->MonitorObject
== monitor
)
121 struct RastPort
*MyCreateRastPort(struct IntuitionBase
*IntuitionBase
)
123 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
124 struct RastPort
*newrp
= AllocMem(sizeof(*newrp
), MEMF_PUBLIC
);
134 struct RastPort
*MyCloneRastPort(struct IntuitionBase
*IntuitionBase
, struct RastPort
*rp
)
136 struct RastPort
*newrp
= NULL
;
140 newrp
= AllocMem(sizeof(*newrp
), MEMF_PUBLIC
);
143 CopyMem(rp
, newrp
, sizeof(struct RastPort
));
150 void MyFreeRastPort(struct IntuitionBase
*IntuitionBase
, struct RastPort
*rp
)
154 /* Just in case... What if someone plays with ClipRects? */
155 FreeVec(rp
->RP_Extra
);
158 FreeMem(rp
, sizeof(*rp
));
163 BOOL
IsLayerHiddenBySibling(struct Layer
*layer
, BOOL xx
)
165 struct Window
*win
= layer
->Window
;
167 /* skip requesters attached to the same window. */
168 while (layer
->front
&& layer
->front
->Window
== win
)
170 layer
= layer
->front
;
173 /* jDc: we need to care for layers that are on
174 ** front of our layer, but don't cover it*/
180 for (lay
= layer
->front
; lay
; lay
= lay
->front
)
182 struct Window
*lwin
= lay
->Window
;
186 if (lwin
->LeftEdge
> win
->LeftEdge
+ win
->Width
- 1) continue;
187 if (lwin
->LeftEdge
+ lwin
->Width
- 1 < win
->LeftEdge
) continue;
188 if (lwin
->TopEdge
> win
->TopEdge
+ win
->Height
- 1) continue;
189 if (lwin
->TopEdge
+ lwin
->Height
- 1 < win
->TopEdge
) continue;
200 struct TextFont
*SafeReopenFont(struct IntuitionBase
*IntuitionBase
,
201 struct TextFont
**fontptr
)
203 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
204 struct TextFont
*ret
= NULL
, *font
;
206 /* Atomically lock the font before, so it can't go away
215 font
->tf_Accessors
++;
218 /* Now really open it
220 ta
.ta_Name
= font
->tf_Message
.mn_Node
.ln_Name
;
221 ta
.ta_YSize
= font
->tf_YSize
;
222 ta
.ta_Style
= font
->tf_Style
;
223 ta
.ta_Flags
= font
->tf_Flags
;
230 font
->tf_Accessors
--;
238 Object
*MakePointerFromData(struct IntuitionBase
*IntuitionBase
,
239 UWORD
*source
, int xOffset
, int yOffset
, int width
, int height
)
241 struct TagItem pointertags
[] = {
242 {POINTERA_BitMap
, (IPTR
)source
},
243 {POINTERA_XOffset
, xOffset
},
244 {POINTERA_YOffset
, yOffset
},
245 {SPRITEA_OldDataFormat
, TRUE
},
246 {SPRITEA_Width
, width
},
247 {SPRITEA_OutputHeight
, height
},
251 return NewObjectA(GetPrivIBase(IntuitionBase
)->pointerclass
, NULL
, pointertags
);
254 Object
*MakePointerFromPrefs(struct IntuitionBase
*IntuitionBase
, struct Preferences
*prefs
)
256 SetPointerColors(IntuitionBase
);
258 return MakePointerFromData(IntuitionBase
, prefs
->PointerMatrix
, prefs
->XOffset
, prefs
->YOffset
, 16, 16);
261 void InstallPointer(struct IntuitionBase
*IntuitionBase
, UWORD which
, Object
**old
, Object
*pointer
)
263 struct IntScreen
*scr
;
265 struct SharedPointer
*oldpointer
;
266 struct SharedPointer
*newpointer
;
269 ULONG lock
= LockIBase(0);
271 GetAttr(POINTERA_SharedPointer
, *old
, (IPTR
*)&oldpointer
);
272 GetAttr(POINTERA_SharedPointer
, pointer
, (IPTR
*)&newpointer
);
274 for (scr
= GetPrivScreen(IntuitionBase
->FirstScreen
); scr
; scr
= GetPrivScreen(scr
->Screen
.NextScreen
))
276 for (win
= scr
->Screen
.FirstWindow
; win
; win
= win
->NextWindow
)
278 if (((struct IntWindow
*)win
)->pointer
== *old
)
280 win
->XOffset
= newpointer
->xoffset
;
281 win
->YOffset
= newpointer
->yoffset
;
285 if (scr
->Pointer
== oldpointer
)
287 DEBUG_POINTER(dprintf("InstallPointer: scr 0x%lx pointer 0x%lx sprite 0x%lx\n",
288 scr
, pointer
, newpointer
->sprite
));
289 if (DoMethod(scr
->MonitorObject
, MM_SetPointerShape
, newpointer
))
291 ObtainSharedPointer(newpointer
, IntuitionBase
);
292 ReleaseSharedPointer(oldpointer
, IntuitionBase
);
293 scr
->Pointer
= newpointer
;
297 DEBUG_POINTER(dprintf("InstallPointer: can't change pointer.\n"));
304 /* Set new normal pointer image on all empty displays */
305 if (which
== WBP_NORMAL
)
306 ResetPointer(IntuitionBase
);
307 /* Dispose old pointer only after setting new one */
308 DisposeObject(oldobject
);
313 void SetPointerColors(struct IntuitionBase
*IntuitionBase
)
315 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
318 ULONG lock
= LockIBase(0);
319 /* Probably this should apply to Workbench screen and not to currently active one? */
320 struct Screen
*scr
= IntuitionBase
->ActiveScreen
;
322 DEBUG_POINTER(dprintf("SetPointerColors()\n");)
324 p
= GetPrivIBase(IntuitionBase
)->Colors
;
328 #ifndef ALWAYS_ALLOCATE_SPRITE_COLORS
329 if (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_DEPTH
) < 9)
332 UWORD firstcol
= scr
->ViewPort
.ColorMap
->SpriteBase_Even
;
334 /* Translate bank number and offset to color number - see graphics/getcolormap.c */
335 firstcol
= (firstcol
<< 4) | (firstcol
>> 8);
336 for (k
= 1; k
< 4; ++k
, ++p
) {
337 DEBUG_POINTER(dprintf("Color %u: R %08lx G %08lx B %08lx\n", p
[k
+7].red
, p
[k
+7].green
, p
[k
+7].blue
);)
338 SetRGB32(&scr
->ViewPort
, k
+ firstcol
, p
[k
+7].red
, p
[k
+7].green
, p
[k
+7].blue
);
345 DEBUG_POINTER(dprintf("SetPointerColors() done\n");)
349 struct SharedPointer
*CreateSharedPointer(struct ExtSprite
*sprite
, int x
, int y
,
350 struct IntuitionBase
*IntuitionBase
)
352 struct SharedPointer
*pointer
;
354 pointer
= AllocMem(sizeof(*pointer
), MEMF_PUBLIC
);
357 pointer
->sprite
= sprite
;
358 pointer
->xoffset
= x
;
359 pointer
->yoffset
= y
;
360 pointer
->ref_count
= 1;
366 void ObtainSharedPointer(struct SharedPointer
*pointer
,
367 struct IntuitionBase
*IntuitionBase
)
369 ULONG lock
= LockIBase(0);
370 ++pointer
->ref_count
;
374 void ReleaseSharedPointer(struct SharedPointer
*pointer
,
375 struct IntuitionBase
*IntuitionBase
)
377 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
378 ULONG lock
= LockIBase(0);
379 if (--pointer
->ref_count
== 0)
381 FreeSpriteData(pointer
->sprite
);
382 FreeMem(pointer
, sizeof(*pointer
));