2 Copyright © 2002-2013, 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 ULONG lock
= LockIBase(0);
276 GetAttr(POINTERA_SharedPointer
, *old
, (IPTR
*)&oldpointer
);
277 GetAttr(POINTERA_SharedPointer
, pointer
, (IPTR
*)&newpointer
);
279 for (scr
= GetPrivScreen(IntuitionBase
->FirstScreen
); scr
; scr
= GetPrivScreen(scr
->Screen
.NextScreen
))
281 for (win
= scr
->Screen
.FirstWindow
; win
; win
= win
->NextWindow
)
283 if (((struct IntWindow
*)win
)->pointer
== *old
)
285 win
->XOffset
= newpointer
->xoffset
;
286 win
->YOffset
= newpointer
->yoffset
;
290 if (scr
->Pointer
== oldpointer
)
292 DEBUG_POINTER(dprintf("InstallPointer: scr 0x%lx pointer 0x%lx sprite 0x%lx\n",
293 scr
, pointer
, newpointer
->sprite
));
294 if (DoMethod(scr
->IMonitorNode
, MM_SetPointerShape
, newpointer
))
296 ObtainSharedPointer(newpointer
, IntuitionBase
);
297 ReleaseSharedPointer(oldpointer
, IntuitionBase
);
298 scr
->Pointer
= newpointer
;
302 DEBUG_POINTER(dprintf("InstallPointer: can't change pointer.\n"));
309 /* Set new normal pointer image on all empty displays */
310 if (which
== WBP_NORMAL
)
311 ResetPointer(IntuitionBase
);
312 /* Dispose old pointer only after setting new one */
313 DisposeObject(oldobject
);
318 void SetPointerColors(struct IntuitionBase
*IntuitionBase
)
320 struct IntIntuitionBase
*_intuitionBase
= GetPrivIBase(IntuitionBase
);
321 struct GfxBase
*GfxBase
= _intuitionBase
->GfxBase
;
324 ULONG lock
= LockIBase(0);
325 /* Probably this should apply to Workbench screen and not to currently active one? */
326 struct Screen
*scr
= IntuitionBase
->ActiveScreen
;
328 DEBUG_POINTER(dprintf("SetPointerColors()\n");)
330 p
= _intuitionBase
->Colors
;
334 #ifndef ALWAYS_ALLOCATE_SPRITE_COLORS
335 if (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_DEPTH
) < 9)
338 UWORD firstcol
= scr
->ViewPort
.ColorMap
->SpriteBase_Even
;
340 /* Translate bank number and offset to color number - see graphics/getcolormap.c */
341 firstcol
= (firstcol
<< 4) | (firstcol
>> 8);
342 for (k
= 1; k
< 4; ++k
, ++p
) {
343 DEBUG_POINTER(dprintf("Color %u: R %08lx G %08lx B %08lx\n", p
[k
+7].red
, p
[k
+7].green
, p
[k
+7].blue
);)
344 SetRGB32(&scr
->ViewPort
, k
+ firstcol
, p
[k
+7].red
, p
[k
+7].green
, p
[k
+7].blue
);
351 DEBUG_POINTER(dprintf("SetPointerColors() done\n");)
355 struct SharedPointer
*CreateSharedPointer(struct ExtSprite
*sprite
, int x
, int y
,
356 struct IntuitionBase
*IntuitionBase
)
358 struct SharedPointer
*pointer
;
360 pointer
= AllocMem(sizeof(*pointer
), MEMF_PUBLIC
);
363 pointer
->sprite
= sprite
;
364 pointer
->xoffset
= x
;
365 pointer
->yoffset
= y
;
366 pointer
->ref_count
= 1;
372 void ObtainSharedPointer(struct SharedPointer
*pointer
,
373 struct IntuitionBase
*IntuitionBase
)
375 ULONG lock
= LockIBase(0);
376 ++pointer
->ref_count
;
380 void ReleaseSharedPointer(struct SharedPointer
*pointer
,
381 struct IntuitionBase
*IntuitionBase
)
383 struct IntIntuitionBase
*_intuitionBase
= GetPrivIBase(IntuitionBase
);
384 struct GfxBase
*GfxBase
= _intuitionBase
->GfxBase
;
385 ULONG lock
= LockIBase(0);
386 if (--pointer
->ref_count
== 0)
388 FreeSpriteData(pointer
->sprite
);
389 FreeMem(pointer
, sizeof(*pointer
));