revert commit 56204.
[AROS.git] / rom / intuition / misc.c
blob5d15965a9c369c0436bcb25ecf2ca1650131abd0
1 /*
2 Copyright © 2002-2019, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
5 */
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;
27 if (mon)
28 DoMethod(mon, MM_SetPointerPos, IntuitionBase->MouseX, IntuitionBase->MouseY);
31 BOOL ResetPointer(struct IntuitionBase *IntuitionBase)
33 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
34 Object *mon;
35 struct SharedPointer *pointer = NULL;
36 Object *obj = _intuitionBase->DefaultPointer;
37 BOOL res = TRUE;
39 if (obj)
40 GetAttr(POINTERA_SharedPointer, obj, (IPTR *)&pointer);
41 D(bug("[ResetPointer] Default pointer is 0x%p\n", pointer));
42 if (!pointer)
43 return TRUE;
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))
51 res = FALSE;
55 ReleaseSemaphore(&_intuitionBase->MonitorListSem);
57 D(bug("[ResetPointer] Returning %d\n", res));
58 return 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)
69 return;
71 if (oldmonitor)
72 SetAttrs(oldmonitor, MA_PointerVisible, FALSE, TAG_DONE);
74 _intuitionBase->ActiveMonitor = newmonitor;
75 if (newmonitor) {
76 struct Screen *scr = FindFirstScreen(newmonitor, IntuitionBase);
77 UWORD DWidth, DHeight;
79 if (x == -1)
80 x = IntuitionBase->MouseX;
81 if (y == -1)
82 y = IntuitionBase->MouseY;
84 /* A crude copy from inputhandler.c. We should really handle this in monitorclass */
85 if (scr)
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;
90 else
92 /* If there's no active screen, we take 160x160 as a limit */
93 DWidth = 159;
94 DHeight = 159;
96 if (x > DWidth)
97 x = DWidth;
98 if (y > DHeight)
99 y = DHeight;
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)
114 struct Screen *scr;
116 for (scr = IntuitionBase->FirstScreen; scr; scr = scr->NextScreen) {
117 if (GetPrivScreen(scr)->IMonitorNode == monitor)
118 break;
120 return scr;
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);
129 if (newrp)
131 InitRastPort(newrp);
134 return newrp;
137 struct RastPort *MyCloneRastPort(struct IntuitionBase *IntuitionBase, struct RastPort *rp)
139 struct RastPort *newrp = NULL;
141 if (rp)
143 newrp = AllocMem(sizeof(*newrp), MEMF_PUBLIC);
144 if (newrp)
146 CopyMem(rp, newrp, sizeof(struct RastPort));
150 return newrp;
153 void MyFreeRastPort(struct IntuitionBase *IntuitionBase, struct RastPort *rp)
155 if (rp->RP_Extra)
157 /* Just in case... What if someone plays with ClipRects? */
158 FreeVec(rp->RP_Extra);
161 FreeMem(rp, sizeof(*rp));
164 #ifdef __MORPHOS__
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*/
179 if (layer->front)
181 struct Layer *lay;
183 for (lay = layer->front; lay; lay = lay->front)
185 struct Window *lwin = lay->Window;
187 if (lwin && win)
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;
193 return TRUE;
196 return NULL;
198 } else return NULL;
201 #endif
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
212 Forbid();
214 font = *fontptr;
215 if (font)
217 struct TextAttr ta;
219 font->tf_Accessors++;
220 Permit();
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;
229 ret = OpenFont(&ta);
231 /* Unlock it
233 Forbid();
234 font->tf_Accessors--;
237 Permit();
239 return ret;
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 },
253 {TAG_DONE }
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;
269 struct Window *win;
270 struct SharedPointer *oldpointer;
271 struct SharedPointer *newpointer;
272 Object *oldobject;
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;
302 else
304 DEBUG_POINTER(dprintf("InstallPointer: can't change pointer.\n"));
309 oldobject = *old;
310 *old = pointer;
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);
317 UnlockIBase(lock);
320 void SetPointerColors(struct IntuitionBase *IntuitionBase)
322 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
323 struct GfxBase *GfxBase = _intuitionBase->GfxBase;
324 struct Color32 *p;
325 int k;
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;
334 if (scr)
336 #ifndef ALWAYS_ALLOCATE_SPRITE_COLORS
337 if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) < 9)
338 #endif
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);
351 UnlockIBase(lock);
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);
363 if (pointer)
365 pointer->sprite = sprite;
366 pointer->xoffset = x;
367 pointer->yoffset = y;
368 pointer->ref_count = 1;
371 return pointer;
374 void ObtainSharedPointer(struct SharedPointer *pointer,
375 struct IntuitionBase *IntuitionBase)
377 ULONG lock = LockIBase(0);
378 ++pointer->ref_count;
379 UnlockIBase(lock);
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));
393 UnlockIBase(lock);