235 lines
5.4 KiB
C
235 lines
5.4 KiB
C
|
/*
|
|||
|
* tclMacPanic.c --
|
|||
|
*
|
|||
|
* Source code for the "panic" library procedure used in "Simple Shell";
|
|||
|
* other Mac applications will probably override this with a more robust
|
|||
|
* application-specific panic procedure.
|
|||
|
*
|
|||
|
* Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
|
|||
|
* Copyright (c) 1995-1996 Sun Microsystems, Inc.
|
|||
|
*
|
|||
|
* See the file "license.terms" for information on usage and redistribution
|
|||
|
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|||
|
*
|
|||
|
* SCCS: @(#) tclMacPanic.c 1.11 96/04/01 20:56:27
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
#include <Events.h>
|
|||
|
#include <Controls.h>
|
|||
|
#include <Windows.h>
|
|||
|
#include <TextEdit.h>
|
|||
|
#include <Fonts.h>
|
|||
|
#include <Dialogs.h>
|
|||
|
#include <Icons.h>
|
|||
|
#include <stdarg.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <stdlib.h>
|
|||
|
|
|||
|
#include "tclInt.h"
|
|||
|
|
|||
|
/*
|
|||
|
* constants for panic dialog
|
|||
|
*/
|
|||
|
#define PANICHEIGHT 150 /* Height of dialog */
|
|||
|
#define PANICWIDTH 350 /* Width of dialog */
|
|||
|
#define PANIC_BUTTON_RECT {125, 260, 145, 335} /* Rect for button. */
|
|||
|
#define PANIC_ICON_RECT {10, 20, 42, 52} /* Rect for icon. */
|
|||
|
#define PANIC_TEXT_RECT {10, 65, 140, 330} /* Rect for text. */
|
|||
|
#define ENTERCODE (0x03)
|
|||
|
#define RETURNCODE (0x0D)
|
|||
|
|
|||
|
/*
|
|||
|
* The panicProc variable contains a pointer to an application
|
|||
|
* specific panic procedure.
|
|||
|
*/
|
|||
|
|
|||
|
void (*panicProc) _ANSI_ARGS_(TCL_VARARGS(char *,format)) = NULL;
|
|||
|
|
|||
|
/*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*
|
|||
|
* Tcl_SetPanicProc --
|
|||
|
*
|
|||
|
* Replace the default panic behavior with the specified functiion.
|
|||
|
*
|
|||
|
* Results:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* Side effects:
|
|||
|
* Sets the panicProc variable.
|
|||
|
*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*/
|
|||
|
|
|||
|
void
|
|||
|
Tcl_SetPanicProc(proc)
|
|||
|
void (*proc) _ANSI_ARGS_(TCL_VARARGS(char *,format));
|
|||
|
{
|
|||
|
panicProc = proc;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*
|
|||
|
* MacPanic --
|
|||
|
*
|
|||
|
* Displays panic info..
|
|||
|
*
|
|||
|
* Results:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* Side effects:
|
|||
|
* Sets the panicProc variable.
|
|||
|
*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*/
|
|||
|
|
|||
|
static void
|
|||
|
MacPanic(msg)
|
|||
|
char *msg;
|
|||
|
{
|
|||
|
WindowRef macWinPtr, foundWinPtr;
|
|||
|
Rect macRect;
|
|||
|
Rect buttonRect = PANIC_BUTTON_RECT;
|
|||
|
Rect iconRect = PANIC_ICON_RECT;
|
|||
|
Rect textRect = PANIC_TEXT_RECT;
|
|||
|
ControlHandle okButtonHandle;
|
|||
|
EventRecord event;
|
|||
|
Handle stopIconHandle;
|
|||
|
int part;
|
|||
|
Boolean done = false;
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* Put up an alert without using the Resource Manager (there may
|
|||
|
* be no resources to load). Use the Window and Control Managers instead.
|
|||
|
* We want the window centered on the main monitor. The following
|
|||
|
* should be tested with multiple monitors. Look and see if there is a way
|
|||
|
* not using qd.screenBits.
|
|||
|
*/
|
|||
|
|
|||
|
macRect.top = (qd.screenBits.bounds.top + qd.screenBits.bounds.bottom)
|
|||
|
/ 2 - (PANICHEIGHT / 2);
|
|||
|
macRect.bottom = (qd.screenBits.bounds.top + qd.screenBits.bounds.bottom)
|
|||
|
/ 2 + (PANICHEIGHT / 2);
|
|||
|
macRect.left = (qd.screenBits.bounds.left + qd.screenBits.bounds.right)
|
|||
|
/ 2 - (PANICWIDTH / 2);
|
|||
|
macRect.right = (qd.screenBits.bounds.left + qd.screenBits.bounds.right)
|
|||
|
/ 2 + (PANICWIDTH / 2);
|
|||
|
|
|||
|
macWinPtr = NewWindow(NULL, &macRect, "\p", true, dBoxProc, (WindowRef) -1,
|
|||
|
false, 0);
|
|||
|
if (macWinPtr == NULL) {
|
|||
|
goto exitNow;
|
|||
|
}
|
|||
|
|
|||
|
okButtonHandle = NewControl(macWinPtr, &buttonRect, "\pOK", true,
|
|||
|
0, 0, 1, pushButProc, 0);
|
|||
|
if (okButtonHandle == NULL) {
|
|||
|
CloseWindow(macWinPtr);
|
|||
|
goto exitNow;
|
|||
|
}
|
|||
|
|
|||
|
SelectWindow(macWinPtr);
|
|||
|
SetCursor(&qd.arrow);
|
|||
|
stopIconHandle = GetIcon(kStopIcon);
|
|||
|
|
|||
|
while (!done) {
|
|||
|
if (WaitNextEvent(mDownMask | keyDownMask | updateMask,
|
|||
|
&event, 0, NULL)) {
|
|||
|
switch(event.what) {
|
|||
|
case mouseDown:
|
|||
|
part = FindWindow(event.where, &foundWinPtr);
|
|||
|
|
|||
|
if ((foundWinPtr != macWinPtr) || (part != inContent)) {
|
|||
|
SysBeep(1);
|
|||
|
} else {
|
|||
|
SetPortWindowPort(macWinPtr);
|
|||
|
GlobalToLocal(&event.where);
|
|||
|
part = FindControl(event.where, macWinPtr,
|
|||
|
&okButtonHandle);
|
|||
|
|
|||
|
if ((inButton == part) &&
|
|||
|
(TrackControl(okButtonHandle,
|
|||
|
event.where, NULL))) {
|
|||
|
done = true;
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
case keyDown:
|
|||
|
switch (event.message & charCodeMask) {
|
|||
|
case ENTERCODE:
|
|||
|
case RETURNCODE:
|
|||
|
HiliteControl(okButtonHandle, 1);
|
|||
|
HiliteControl(okButtonHandle, 0);
|
|||
|
done = true;
|
|||
|
}
|
|||
|
break;
|
|||
|
case updateEvt:
|
|||
|
SetPortWindowPort(macWinPtr);
|
|||
|
TextFont(systemFont);
|
|||
|
|
|||
|
BeginUpdate(macWinPtr);
|
|||
|
if (stopIconHandle != NULL) {
|
|||
|
PlotIcon(&iconRect, stopIconHandle);
|
|||
|
}
|
|||
|
TextBox(msg, strlen(msg), &textRect, teFlushDefault);
|
|||
|
DrawControls(macWinPtr);
|
|||
|
EndUpdate(macWinPtr);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
CloseWindow(macWinPtr);
|
|||
|
|
|||
|
exitNow:
|
|||
|
#ifdef TCL_DEBUG
|
|||
|
Debugger();
|
|||
|
#else
|
|||
|
abort();
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*
|
|||
|
* panic --
|
|||
|
*
|
|||
|
* Print an error message and kill the process.
|
|||
|
*
|
|||
|
* Results:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* Side effects:
|
|||
|
* The process dies, entering the debugger if possible.
|
|||
|
*
|
|||
|
*----------------------------------------------------------------------
|
|||
|
*/
|
|||
|
|
|||
|
#pragma ignore_oldstyle on
|
|||
|
void
|
|||
|
panic(char * format, ...)
|
|||
|
{
|
|||
|
va_list varg;
|
|||
|
char errorText[256];
|
|||
|
|
|||
|
if (panicProc != NULL) {
|
|||
|
va_start(varg, format);
|
|||
|
|
|||
|
(void) (*panicProc)(format, varg);
|
|||
|
|
|||
|
va_end(varg);
|
|||
|
} else {
|
|||
|
va_start(varg, format);
|
|||
|
|
|||
|
vsprintf(errorText, format, varg);
|
|||
|
|
|||
|
va_end(varg);
|
|||
|
|
|||
|
MacPanic(errorText);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
#pragma ignore_oldstyle reset
|