Minor fixes to comments.
[AROS.git] / rom / intuition / displaybeep.c
blob594d3edc740645e05e618ba6b369c562056a361f
1 /*
2 Copyright © 1995-2010, 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 HISTORY
57 *****************************************************************************/
59 AROS_LIBFUNC_INIT
61 #if USE_NEWDISPLAYBEEP
63 BOOL AllScreens = FALSE;
64 //ULONG lock;
66 D(bug("INT_DisplayBeep: entry, screen 0x%p\n", screen));
68 #ifdef USEWINDOWLOCK
69 ObtainSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
70 #else
71 return; //RenderScreenBar NOT safe without this
72 #endif
73 //jDc: screenlist will NOT be modified while we hold WINDOWLOCK!
74 //lock = LockIBase(0);
76 /* Start Beep */
77 if (screen == (struct Screen *) -1 || screen == NULL)
79 screen = IntuitionBase->FirstScreen;
80 AllScreens = TRUE;
83 while (screen)
85 D(bug("INT_DisplayBeep: screen 0x%p\n", screen));
87 if (screen->Flags & BEEPING)
89 GetPrivScreen(screen)->BeepingCounter = BEEPTICKS;
91 else
93 screen->Flags |= BEEPING;
95 RenderScreenBar(screen, FALSE, IntuitionBase);
96 D(bug("INT_DisplayBeep: RenderScreenBar done for screen 0x%p\n", screen));
98 GetPrivIBase(IntuitionBase)->BeepingScreens++;
99 GetPrivScreen(screen)->BeepingCounter = BEEPTICKS;
102 screen = AllScreens ? screen->NextScreen : NULL;
105 //UnlockIBase(lock);
107 #ifdef USEWINDOWLOCK
108 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
109 #endif
110 D(bug("INT_DisplayBeep: done\n"));
112 #else /* USE_NEWDISPLAYBEEP */
114 struct MsgPort *TimerMsgPort;
115 struct timerequest *BeepTimerIO;
116 BOOL VisualBeep = TRUE;
117 BOOL AllScreens = FALSE;
118 LONG NumBeeped = 0;
120 TimerMsgPort = CreateMsgPort();
121 if (!TimerMsgPort)
123 return;
126 BeepTimerIO = (struct timerequest *) CreateIORequest (TimerMsgPort, sizeof (struct timerequest));
127 if (!BeepTimerIO)
129 DeleteMsgPort(TimerMsgPort);
130 return;
133 if (OpenDevice ("timer.device", UNIT_VBLANK, (struct IORequest *) BeepTimerIO, 0) != 0)
135 DeleteIORequest((struct IORequest *) BeepTimerIO);
136 DeleteMsgPort(TimerMsgPort);
137 return;
140 BeepTimerIO->tr_node.io_Command = TR_ADDREQUEST;
141 BeepTimerIO->tr_time.tv_secs = 0;
142 BeepTimerIO->tr_time.tv_micro = 200000; // 250000
145 /* Start Beep */
146 if (VisualBeep)
148 if (screen == (struct Screen *) -1 || screen == NULL)
150 //LockIBase();
151 screen = IntuitionBase->FirstScreen;
152 //UnlockIBase();
153 AllScreens = TRUE;
158 Forbid();
159 if (!(screen->Flags & BEEPING))
161 screen->Flags |= BEEPING;
162 Permit();
164 if (GetBitMapAttr(screen->RastPort.BitMap, BMA_DEPTH) <= 8)
165 // visual beep on CLUT-screen
168 struct DrawInfo *DInfo = NULL;
169 UWORD BGPen;
170 ULONG color[3];
172 DInfo = GetScreenDrawInfo (screen);
173 BGPen = DInfo->dri_Pens[BACKGROUNDPEN];
176 GetRGB32 (screen->ViewPort.ColorMap, 0, 1, GetPrivScreen(screen)->DisplayBeepColor0);
177 screen->SaveColor0 = GetRGB4 (screen->ViewPort.ColorMap, 0);
179 SetRGB32 (&screen->ViewPort, 0,
180 beepcolor(GetPrivScreen(screen)->DisplayBeepColor0[0]),
181 beepcolor(GetPrivScreen(screen)->DisplayBeepColor0[1]),
182 beepcolor(GetPrivScreen(screen)->DisplayBeepColor0[2])
185 // FreeScreenDrawInfo (screen, DInfo);
188 else
189 // visual beep on hi- and truecolor screens
191 // struct Window *BeepWindow;
192 struct TagItem window_tags[] =
194 {WA_Left , 0 },
195 {WA_Top , 0 },
196 {WA_Width , -1 },
197 {WA_Height , -1 },
198 {WA_Flags , WFLG_SIMPLE_REFRESH | WFLG_BORDERLESS },
199 {WA_CustomScreen, (IPTR) screen },
200 //{WA_Priority , 50 }, // Place in front of all other windows!
201 {TAG_DONE }
204 GetPrivScreen(screen)->DisplayBeepWindow = (struct Window *) OpenWindowTagList (NULL, window_tags);
205 screen->Flags |= BEEPING;
207 NumBeeped++;
209 //LockIBase();
210 if (AllScreens) screen = screen->NextScreen;
211 //UnlockIBase();
213 else
214 Permit();
217 while (AllScreens && screen);
220 if (NumBeeped)
222 /* Wait */
223 DoIO ((struct IORequest *) BeepTimerIO);
226 /* Stop Beep */
227 if (VisualBeep)
229 if (AllScreens)
231 //LockIBase();
232 screen = IntuitionBase->FirstScreen;
233 //UnlockIBase();
239 Forbid();
240 if (screen->Flags & BEEPING)
242 Permit();
244 if (GetBitMapAttr(screen->RastPort.BitMap, BMA_DEPTH) <= 8)
245 // visual beep on CLUT-screen
247 // SetRGB4 (&screen->ViewPort, 0, screen->SaveColor0 & 0x000F, (screen->SaveColor0 & 0x00F0) >> 4, (screen->SaveColor0 & 0x0F00) >> 8);
248 SetRGB32 (&screen->ViewPort, 0,
249 GetPrivScreen(screen)->DisplayBeepColor0[0],
250 GetPrivScreen(screen)->DisplayBeepColor0[1],
251 GetPrivScreen(screen)->DisplayBeepColor0[2]
254 else
255 // visual beep on hi- and truecolor screens
257 if (GetPrivScreen(screen)->DisplayBeepWindow)
259 CloseWindow (GetPrivScreen(screen)->DisplayBeepWindow);
260 GetPrivScreen(screen)->DisplayBeepWindow = NULL;
264 screen->Flags &= (UWORD) ~BEEPING;
266 else
267 Permit();
269 //LockIBase();
270 if (AllScreens) screen = screen->NextScreen;
271 //UnlockIBase();
274 while (AllScreens && screen);
277 CloseDevice((struct IORequest *) BeepTimerIO);
278 DeleteIORequest((struct IORequest *) BeepTimerIO);
279 DeleteMsgPort(TimerMsgPort);
281 #warning TODO: Make this "multitasking proof"!
282 #warning TODO: Produce beep according to prefs
283 #warning TODO: Check if BEEPING flag is handled correctly
284 #warning TODO: Make BeepWindow 50% transparent! :-)
285 #warning TODO: Use TimerIO (IntuitionBase->TimerIO) instead of self-made BeepTimerIO?
287 #endif /* USE_NEWDISPLAYBEEP */
289 AROS_LIBFUNC_EXIT
290 } /* DisplayBeep */