728 lines
20 KiB
C
728 lines
20 KiB
C
/* Copyright 1986-1995 by Abacus Research and
|
|
* Development, Inc. All rights reserved.
|
|
*/
|
|
|
|
#if !defined (OMIT_RCSID_STRINGS)
|
|
char ROMlib_rcsid_windInit[] =
|
|
"$Id: windInit.c 88 2005-05-25 03:59:37Z ctm $";
|
|
#endif
|
|
|
|
/* Forward declarations in WindowMgr.h (DO NOT DELETE THIS LINE) */
|
|
|
|
#include "rsys/common.h"
|
|
#include "QuickDraw.h"
|
|
#include "CQuickDraw.h"
|
|
#include "WindowMgr.h"
|
|
#include "ToolboxUtil.h"
|
|
#include "ResourceMgr.h"
|
|
#include "FontMgr.h"
|
|
#include "MemoryMgr.h"
|
|
#include "SegmentLdr.h"
|
|
#include "OSUtil.h"
|
|
#include "OSEvent.h"
|
|
#include "ControlMgr.h"
|
|
#include "MenuMgr.h"
|
|
#include "SysErr.h"
|
|
#include "DialogMgr.h"
|
|
|
|
#include "rsys/cquick.h"
|
|
#include "rsys/wind.h"
|
|
#include "rsys/menu.h"
|
|
#include "rsys/resource.h"
|
|
#include "rsys/system_error.h"
|
|
|
|
#include "rsys/prefs.h"
|
|
#include "rsys/flags.h"
|
|
|
|
#include "rsys/segment.h"
|
|
#include "rsys/file.h"
|
|
#include "rsys/executor.h"
|
|
#include "rsys/custom.h"
|
|
#include "rsys/options.h"
|
|
#include "rsys/launch.h"
|
|
|
|
PUBLIC BOOLEAN ROMlib_dirtyvariant = FALSE;
|
|
|
|
boolean_t system_file_version_skew_p;
|
|
|
|
static void
|
|
exit_executor (void)
|
|
{
|
|
ROMlib_exit = TRUE;
|
|
ExitToShell ();
|
|
}
|
|
|
|
#if !defined (MSDOS)
|
|
PRIVATE char *reinstall = "System and %System";
|
|
#else
|
|
PRIVATE char *reinstall = "EXSYSTEM.HFV";
|
|
#endif
|
|
|
|
P0 (PUBLIC pascal trap, void, InitWindows)
|
|
{
|
|
PatHandle ph;
|
|
PixPatHandle new_ph;
|
|
RgnHandle mrgn, corners;
|
|
|
|
AuxWinHead = RM (default_aux_win);
|
|
SaveVisRgn = NULL;
|
|
|
|
THEPORT_SAVE_EXCURSION
|
|
(thePort,
|
|
{
|
|
/* FIXME: is this a memory leak, to just call InitPort () again? */
|
|
InitPort (MR (WMgrPort));
|
|
InitCPort (MR (WMgrCPort));
|
|
|
|
ph = GetPattern(deskPatID);
|
|
if (ph == NULL)
|
|
{
|
|
fprintf (stderr, "Can't open System file.\n"
|
|
"This is very bad. You will have to reinstall %s"
|
|
" before\n"
|
|
"Executor will work again.\n", reinstall);
|
|
ROMlib_exit = TRUE;
|
|
ExitToShell ();
|
|
}
|
|
new_ph = GetPixPat (deskPatID);
|
|
if (new_ph)
|
|
DeskCPat = RM(new_ph);
|
|
else
|
|
USE_DESKCPAT_VAR &= ~USE_DESKCPAT_BIT;
|
|
InitPalettes ();
|
|
InitMenus ();
|
|
PATASSIGN (DeskPattern, STARH(ph));
|
|
GrayRgn = RM (NewRgn ());
|
|
|
|
OpenRgn ();
|
|
if (ROMlib_creator && !(ROMlib_options & ROMLIB_RECT_SCREEN_BIT))
|
|
FrameRoundRect (&GD_BOUNDS (MR (TheGDevice)), 16, 16);
|
|
else
|
|
FrameRect (&GD_BOUNDS (MR (TheGDevice)));
|
|
CloseRgn (MR (GrayRgn));
|
|
mrgn = NewRgn();
|
|
SetRectRgn(mrgn, 0, 0, CW (GD_BOUNDS (MR (TheGDevice)).right),
|
|
CW(MBarHeight));
|
|
SectRgn(MR(GrayRgn), mrgn, mrgn);
|
|
corners = NewRgn();
|
|
SetRectRgn(corners, 0, 0, CW (GD_BOUNDS (MR (TheGDevice)).right),
|
|
CW (GD_BOUNDS (MR (TheGDevice)).bottom));
|
|
DiffRgn(corners, MR(GrayRgn), corners);
|
|
PaintRgn(corners);
|
|
CopyRgn (MR (GrayRgn), PORT_VIS_REGION (MR (wmgr_port)));
|
|
DiffRgn(MR(GrayRgn), mrgn, MR(GrayRgn));
|
|
PenPat(white);
|
|
PaintRgn(mrgn);
|
|
PenPat(black);
|
|
MoveTo(0, CW(MBarHeight) - 1);
|
|
Line (CW (GD_BOUNDS (MR (TheGDevice)).right), 0);
|
|
if ((USE_DESKCPAT_VAR & USE_DESKCPAT_BIT)
|
|
&& PIXMAP_PIXEL_SIZE (GD_PMAP (MR (MainDevice))) > 2)
|
|
FillCRgn(MR(GrayRgn), MR(DeskCPat));
|
|
else
|
|
FillRgn(MR(GrayRgn), DeskPattern);
|
|
DisposeRgn(mrgn);
|
|
DisposeRgn(corners);
|
|
CopyRgn (MR (GrayRgn), PORT_CLIP_REGION (MR (wmgr_port)));
|
|
WindowList = NULL;
|
|
SaveUpdate = -1;
|
|
PaintWhite = -1;
|
|
DeskHook = NULL;
|
|
GhostWindow = NULL;
|
|
PATASSIGN (DragPattern, gray);
|
|
});
|
|
|
|
/* since there is no `InitControls ()', we do this here */
|
|
ctl_color_init ();
|
|
|
|
WWExist = EXIST_YES;
|
|
|
|
if (ROMlib_creator && ROMlib_creatorsp)
|
|
{
|
|
int i;
|
|
boolean_t found_p;
|
|
int n_vals;
|
|
|
|
n_vals = (ROMlib_creatorsp->head.length /
|
|
sizeof ROMlib_creatorsp->vals[0]);
|
|
for (found_p = FALSE, i = 0; !found_p && i < n_vals; ++i)
|
|
if (ROMlib_creatorsp->vals[i] == (uint32) ROMlib_creator)
|
|
found_p = TRUE;
|
|
|
|
if (!found_p)
|
|
{
|
|
char msg_buf[1024];
|
|
sprintf (msg_buf, "You are trying to run a Macintosh Application "
|
|
"for which this copy of Executor isn't licensed. This "
|
|
"copy of Executor is licensed only to run specific "
|
|
"applications. "
|
|
"Please choose the \"About Executor...\" menu item and "
|
|
"click on the \"License\" button for more information.");
|
|
|
|
system_error (msg_buf, 0,
|
|
"Exit", NULL, NULL,
|
|
C_ExitToShell, NULL, NULL);
|
|
}
|
|
}
|
|
|
|
{
|
|
static boolean_t issued_system_file_version_skew_warning_p = FALSE;
|
|
|
|
if (system_file_version_skew_p
|
|
&& ! issued_system_file_version_skew_warning_p)
|
|
{
|
|
system_error ("\
|
|
The system file you have installed appears to be too old. \
|
|
Executor may die without warning because of this mismatch", 0,
|
|
"Continue", "Exit", NULL,
|
|
NULL, exit_executor, NULL);
|
|
}
|
|
issued_system_file_version_skew_warning_p = TRUE;
|
|
}
|
|
|
|
#if defined (MSDOS)
|
|
{
|
|
static boolean_t issued_cd_warning_p = FALSE;
|
|
|
|
if (cd_mounted_by_trickery_p && !issued_cd_warning_p)
|
|
{
|
|
char *warning_file;
|
|
struct stat sbuf;
|
|
|
|
warning_file = copystr ("+/cdinfo.txt");
|
|
if (warning_file)
|
|
{
|
|
if (stat (warning_file, &sbuf) == 0)
|
|
{
|
|
char buf[1024];
|
|
int i;
|
|
|
|
for (i = strlen (warning_file) -1; i >=0; --i)
|
|
if (warning_file[i] == '/')
|
|
warning_file[i] = '\\';
|
|
|
|
sprintf (buf, "From DOS or Windows, please read the "
|
|
"file \"%s\". "
|
|
"If you don't, Executor won't be "
|
|
"able to read Mac CD-ROMS (except "
|
|
"the Executor CD-ROM, which is special).",
|
|
warning_file);
|
|
system_error (buf, 0,
|
|
"Exit", "Continue", NULL,
|
|
exit_executor, NULL, NULL);
|
|
}
|
|
free (warning_file);
|
|
}
|
|
issued_cd_warning_p = TRUE;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
switch (ROMlib_launch_failure)
|
|
{
|
|
case launch_no_failure:
|
|
break;
|
|
case launch_cfm_requiring:
|
|
system_error ("CFM-requiring applications are not currently supported.",
|
|
0, "OK", NULL, NULL, NULL, NULL, NULL);
|
|
break;
|
|
case launch_ppc_only:
|
|
#if !defined (powerpc) && !defined (__ppc__)
|
|
system_error ("That application is PowerPC-only. This version of "
|
|
"Executor doesn't run PowerPC applications. "
|
|
"You need to find an M68k version of that application.",
|
|
0, "OK", NULL, NULL, NULL, NULL, NULL);
|
|
#else
|
|
system_error ("That application is PowerPC-only. To attempt to run "
|
|
"it, Executor must be started using the \"-ppc\" "
|
|
"command-line switch.",
|
|
0, "OK", NULL, NULL, NULL, NULL, NULL);
|
|
#endif
|
|
break;
|
|
case launch_damaged:
|
|
system_error ("That application appears damaged (lacks CODE and cfrg).",
|
|
0, "OK", NULL, NULL, NULL, NULL, NULL);
|
|
break;
|
|
|
|
case launch_compressed_ge7:
|
|
system_error ("That application has a compressed CODE 0. "
|
|
"It is probably unusable under Executor but "
|
|
"might work in System 6 mode",
|
|
0, "OK", NULL, NULL, NULL, NULL, NULL);
|
|
break;
|
|
case launch_compressed_lt7:
|
|
system_error ("That application has a compressed CODE 0. "
|
|
"It will not run under this version of Executor.",
|
|
0, "OK", NULL, NULL, NULL, NULL, NULL);
|
|
break;
|
|
|
|
default:
|
|
warning_unexpected ("%d", ROMlib_launch_failure);
|
|
break;
|
|
}
|
|
ROMlib_launch_failure = launch_no_failure;
|
|
|
|
if (! size_info.application_p)
|
|
return;
|
|
|
|
/* only issue warnings once */
|
|
size_info.application_p = FALSE;
|
|
|
|
if ((! size_info.size_resource_present_p
|
|
|| (size_info.size_flags & SZis32BitCompatible) != SZis32BitCompatible)
|
|
&& !ROMlib_nowarn32)
|
|
{
|
|
system_error ("This application doesn't claim to be \"32 bit clean\". "
|
|
"It is quite possible that this program will not work "
|
|
"under Executor.", 0,
|
|
"Continue", "Restart", NULL,
|
|
NULL, C_ExitToShell, NULL);
|
|
}
|
|
|
|
if (size_info.size_resource_present_p
|
|
&& ROMlib_applzone_size < size_info.preferred_size)
|
|
{
|
|
char msg_buf[1024];
|
|
int applzone_in_k, preferred_size_in_k;
|
|
|
|
applzone_in_k = ROMlib_applzone_size / 1024;
|
|
preferred_size_in_k = (size_info.preferred_size + 1023) / 1024;
|
|
|
|
sprintf (msg_buf, "This application prefers `%dk' of memory, "
|
|
"but only '%dk' of memory is available in the application "
|
|
"zone. You should exit Executor and run it again "
|
|
"with \"-applzone %dk\".", preferred_size_in_k, applzone_in_k,
|
|
preferred_size_in_k);
|
|
|
|
system_error (msg_buf, 0,
|
|
"Continue", "Browser", "Exit",
|
|
NULL, C_ExitToShell, exit_executor);
|
|
}
|
|
}
|
|
|
|
P1 (PUBLIC pascal trap, void, GetWMgrPort, HIDDEN_GrafPtr *, wp)
|
|
{
|
|
wp->p = WMgrPort;
|
|
}
|
|
|
|
P1 (PUBLIC pascal trap, void, GetCWMgrPort, HIDDEN_CGrafPtr *, wp)
|
|
{
|
|
wp->p = WMgrCPort;
|
|
}
|
|
|
|
P1(PUBLIC pascal trap, void, SetDeskCPat, PixPatHandle, ph)
|
|
{
|
|
PatHandle bw_ph;
|
|
|
|
if (ph)
|
|
{
|
|
DeskCPat = RM(ph);
|
|
USE_DESKCPAT_VAR |= USE_DESKCPAT_BIT;
|
|
}
|
|
else
|
|
{
|
|
bw_ph = GetPattern(deskPatID);
|
|
PATASSIGN(DeskPattern, STARH(bw_ph));
|
|
USE_DESKCPAT_VAR &= ~USE_DESKCPAT_BIT;
|
|
}
|
|
PaintOne((WindowPeek) 0, MR(GrayRgn));
|
|
}
|
|
|
|
void
|
|
ROMlib_new_window_common (WindowPeek w,
|
|
int allocated_p, int cwindow_p,
|
|
Rect *bounds, StringPtr title, BOOLEAN visible_p,
|
|
INTEGER proc_id, WindowPtr behind,
|
|
BOOLEAN go_away_flag, LONGINT ref_con)
|
|
{
|
|
WindowPeek t_w;
|
|
AuxWinHandle t_aux_w;
|
|
GrafPtr save_port;
|
|
|
|
save_port = thePort;
|
|
if (!title)
|
|
title = (StringPtr) ""; /* thank MS Word for pointing this out */
|
|
if (!behind)
|
|
{
|
|
WINDOW_NEXT_WINDOW_X (w) = CLC (0);
|
|
if (WindowList)
|
|
{
|
|
for (t_w = MR (WindowList);
|
|
WINDOW_NEXT_WINDOW_X (t_w);
|
|
t_w = WINDOW_NEXT_WINDOW (t_w))
|
|
;
|
|
WINDOW_NEXT_WINDOW_X (t_w) = RM (w);
|
|
}
|
|
else
|
|
{
|
|
WindowList = RM (w);
|
|
if (visible_p)
|
|
{
|
|
/* notify the palette manager that the `FrontWindow ()'
|
|
may have changed */
|
|
pm_front_window_maybe_changed_hook ();
|
|
}
|
|
}
|
|
}
|
|
else if (behind == (WindowPtr) -1L)
|
|
{
|
|
WINDOW_NEXT_WINDOW_X (w) = WindowList;
|
|
WindowList = (WindowPeek) RM (w);
|
|
if (visible_p)
|
|
{
|
|
/* notify the palette manager that the `FrontWindow ()' may have
|
|
changed */
|
|
pm_front_window_maybe_changed_hook ();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WINDOW_NEXT_WINDOW_X (w) = WINDOW_NEXT_WINDOW_X (behind);
|
|
WINDOW_NEXT_WINDOW_X (behind) = (WindowPeek) RM (w);
|
|
}
|
|
WINDOW_KIND_X (w) = CWC (userKind);
|
|
WINDOW_VISIBLE_X (w) = visible_p;
|
|
for (t_w = MR (WindowList);
|
|
t_w && !WINDOW_VISIBLE (t_w);
|
|
t_w = WINDOW_NEXT_WINDOW (t_w))
|
|
;
|
|
WINDOW_HILITED_X (w) = visible_p && (t_w == w);
|
|
if (WINDOW_HILITED_X (w))
|
|
{
|
|
CurActivate = (WindowPtr) RM (w);
|
|
for (t_w = WINDOW_NEXT_WINDOW (t_w);
|
|
t_w && !WINDOW_HILITED_X (t_w);
|
|
t_w = WINDOW_NEXT_WINDOW (t_w))
|
|
;
|
|
}
|
|
else
|
|
t_w = 0; /* t_w will be used later */
|
|
WINDOW_GO_AWAY_FLAG_X (w) = go_away_flag;
|
|
WINDOW_SPARE_FLAG_X (w) = 0; /* will be used zoombox (wNew) */
|
|
WINDOW_DATA_X (w) = 0;
|
|
WINDOW_STRUCT_REGION_X (w) = RM (NewRgn ());
|
|
WINDOW_CONT_REGION_X (w) = RM (NewRgn ());
|
|
WINDOW_UPDATE_REGION_X (w) = RM (NewRgn ());
|
|
WINDOW_DEF_PROC_X (w) = RM (GetResource (TICK ("WDEF"), proc_id >> 4));
|
|
if (!WINDOW_DEF_PROC_X (w))
|
|
{
|
|
WINDOW_DEF_PROC_X (w) = RM (GetResource (TICK ("WDEF"), 0));
|
|
if (!WINDOW_DEF_PROC_X (w))
|
|
{
|
|
if (allocated_p)
|
|
DisposPtr ((Ptr) w);
|
|
/* fatal_error ("no window (?)"); */
|
|
gui_fatal ("Unable to find WDEF.");
|
|
}
|
|
}
|
|
|
|
t_aux_w = (AuxWinHandle) NewHandle (sizeof (AuxWinRec));
|
|
HxX (t_aux_w, awNext) = AuxWinHead;
|
|
HxX (t_aux_w, awOwner) = (WindowPtr) RM (w);
|
|
HxX (t_aux_w, awCTable) = (CTabHandle) RM (GetResource (TICK("wctb"), 0));
|
|
HxX (t_aux_w, dialogCItem) = 0;
|
|
HxX (t_aux_w, awFlags) = CL ((proc_id & 0xF) << 24);
|
|
HxX (t_aux_w, awReserved) = 0;
|
|
HxX (t_aux_w, awRefCon) = 0;
|
|
AuxWinHead = RM (t_aux_w);
|
|
|
|
{
|
|
HIDDEN_Handle t;
|
|
|
|
PtrToHand ((Ptr) title, &t, (LONGINT) title[0] + 1);
|
|
WINDOW_TITLE_X (w) = (StringHandle) RM (t.p);
|
|
}
|
|
|
|
if (cwindow_p)
|
|
OpenCPort ((CGrafPtr) w);
|
|
else
|
|
OpenPort ((GrafPtr) w);
|
|
OffsetRect (&PORT_BOUNDS (w), -CW (bounds->left), -CW (bounds->top));
|
|
PORT_RECT (w) = *bounds;
|
|
OffsetRect (&PORT_RECT (w), -CW (bounds->left), -CW (bounds->top));
|
|
LOCK_HANDLE_EXCURSION_1
|
|
(WINDOW_TITLE (w),
|
|
{
|
|
WINDOW_TITLE_WIDTH_X (w) = CW (StringWidth (STARH (WINDOW_TITLE (w))));
|
|
});
|
|
|
|
TextFont (applFont);
|
|
WINDOW_CONTROL_LIST_X (w) = CWC (0);
|
|
WINDOW_PIC_X (w) = CWC (0);
|
|
WINDOW_REF_CON_X (w) = CL (ref_con);
|
|
WINDCALL ((WindowPtr) w, wNew, 0);
|
|
if (WINDOW_VISIBLE_X (w))
|
|
{
|
|
THEPORT_SAVE_EXCURSION
|
|
(MR (wmgr_port),
|
|
{
|
|
WINDCALL ((WindowPtr) w, wCalcRgns, 0);
|
|
SetClip (WINDOW_STRUCT_REGION (w));
|
|
ClipAbove (w);
|
|
PenPat (black);
|
|
WINDCALL ((WindowPtr) w, wDraw, 0);
|
|
CalcVis (w);
|
|
EraseRgn (WINDOW_CONT_REGION (w));
|
|
CopyRgn (WINDOW_CONT_REGION (w), WINDOW_UPDATE_REGION (w));
|
|
if (WINDOW_NEXT_WINDOW_X (w))
|
|
CalcVisBehind (WINDOW_NEXT_WINDOW (w), WINDOW_STRUCT_REGION (w));
|
|
});
|
|
}
|
|
else
|
|
SetEmptyRgn (PORT_VIS_REGION (w));
|
|
if (t_w)
|
|
{
|
|
HiliteWindow ((WindowPtr) t_w, FALSE);
|
|
CurDeactive = (WindowPtr) RM (t_w);
|
|
}
|
|
|
|
SetPort (save_port);
|
|
}
|
|
|
|
P8 (PUBLIC pascal trap, WindowPtr, NewWindow,
|
|
Ptr, window_storage, Rect *, bounds, StringPtr, title,
|
|
BOOLEAN, visible_p, INTEGER, proc_id, WindowPtr, behind,
|
|
BOOLEAN, go_away_flag, LONGINT, ref_con)
|
|
{
|
|
WindowPeek w;
|
|
int allocated_p = 0;
|
|
|
|
if (!window_storage)
|
|
{
|
|
allocated_p = 1;
|
|
/* Hack for Dark Castle Demo. They call NewWindow and expect us to
|
|
create the storage. Immediately after calling NewWindow they set
|
|
the windowKind field to dialogKind. Later they call UpdateDialog
|
|
on this window and we die a horrible death since we try to refer
|
|
to a field that isn't present. I don't know how they get away with
|
|
it on the Mac, but I doubt that this particular hack will hurt us
|
|
elsewhere. At some point we should find out why it works on the
|
|
Mac and then get rid of this evil hack. ctm 97/06/01 */
|
|
{
|
|
int size;
|
|
|
|
#define DARK_CASTLE_HACK
|
|
#if defined(DARK_CASTLE_HACK)
|
|
#warning DARK_CASTLE_HACK
|
|
if (strncmp ((char *) title+1, "Modal", 5) == 0)
|
|
size = sizeof (DialogRecord);
|
|
else
|
|
size = sizeof *w;
|
|
w = (WindowPeek) _NewPtr_flags (size, FALSE, TRUE);
|
|
#else
|
|
w = (WindowPeek) NewPtr (sizeof *w);
|
|
#endif
|
|
}
|
|
}
|
|
else
|
|
w = (WindowPeek) window_storage;
|
|
|
|
ROMlib_new_window_common (w, allocated_p, 0,
|
|
bounds, title, visible_p, proc_id, behind,
|
|
go_away_flag, ref_con);
|
|
return (WindowPtr) w;
|
|
}
|
|
|
|
P8 (PUBLIC pascal trap, CWindowPtr, NewCWindow,
|
|
Ptr, window_storage, Rect *, bounds, StringPtr, title,
|
|
BOOLEAN, visible_p, INTEGER, proc_id, CWindowPtr, behind,
|
|
BOOLEAN, go_away_flag, LONGINT, ref_con)
|
|
{
|
|
WindowPeek w;
|
|
int allocated_p = 0;
|
|
|
|
if (!window_storage)
|
|
{
|
|
allocated_p = 1;
|
|
w = (WindowPeek) NewPtr (sizeof *w);
|
|
}
|
|
else
|
|
w = (WindowPeek) window_storage;
|
|
|
|
ROMlib_new_window_common (w, allocated_p, 1,
|
|
bounds, title, visible_p, proc_id,
|
|
(WindowPtr) behind,
|
|
go_away_flag, ref_con);
|
|
return (CWindowPtr) w;
|
|
}
|
|
|
|
typedef windrestype *windrestypeptr;
|
|
MAKE_HIDDEN(windrestypeptr);
|
|
typedef HIDDEN_windrestypeptr *windrestypehand;
|
|
|
|
P3 (PUBLIC pascal trap, CWindowPtr, GetNewCWindow,
|
|
INTEGER, window_id,
|
|
Ptr, window_storage,
|
|
CWindowPtr, behind)
|
|
{
|
|
|
|
CWindowPtr new_cwin;
|
|
windrestypehand win_res;
|
|
Handle win_ctab_res;
|
|
PaletteHandle palette;
|
|
|
|
win_res = (windrestypehand) ROMlib_getrestid (TICK ("WIND"), window_id);
|
|
if (win_res == NULL)
|
|
return (CWindowPtr) NULL;
|
|
|
|
new_cwin = NewCWindow (window_storage, &HxX (win_res, _wrect),
|
|
(StringPtr) ((char *) &HxX (win_res, _wrect) + 18),
|
|
Hx (win_res, _wvisible) != 0,
|
|
Hx (win_res, _wprocid),
|
|
behind, Hx (win_res, _wgoaway) != 0,
|
|
CL (*(LONGINT *) ((char *) &HxX (win_res, _wrect) + 14)));
|
|
|
|
|
|
win_ctab_res = ROMlib_getrestid (TICK ("wctb"), window_id);
|
|
if (win_ctab_res != NULL)
|
|
{
|
|
THEPORT_SAVE_EXCURSION
|
|
(thePort,
|
|
{
|
|
SetWinColor ((WindowPtr) new_cwin, (CTabHandle) win_ctab_res);
|
|
});
|
|
}
|
|
|
|
/* if this is a color window we must check if a palette
|
|
corresponding to this window id exists */
|
|
|
|
palette = GetNewPalette (window_id);
|
|
if (palette)
|
|
NSetPalette ((WindowPtr) new_cwin, palette, pmAllUpdates);
|
|
|
|
return new_cwin;
|
|
}
|
|
|
|
P3(PUBLIC pascal trap, WindowPtr, GetNewWindow, INTEGER, wid, Ptr, wst,
|
|
WindowPtr, behind)
|
|
{
|
|
windrestypehand wh;
|
|
WindowPtr tp;
|
|
|
|
wh = (windrestypehand) GetResource(TICK("WIND"), wid);
|
|
if (!wh)
|
|
return(0);
|
|
if (!(*wh).p)
|
|
LoadResource((Handle) wh);
|
|
tp = NewWindow(wst, &(HxX(wh, _wrect)),
|
|
(StringPtr) ((char *) &HxX(wh, _wrect) + 18),
|
|
Hx(wh, _wvisible) != 0, Hx(wh, _wprocid), (WindowPtr) behind,
|
|
Hx(wh, _wgoaway) != 0,
|
|
CL(*(LONGINT *)( (char *) &HxX(wh, _wrect) + 14)));
|
|
return(tp);
|
|
}
|
|
|
|
/*
|
|
* NOTE below: On the Mac+ if after you close a window, the top most
|
|
* window is non-visible, it will shuffle things.
|
|
*/
|
|
|
|
P1(PUBLIC pascal trap, void, CloseWindow, WindowPtr, w)
|
|
{
|
|
WindowPeek wptmp;
|
|
GrafPtr savgp;
|
|
MAKE_HIDDEN(AuxWinHandle);
|
|
AuxWinHandle saveauxh;
|
|
HIDDEN_AuxWinHandle *auxhp;
|
|
ControlHandle c, t;
|
|
|
|
if (FrontWindow () == w)
|
|
{
|
|
wptmp = ROMlib_firstvisible ((WindowPtr) WINDOW_NEXT_WINDOW (w));
|
|
if (wptmp)
|
|
{
|
|
HiliteWindow ((WindowPtr) wptmp, TRUE);
|
|
CurActivate = (WindowPtr) RM (wptmp);
|
|
}
|
|
}
|
|
if (MR (WindowList) == (WindowPeek) w)
|
|
{
|
|
WindowList = WINDOW_NEXT_WINDOW_X (w);
|
|
wptmp = MR(WindowList);
|
|
} else {
|
|
for (wptmp = MR (WindowList);
|
|
wptmp && WINDOW_NEXT_WINDOW (wptmp) != (WindowPeek) w;
|
|
wptmp = WINDOW_NEXT_WINDOW (wptmp))
|
|
;
|
|
if (wptmp)
|
|
WINDOW_NEXT_WINDOW_X (wptmp) = WINDOW_NEXT_WINDOW_X (w);
|
|
}
|
|
|
|
/* notify the palette manager this window has been deleted */
|
|
pm_window_closed (w);
|
|
|
|
/* notify the palette manager that the `FrontWindow ()' may have
|
|
changed */
|
|
pm_front_window_maybe_changed_hook ();
|
|
|
|
/* NOTE: tests have shown that the behaviour implemented below is
|
|
indeed what a Mac+ does */
|
|
|
|
/* NOTE: we can't use THEPORT_SAVE_EXCURSION here, becuase of this
|
|
odd behavior */
|
|
savgp = thePort == (GrafPtr) w ? (GrafPtr) MR (wmgr_port) : thePort;
|
|
SetPort (MR (wmgr_port));
|
|
SetClip (MR (GrayRgn));
|
|
PaintBehind (WINDOW_NEXT_WINDOW (w), WINDOW_STRUCT_REGION (w));
|
|
if (WINDOW_NEXT_WINDOW_X (w))
|
|
CalcVisBehind (WINDOW_NEXT_WINDOW (w), WINDOW_STRUCT_REGION (w));
|
|
|
|
DisposeRgn (WINDOW_STRUCT_REGION (w));
|
|
DisposeRgn (WINDOW_CONT_REGION (w));
|
|
DisposeRgn (WINDOW_UPDATE_REGION (w));
|
|
DisposHandle ((Handle) WINDOW_TITLE (w));
|
|
for (auxhp = (HIDDEN_AuxWinHandle *) &AuxWinHead;
|
|
(*auxhp).p && STARH(STARH(auxhp))->awOwner != RM(w);
|
|
auxhp = (HIDDEN_AuxWinHandle *) &STARH(STARH(auxhp))->awNext)
|
|
;
|
|
if ((*auxhp).p)
|
|
{
|
|
saveauxh = STARH(auxhp);
|
|
(*auxhp).p = STARH(STARH(auxhp))->awNext;
|
|
DisposHandle((Handle) saveauxh);
|
|
}
|
|
|
|
#if defined (NOTAGOODIDEA)
|
|
#warning "what the hell does this mean?! DANGER WILL ROBINSON!"
|
|
Cx(* (Ptr *) Cx)(((WindowPeek)w)->windowDefProc) = 0;
|
|
DisposHandle(Cx(((WindowPeek)w)->windowDefProc));
|
|
#endif /* NOTAGOODIDEA */
|
|
|
|
/*
|
|
* TODO: Fix this. Tests on the mac show that KillControls is called,
|
|
* but just replacing the for loop causes many apps to die. It could
|
|
* be because some window information that DisposeControl wants is
|
|
* destroyed already, or it could be DisposeControl or KillControl
|
|
* makes some FALSE assumptions. More tests need to be written.
|
|
*/
|
|
#if 1
|
|
for (c = WINDOW_CONTROL_LIST (w); c;)
|
|
{
|
|
t = c;
|
|
c = HxP (c, nextControl);
|
|
#if 0
|
|
DisposHandle(Hx(t, contrlDefProc));
|
|
#endif /* 0 */
|
|
DisposHandle((Handle) t);
|
|
}
|
|
#else /* 0 */
|
|
KillControls(w);
|
|
#endif /* 0 */
|
|
|
|
if (WINDOW_PIC_X (w))
|
|
KillPicture (WINDOW_PIC (w));
|
|
ClosePort ((GrafPtr) w);
|
|
SetPort (savgp);
|
|
if (MR (CurActivate) == w)
|
|
CurActivate = 0;
|
|
if (MR (CurDeactive) == w)
|
|
CurDeactive = 0;
|
|
WINDCALL((WindowPtr) w, wDispose, 0);
|
|
}
|
|
|
|
P1 (PUBLIC pascal trap, void, DisposeWindow, WindowPtr, w)
|
|
{
|
|
CloseWindow(w);
|
|
DisposPtr((Ptr) w);
|
|
}
|