Improved debug messages and added missing properties.
[AROS.git] / rom / intuition / misc.c
blobdde1cde3e6c8ef98a1d1270e502ab634fa92453d
1 /*
2 Copyright © 2002-2011, 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 Object *mon = GetPrivIBase(IntuitionBase)->ActiveMonitor;
26 if (mon)
27 DoMethod(mon, MM_SetPointerPos, IntuitionBase->MouseX, IntuitionBase->MouseY);
30 BOOL ResetPointer(struct IntuitionBase *IntuitionBase)
33 Object *mon;
34 struct SharedPointer *pointer = NULL;
35 Object *obj = GetPrivIBase(IntuitionBase)->DefaultPointer;
36 BOOL res = TRUE;
38 if (obj)
39 GetAttr(POINTERA_SharedPointer, obj, (IPTR *)&pointer);
40 D(bug("[ResetPointer] Default pointer is 0x%p\n", pointer));
41 if (!pointer)
42 return TRUE;
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))
50 res = FALSE;
54 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->MonitorListSem);
56 D(bug("[ResetPointer] Returning %d\n", res));
57 return 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)
67 return;
69 if (oldmonitor)
70 SetAttrs(oldmonitor, MA_PointerVisible, FALSE, TAG_DONE);
72 GetPrivIBase(IntuitionBase)->ActiveMonitor = newmonitor;
73 if (newmonitor) {
74 struct Screen *scr = FindFirstScreen(newmonitor, IntuitionBase);
75 UWORD DWidth, DHeight;
77 if (x == -1)
78 x = IntuitionBase->MouseX;
79 if (y == -1)
80 y = IntuitionBase->MouseY;
82 /* A crude copy from inputhandler.c. We should really handle this in monitorclass */
83 if (scr)
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;
88 else
90 /* If there's no active screen, we take 160x160 as a limit */
91 DWidth = 159;
92 DHeight = 159;
94 if (x > DWidth)
95 x = DWidth;
96 if (y > DHeight)
97 y = DHeight;
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)
112 struct Screen *scr;
114 for (scr = IntuitionBase->FirstScreen; scr; scr = scr->NextScreen) {
115 if (GetPrivScreen(scr)->MonitorObject == monitor)
116 break;
118 return scr;
121 struct RastPort *MyCreateRastPort(struct IntuitionBase *IntuitionBase)
123 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
124 struct RastPort *newrp = AllocMem(sizeof(*newrp), MEMF_PUBLIC);
126 if (newrp)
128 InitRastPort(newrp);
131 return newrp;
134 struct RastPort *MyCloneRastPort(struct IntuitionBase *IntuitionBase, struct RastPort *rp)
136 struct RastPort *newrp = NULL;
138 if (rp)
140 newrp = AllocMem(sizeof(*newrp), MEMF_PUBLIC);
141 if (newrp)
143 CopyMem(rp, newrp, sizeof(struct RastPort));
147 return newrp;
150 void MyFreeRastPort(struct IntuitionBase *IntuitionBase, struct RastPort *rp)
152 if (rp->RP_Extra)
154 /* Just in case... What if someone plays with ClipRects? */
155 FreeVec(rp->RP_Extra);
158 FreeMem(rp, sizeof(*rp));
161 #ifdef __MORPHOS__
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*/
176 if (layer->front)
178 struct Layer *lay;
180 for (lay = layer->front; lay; lay = lay->front)
182 struct Window *lwin = lay->Window;
184 if (lwin && win)
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;
190 return TRUE;
193 return NULL;
195 } else return NULL;
198 #endif
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
208 Forbid();
210 font = *fontptr;
211 if (font)
213 struct TextAttr ta;
215 font->tf_Accessors++;
216 Permit();
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;
225 ret = OpenFont(&ta);
227 /* Unlock it
229 Forbid();
230 font->tf_Accessors--;
233 Permit();
235 return ret;
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 },
248 {TAG_DONE }
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;
264 struct Window *win;
265 struct SharedPointer *oldpointer;
266 struct SharedPointer *newpointer;
267 Object *oldobject;
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;
295 else
297 DEBUG_POINTER(dprintf("InstallPointer: can't change pointer.\n"));
302 oldobject = *old;
303 *old = pointer;
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);
310 UnlockIBase(lock);
313 void SetPointerColors(struct IntuitionBase *IntuitionBase)
315 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
316 struct Color32 *p;
317 int k;
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;
326 if (scr)
328 #ifndef ALWAYS_ALLOCATE_SPRITE_COLORS
329 if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) < 9)
330 #endif
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);
343 UnlockIBase(lock);
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);
355 if (pointer)
357 pointer->sprite = sprite;
358 pointer->xoffset = x;
359 pointer->yoffset = y;
360 pointer->ref_count = 1;
363 return pointer;
366 void ObtainSharedPointer(struct SharedPointer *pointer,
367 struct IntuitionBase *IntuitionBase)
369 ULONG lock = LockIBase(0);
370 ++pointer->ref_count;
371 UnlockIBase(lock);
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));
384 UnlockIBase(lock);