Build fix, include deflibdefs.h during dependencies generation.
[AROS.git] / rom / exec / useralert.c
blob2e8560cd6c3d5e9aec92283344d686d895f66afd
1 #include <aros/debug.h>
2 #include <exec/alerts.h>
3 #include <intuition/intuition.h>
4 #include <proto/exec.h>
5 #include <proto/intuition.h>
6 #include <proto/kernel.h>
8 #include "etask.h"
9 #include "exec_intern.h"
10 #include "exec_util.h"
12 static char *startstring = "Program failed\n";
13 static char *endstring = "\nWait for disk activity to finish.";
14 static char *deadend_buttons = "More...|Suspend|Reboot";
15 static char *recoverable_buttons = "More...|Continue";
17 #define MORE_SKIP 8
19 static LONG AskSuspend(struct Task *task, ULONG alertNum, struct ExecBase *SysBase)
21 LONG choice = -1;
22 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
24 if (IntuitionBase)
26 char *buffer = AllocMem(ALERT_BUFFER_SIZE, MEMF_ANY);
28 if (buffer)
30 char *buf, *end;
31 struct EasyStruct es = {
32 sizeof (struct EasyStruct),
34 NULL,
35 buffer,
36 NULL,
39 buf = Alert_AddString(buffer, startstring);
40 buf = FormatAlert(buf, alertNum, task, SysBase);
41 end = buf;
42 buf = Alert_AddString(buf, endstring);
43 *buf = 0;
45 es.es_Title = Alert_GetTitle(alertNum);
47 /* Determine set of buttons */
48 es.es_GadgetFormat = (alertNum & AT_DeadEnd) ? deadend_buttons : recoverable_buttons;
50 D(bug("[UserAlert] Body text:\n%s\n", buffer));
51 choice = EasyRequestArgs(NULL, &es, NULL, NULL);
53 if (choice == 1)
55 /* 'More' has been pressed. Append full alert data */
56 FormatAlertExtra(end, task, SysBase);
58 /* Re-post the alert, without 'More...' this time */
59 es.es_GadgetFormat += MORE_SKIP;
60 choice = EasyRequestArgs(NULL, &es, NULL, NULL);
63 FreeMem(buffer, ALERT_BUFFER_SIZE);
66 CloseLibrary(&IntuitionBase->LibNode);
68 return choice;
72 * This function posts alerts in user-mode via Intuition requester.
73 * Returns initial alert code if something fails and 0 if it was a recoverable
74 * alert and everything went ok.
75 * Note that in case of some crashes (e.g. corrupt memory list) this function
76 * may crash itself, and this has to be handled on a lower level. This is
77 * why we do this trick with iet_AlertCode
79 ULONG Exec_UserAlert(ULONG alertNum, struct ExecBase *SysBase)
81 struct Task *task = SysBase->ThisTask;
82 struct IntETask *iet;
83 LONG res;
85 /* Protect ourselves agains really hard crashes where SysBase->ThisTask is NULL.
86 Obviously we won't go far away in such a case */
87 if (!task)
88 return alertNum;
90 /* Get internal task structure */
91 iet = GetIntETask(task);
93 * If we already have alert number for this task, we are in double-crash during displaying
94 * intuition requester. Well, take the initial alert code (because it's more helpful to the programmer)
95 * and proceed with arch-specific Alert().
96 * Since this is a double-crash, we may append AT_DeadEnd flag if our situation has become unrecoverable.
98 D(bug("[UserAlert] Task alert state: 0x%08X\n", iet->iet_AlertCode));
99 if (iet->iet_AlertCode)
102 * Some more logic here. Nested AN_SysScrnType should not make original alert deadend.
103 * It just means we were unable to display it using Intuition requested because there
104 * are no display drivers at all.
106 if (alertNum == AN_SysScrnType)
107 return iet->iet_AlertCode;
108 else
109 return iet->iet_AlertCode | (alertNum & AT_DeadEnd);
113 * Otherwise we can try to put up Intuition requester first. Store alert code in order in ETask
114 * in order to indicate crash condition
116 iet->iet_AlertCode = alertNum;
118 * AN_SysScrnType is somewhat special. We remember it in the ETask (just in case),
119 * but propagate it to supervisor mode immetiately. We do it because this error
120 * means we don't have any display modes, so we won't be able to bring up the requester.
122 if (alertNum == AN_SysScrnType)
123 return alertNum;
125 /* Issue a requester */
126 res = AskSuspend(task, alertNum, SysBase);
127 D(bug("[UserAlert] Requester result: %d\n", res));
129 /* If AskSuspend() failed, fail back to safe-mode alert */
130 if (res == -1)
131 return alertNum;
133 /* Halt if we need to */
134 if (alertNum & AT_DeadEnd)
136 if (res == 0)
138 ColdReboot();
139 /* In case if ColdReboot() doesn't work */
140 ShutdownA(SD_ACTION_COLDREBOOT);
142 D(bug("[UserAlert] Returned from ShutdownA()!\n"));
144 /* Well, stop if the user wants so (or if the reboot didn't work at all) */
145 Wait(0);
148 /* Otherwise clear crash status and return happily */
149 ResetETask(iet);
151 return 0;