use the cached method id's to improve performance.
[AROS.git] / rom / intuition / misc.c
blob866278911d6ddc1707eae57b83680da3d32a3743
1 /*
2 Copyright © 2002-2013, 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 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;
300 else
302 DEBUG_POINTER(dprintf("InstallPointer: can't change pointer.\n"));
307 oldobject = *old;
308 *old = pointer;
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);
315 UnlockIBase(lock);
318 void SetPointerColors(struct IntuitionBase *IntuitionBase)
320 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
321 struct GfxBase *GfxBase = _intuitionBase->GfxBase;
322 struct Color32 *p;
323 int k;
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;
332 if (scr)
334 #ifndef ALWAYS_ALLOCATE_SPRITE_COLORS
335 if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) < 9)
336 #endif
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);
349 UnlockIBase(lock);
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);
361 if (pointer)
363 pointer->sprite = sprite;
364 pointer->xoffset = x;
365 pointer->yoffset = y;
366 pointer->ref_count = 1;
369 return pointer;
372 void ObtainSharedPointer(struct SharedPointer *pointer,
373 struct IntuitionBase *IntuitionBase)
375 ULONG lock = LockIBase(0);
376 ++pointer->ref_count;
377 UnlockIBase(lock);
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));
391 UnlockIBase(lock);