add necessary tasklist spinlocks
[AROS.git] / rom / intuition / displaybeep.c
blob6f208cf8e16609aca86f3fe2262619c93238cc18
1 /*
2 Copyright © 1995-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 <proto/graphics.h>
9 #include "intuition_intern.h"
11 #define BEEPTICKS 3 /* in 1/10th sec units */
13 static inline ULONG beepcolor(ULONG x)
15 return x < 0x88888888 ? 0xCCCCCCCC : 0x55555555;
19 /*****************************************************************************
21 NAME */
22 #include <proto/intuition.h>
24 AROS_LH1(void, DisplayBeep,
26 /* SYNOPSIS */
27 AROS_LHA(struct Screen *, screen, A0),
29 /* LOCATION */
30 struct IntuitionBase *, IntuitionBase, 16, Intuition)
32 /* FUNCTION
33 The Amiga has no internal speaker, so it flashes the background
34 color of the specified screen as a signal. If the argument is
35 NULL all screens will be flashed.
37 INPUTS
38 screen - The Screen that will be flashed.
39 If NULL all screens will flash.
41 RESULT
43 NOTES
45 EXAMPLE
47 BUGS
49 SEE ALSO
51 INTERNALS
52 Hardware with a speaker should make an audible beep, too.
53 Maybe even leave out the flashing on those architectures.
55 *****************************************************************************/
57 AROS_LIBFUNC_INIT
59 #if USE_NEWDISPLAYBEEP
61 BOOL AllScreens = FALSE;
62 //ULONG lock;
64 D(bug("INT_DisplayBeep: entry, screen 0x%p\n", screen));
66 #ifdef USEWINDOWLOCK
67 ObtainSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
68 #else
69 return; //RenderScreenBar NOT safe without this
70 #endif
71 //jDc: screenlist will NOT be modified while we hold WINDOWLOCK!
72 //lock = LockIBase(0);
74 /* Start Beep */
75 if (screen == (struct Screen *) -1 || screen == NULL)
77 screen = IntuitionBase->FirstScreen;
78 AllScreens = TRUE;
81 while (screen)
83 D(bug("INT_DisplayBeep: screen 0x%p\n", screen));
85 if (screen->Flags & BEEPING)
87 GetPrivScreen(screen)->BeepingCounter = BEEPTICKS;
89 else
91 screen->Flags |= BEEPING;
93 RenderScreenBar(screen, FALSE, IntuitionBase);
94 D(bug("INT_DisplayBeep: RenderScreenBar done for screen 0x%p\n", screen));
96 GetPrivIBase(IntuitionBase)->BeepingScreens++;
97 GetPrivScreen(screen)->BeepingCounter = BEEPTICKS;
100 screen = AllScreens ? screen->NextScreen : NULL;
103 //UnlockIBase(lock);
105 #ifdef USEWINDOWLOCK
106 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
107 #endif
108 D(bug("INT_DisplayBeep: done\n"));
110 #else /* USE_NEWDISPLAYBEEP */
112 struct MsgPort *TimerMsgPort;
113 struct timerequest *BeepTimerIO;
114 BOOL VisualBeep = TRUE;
115 BOOL AllScreens = FALSE;
116 LONG NumBeeped = 0;
118 TimerMsgPort = CreateMsgPort();
119 if (!TimerMsgPort)
121 return;
124 BeepTimerIO = (struct timerequest *) CreateIORequest (TimerMsgPort, sizeof (struct timerequest));
125 if (!BeepTimerIO)
127 DeleteMsgPort(TimerMsgPort);
128 return;
131 if (OpenDevice ("timer.device", UNIT_VBLANK, (struct IORequest *) BeepTimerIO, 0) != 0)
133 DeleteIORequest((struct IORequest *) BeepTimerIO);
134 DeleteMsgPort(TimerMsgPort);
135 return;
138 BeepTimerIO->tr_node.io_Command = TR_ADDREQUEST;
139 BeepTimerIO->tr_time.tv_secs = 0;
140 BeepTimerIO->tr_time.tv_micro = 200000; // 250000
143 /* Start Beep */
144 if (VisualBeep)
146 if (screen == (struct Screen *) -1 || screen == NULL)
148 //LockIBase();
149 screen = IntuitionBase->FirstScreen;
150 //UnlockIBase();
151 AllScreens = TRUE;
156 Forbid();
157 if (!(screen->Flags & BEEPING))
159 screen->Flags |= BEEPING;
160 Permit();
162 if (GetBitMapAttr(screen->RastPort.BitMap, BMA_DEPTH) <= 8)
163 // visual beep on CLUT-screen
166 struct DrawInfo *DInfo = NULL;
167 UWORD BGPen;
168 ULONG color[3];
170 DInfo = GetScreenDrawInfo (screen);
171 BGPen = DInfo->dri_Pens[BACKGROUNDPEN];
174 GetRGB32 (screen->ViewPort.ColorMap, 0, 1, GetPrivScreen(screen)->DisplayBeepColor0);
175 screen->SaveColor0 = GetRGB4 (screen->ViewPort.ColorMap, 0);
177 SetRGB32 (&screen->ViewPort, 0,
178 beepcolor(GetPrivScreen(screen)->DisplayBeepColor0[0]),
179 beepcolor(GetPrivScreen(screen)->DisplayBeepColor0[1]),
180 beepcolor(GetPrivScreen(screen)->DisplayBeepColor0[2])
183 // FreeScreenDrawInfo (screen, DInfo);
186 else
187 // visual beep on hi- and truecolor screens
189 // struct Window *BeepWindow;
190 struct TagItem window_tags[] =
192 {WA_Left , 0 },
193 {WA_Top , 0 },
194 {WA_Width , -1 },
195 {WA_Height , -1 },
196 {WA_Flags , WFLG_SIMPLE_REFRESH | WFLG_BORDERLESS },
197 {WA_CustomScreen, (IPTR) screen },
198 //{WA_Priority , 50 }, // Place in front of all other windows!
199 {TAG_DONE }
202 GetPrivScreen(screen)->DisplayBeepWindow = (struct Window *) OpenWindowTagList (NULL, window_tags);
203 screen->Flags |= BEEPING;
205 NumBeeped++;
207 //LockIBase();
208 if (AllScreens) screen = screen->NextScreen;
209 //UnlockIBase();
211 else
212 Permit();
215 while (AllScreens && screen);
218 if (NumBeeped)
220 /* Wait */
221 DoIO ((struct IORequest *) BeepTimerIO);
224 /* Stop Beep */
225 if (VisualBeep)
227 if (AllScreens)
229 //LockIBase();
230 screen = IntuitionBase->FirstScreen;
231 //UnlockIBase();
237 Forbid();
238 if (screen->Flags & BEEPING)
240 Permit();
242 if (GetBitMapAttr(screen->RastPort.BitMap, BMA_DEPTH) <= 8)
243 // visual beep on CLUT-screen
245 // SetRGB4 (&screen->ViewPort, 0, screen->SaveColor0 & 0x000F, (screen->SaveColor0 & 0x00F0) >> 4, (screen->SaveColor0 & 0x0F00) >> 8);
246 SetRGB32 (&screen->ViewPort, 0,
247 GetPrivScreen(screen)->DisplayBeepColor0[0],
248 GetPrivScreen(screen)->DisplayBeepColor0[1],
249 GetPrivScreen(screen)->DisplayBeepColor0[2]
252 else
253 // visual beep on hi- and truecolor screens
255 if (GetPrivScreen(screen)->DisplayBeepWindow)
257 CloseWindow (GetPrivScreen(screen)->DisplayBeepWindow);
258 GetPrivScreen(screen)->DisplayBeepWindow = NULL;
262 screen->Flags &= (UWORD) ~BEEPING;
264 else
265 Permit();
267 //LockIBase();
268 if (AllScreens) screen = screen->NextScreen;
269 //UnlockIBase();
272 while (AllScreens && screen);
275 CloseDevice((struct IORequest *) BeepTimerIO);
276 DeleteIORequest((struct IORequest *) BeepTimerIO);
277 DeleteMsgPort(TimerMsgPort);
279 #warning TODO: Make this "multitasking proof"!
280 #warning TODO: Produce beep according to prefs
281 #warning TODO: Check if BEEPING flag is handled correctly
282 #warning TODO: Make BeepWindow 50% transparent! :-)
283 #warning TODO: Use TimerIO (IntuitionBase->TimerIO) instead of self-made BeepTimerIO?
285 #endif /* USE_NEWDISPLAYBEEP */
287 AROS_LIBFUNC_EXIT
288 } /* DisplayBeep */