sys7.1-doc-wip/ProcessMgr/OSDispatch.c

881 lines
24 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
File: OSDispatch.c
Contains: Selected Process Mgr dispatch routines.
Written by: Phil Goldman and Erich Ringewald
Copyright: © 1986-1992 by Apple Computer, Inc., all rights reserved.
Change History (most recent first):
<18> 9/4/92 DRF #1041525,<EA> Changed SameProcess() to handle the case where
there is no current process.
<17> 8/26/92 DTY Change ModSquads funky conditional to use #ifdefs like everyone
else.
<16> 8/26/92 DTY Roll in latest changes for A/UX.
<15> 8/17/92 hjcr Adding support for OCE's "defer drag" feature. Conditionally
compiled under MODSQUAD
<14> 4/10/92 JSM Get rid of compiler warning from last change.
<13> 4/9/92 KST #1025131,<JH>: Changed SWM from a background app to a driver so
that input method can do dialog, change cursor, access the menu,
and type into the dialog window.
<12> 3/25/92 DTY #1024114,<pvh>: Added c_PEntryFromProcessSerialNumber. This is
identical to the PEntryFromPSN routine in Processes.c, except
that this follows Pascal calling conventions and is accessed as
a selector off of OSDispatch. Cube-E Finder needs this routine
so that it doesnt have to rely on hard coded offsets into
Process Manager globals for the application assassin code. The
ultimate solution would be to move the assassin into Launch and
remove this selector.
<11> 1/11/92 YK Added NewTSMLayerOwner and RouteEventToSWM for TSM.
<10> 10/16/91 YK Added c_InlineAware for supporting the Text Services Manager.
<9> 10/9/91 DTY Add #include "OSDispatchPrivate.h" for new definition of
FindAppLayer(). The build was broken because FindAppLayer() was
changed to FindAppBaseLayer(), and FindAppLayer() became a macro
which called the new name. This file wasnt updated to reflect
the new scheme of things.
<8> 1/14/91 DFH Fix checkin comment.
<7> 1/14/91 DFH (dba) Make system mode per process.
<6> 1/14/91 DFH (JDR) Conditionalize out AUX support.
<4> 1/8/91 DFH (rdd) Changed c_SetFrontProcess to allow for case where
destination process is already frontmost, but suspended for
high-level debugging.
<3> 12/20/90 DFH (dba) Remove obsolete dispatch routine TWKill.
<2> 12/5/90 DFH Integrate AUX support.
<0> x/xx/86 PYG New Today.
*/
#include <types.h>
#include <memory.h>
#include <files.h>
#include <quickdraw.h>
#include <windows.h>
#include <menus.h>
#include <events.h>
#include <resources.h>
#include <osutils.h>
#include <toolutils.h>
#include <retrace.h>
#include <desk.h>
#include <dialogs.h>
#include <errors.h>
#include "Glue.h"
#include "Lomem.h"
#include "Data.h"
#include "SysMisc.h"
#include "Aux.h"
#include "Puppet.h"
#include "OSDispatchPrivate.h"
/*------------------------------------------------------------------
Here are the exported (via Trap) task management calls.
------------------------------------------------------------------*/
#pragma segment kernel_segment
/* c_KernelLaunch. Launch a task into a new partition. */
pascal OSErr
c_KernelLaunch(InternalLaunchPBPtr pParams)
{
unsigned long olda5;
OSErr err, NewProcess(InternalLaunchPBPtr);
void DisposeProcessEntry(PEntryPtr);
/* Get access to our globals, and switch to launchee's volume */
olda5 = ProcessMgrA5Setup();
/* Create a new process. Let AUX have the first chance at it. */
#ifdef HAS_AUX_PROCESSMGR
if (AUXIsPresent)
{
err = AUX_Launch(pParams);
if ((err == permErr))
err = NewProcess(pParams);
}
else
#endif HAS_AUX_PROCESSMGR
err = NewProcess(pParams);
A5Restore(olda5);
return(err);
}
/* TWFGSwitch. This routine arranges for a foreground switch from the current application
* to the given one. Note: It is OK for a task to switch to itself, as long as it's not
* currently the foreground task. In this way a background app could force itself to the
* front.
* NOTE: This is the old call, so it just defers to the current one (SetFrontProcess).
*/
pascal long
c_TWFGSWitch(ProcessID pid)
{
PEntryPtr pProc;
/* Locate the process. */
if ((pProc = PEntryFromPID(pid)) == nil)
return(procNotFound);
return(SetFrontProcess(&pProc->p_serialNumber));
}
/* KillProcess. Terminate the given process. Actually, this just puts the process
* in a state where the next switch in will make it ExitToShell. This way, the
* low memory/trap patch/VBL/etc context is correct for the cleanup.
*/
pascal OSErr
c_KillProcess(ProcessSerialNumberPtr pPSN)
{
PEntryPtr pDeadMeat;
unsigned long olda5;
void PushOnStateList(PEntryPtr, PEntryPtr *);
/* Locate the poor thing */
if ((pDeadMeat = PEntryFromPSN(pPSN)) == nil)
return(procNotFound);
/* Special case! */
olda5 = ProcessMgrA5SimpleSetup();
if (pDeadMeat == pCurrentProcess)
ExitToShell();
/* Rouse him from his slumber */
CancelSleep(pDeadMeat);
/* And throw him into the chute */
if (pDeadMeat->p_condemned == wFalse)
{
pDeadMeat->p_condemned = wTrue;
PushOnStateList(pDeadMeat, &pDyingStateList);
}
A5SimpleRestore(olda5);
return(noErr);
}
/* TWGetPID. Return the currently running process ID. */
pascal ProcessID
c_TWGetPID(void)
{
unsigned long olda5;
ProcessID retval;
olda5 = ProcessMgrA5SimpleSetup();
retval = (pCurrentProcess != nil) ? pCurrentProcess->p_mypid : 0;
A5SimpleRestore(olda5);
return(retval);
}
/* TWGetProcInfo. This routine fills in the data of the passed info record for the
* given process ID. Returns noErr for real processes, or procNotFound for a bogus
* ProcessID.
*/
pascal long
c_TWGetProcInfo(ProcessID pid, struct procinfo *inforec)
{
PEntryPtr p, pDadProc;
PCB *pc;
THz savezone;
unsigned long olda5;
if ((p = PEntryFromPID(pid)) == nil)
return(procNotFound);
olda5 = ProcessMgrA5SimpleSetup();
inforec->p_state = p->p_state;
inforec->p_mypid = p->p_mypid;
inforec->p_type = p->p_type;
inforec->p_signature = p->p_signature;
inforec->p_version = p->p_version;
inforec->p_zone = p->p_zone;
inforec->p_taskmode = p->p_taskmode;
inforec->p_needsuspresevts = ((p->p_taskmode & modeNeedSuspendResume) != 0);
inforec->p_back = ((p->p_taskmode & modeCanBackground) != 0);
/* NOTE: Add this when next Finder created:
* inforec->p_isfirstbackevt = p->p_isfirstbackevt;
*/
inforec->p_activateonresume = ((p->p_taskmode & modeDoesActivateOnFGSwitch) != 0);
inforec->p_dad = ((pDadProc = p->p_dadProcess) != nil) ? pDadProc->p_mypid : 0;
inforec->p_size = p->p_size;
inforec->p_ssize = p->p_ssize;
inforec->p_slices = p->p_slices;
assert(p->p_pcb != nil);
pc = *p->p_pcb;
BlockMove(&pc->curapname, &inforec->p_name, 32);
inforec->p_vrefnum = pc->p_vrefnum;
/* NOTE: Assumes FreeMem can not cause ProcessMgrZone to move, since we restore the
* saved zone unconditionally, instead of using SafeSetZone and RestoreZone.
*/
savezone = THEZONE;
THEZONE = p->p_zone;
inforec->p_freemem = (unsigned long)(*p->p_pcb)->appllimit
- (unsigned long)((p->p_zone)->bkLim) + FreeMem();
THEZONE = savezone;
A5SimpleRestore(olda5);
return(noErr);
}
/* c_GetCurrentProcess. Return the serial number of the currently running process.
* NOTE: Must allow for times when there is no current process (e.g. during a switch).
*/
pascal OSErr
c_GetCurrentProcess(ProcessSerialNumberPtr psnStorage)
{
PEntryPtr pCurrProc;
u_long oldA5;
oldA5 = ProcessMgrA5SimpleSetup();
pCurrProc = pCurrentProcess;
if (pCurrProc != nil)
*psnStorage = pCurrProc->p_serialNumber;
else
SetPSN(kNoProcess, psnStorage);
A5SimpleRestore(oldA5);
return(noErr);
}
/* c_GetSystemClientProcess. Return a process serial number to identify the party
* responsible for current system activity. This will be either "the system" or
* the current application.
*/
pascal OSErr
c_GetSystemClientProcess(ProcessSerialNumberPtr psnStorage)
{
OSErr retval;
u_long oldA5;
oldA5 = ProcessMgrA5SimpleSetup();
/* Check depth counter */
if ((pCurrentProcess != nil) && (pCurrentProcess->p_systemModeLevel == 0))
retval = GetCurrentProcess(psnStorage);
else
{
SetPSN(kSystemProcess, psnStorage);
retval = noErr;
}
A5SimpleRestore(oldA5);
return(retval);
}
/* c_GetNextProcess. Return the next highest process serial number in use.
* NOTE: Assumes that the process list is in descending order of p_serialNumber.
*/
#define IS_GTE_PSN(src, dst) \
(((src)->highLongOfPSN != (dst)->highLongOfPSN) ? \
((src)->highLongOfPSN >= (dst)->highLongOfPSN) \
: ((src)->lowLongOfPSN >= (dst)->lowLongOfPSN))
pascal OSErr
c_GetNextProcess(ProcessSerialNumberPtr pParamPSN)
{
register PEntryPtr pProc, pPrev;
ProcessSerialNumberPtr pCheckPSN;
OSErr retVal = noErr;
u_long oldA5;
oldA5 = ProcessMgrA5SimpleSetup();
/* Look for special values */
if (EqualPSNConst(kCurrentProcess, pParamPSN) && (pCurrentProcess != nil))
pCheckPSN = &pCurrentProcess->p_serialNumber;
else
pCheckPSN = pParamPSN;
/* Search the process list */
pPrev = nil;
pProc = pProcessList;
while (pProc != nil)
{
if (IS_GTE_PSN(pCheckPSN, &(pProc->p_serialNumber)))
break;
pPrev = pProc;
pProc = pProc->p_NextProcess;
}
/* If we actually found something, pProc points to the item after the desired
* one (nil if the desired one is last in the list). pPrev points to the desired
* one itself (nil if the desired one is first in the list). Handle these cases.
*/
if (pPrev != nil)
*pParamPSN = pPrev->p_serialNumber;
else
{
SetPSN(kNoProcess, pParamPSN);
retVal = procNotFound;
}
A5SimpleRestore(oldA5);
return (retVal);
}
/* c_GetProcessFromLayer. Identify the process ultimately responsible for the
* given layer. If pLayer is -1, caller is asking for the frontmost process.
*/
pascal OSErr
c_GetProcessFromLayer(ProcessSerialNumberPtr pPSN, LayerPtr pLayer)
{
LayerPtr pAppLayer;
PEntryPtr pOwnerProc;
unsigned long olda5;
OSErr retval;
olda5 = ProcessMgrA5SimpleSetup();
/* Set up probable return value */
retval = noErr;
/* Weed out some bad cases */
if ((pLayer == nil) || (pPSN == nil))
retval = paramErr;
else
{
pAppLayer = (pLayer == (LayerPtr) -1) ? GetFrontAppLayer() : FindAppLayer((WindowPtr) pLayer);
if ( (pAppLayer != nil) && ((pOwnerProc = LayerOwner(pAppLayer)) != nil) )
*pPSN = pOwnerProc->p_serialNumber;
else
retval = procNotFound;
}
/* Return kNoProcess if caller goofed, or there is no front process */
if (retval != noErr)
SetPSN(kNoProcess, pPSN);
A5SimpleRestore(olda5);
return(retval);
}
/* c_SameProcess. Determine whether two ProcessSerialNumbers refer to the
* exact same process. Provided partially for convenience, but mainly so that
* we can keep the format of a PSN private (e.g. might want PSN to have subfields
* with abstract values, like machine ID).
*/
pascal OSErr
c_SameProcess(ProcessSerialNumberPtr pPSN1, ProcessSerialNumberPtr pPSN2, Boolean *pResult)
{
PEntryPtr pCurrProc;
ProcessSerialNumberPtr pCheckPSN1, pCheckPSN2;
u_long oldA5;
/* Weed out the hose heads */
if ( pPSN1 == nil || pPSN2 == nil || pResult == nil )
return(paramErr);
oldA5 = ProcessMgrA5SimpleSetup();
/* Convert special values to real PSNs */
pCheckPSN1 = pPSN1;
pCheckPSN2 = pPSN2;
if ((pCurrProc = pCurrentProcess) != nil)
{
if (EqualPSNConst(kCurrentProcess, pPSN1))
pCheckPSN1 = &pCurrProc->p_serialNumber;
if (EqualPSNConst(kCurrentProcess, pPSN2))
pCheckPSN2 = &pCurrProc->p_serialNumber;
}
#if TheFuture
else // DRF #1041525: Handle case where there is no current process
{
if (EqualPSNConst(kNoProcess, pPSN1))
SetPSN(kNoProcess,pCheckPSN1);
if (EqualPSNConst(kNoProcess, pPSN2))
SetPSN(kNoProcess,pCheckPSN2);
}
#endif
/* Compare them */
*pResult = EqualPSN(pCheckPSN1, pCheckPSN2);
A5SimpleRestore(oldA5);
return(noErr);
}
/* c_GetProcessInformation. Fill caller's record with data about the specified
* process.
*/
/* Size of first ProcessInfoRec we ever defined */
#define FIRSTPROCESSINFORECLENGTH (11*sizeof(long) + 2*sizeof(ProcessSerialNumber))
pascal OSErr
c_GetProcessInformation(ProcessSerialNumberPtr pPSN, ProcessInfoRecPtr pStorage)
{
PEntryPtr pProc, pDadProc;
PCB *pPCB;
OSErr err = noErr;
FSSpecPtr pFileSpec;
FCBPBRec fcbInfo;
THz savezone;
u_long oldA5;
/* check for dupes */
if ((pStorage == nil) || (pStorage->processInfoLength < FIRSTPROCESSINFORECLENGTH))
return(paramErr);
/* Can't do anything if there is no such process */
if ((pProc = PEntryFromPSN(pPSN)) == nil)
return(procNotFound);
/* Fill in the record. */
oldA5 = ProcessMgrA5SimpleSetup();
assert(pProc->p_pcb != nil);
pPCB = *pProc->p_pcb;
if (pStorage->processName != nil)
BlockMove(&pPCB->curapname, pStorage->processName, 32);
pStorage->processNumber = pProc->p_serialNumber;
pStorage->processSignature = pProc->p_signature;
pStorage->processType = pProc->p_type;
pStorage->processMode = pProc->p_taskmode;
/* Get process location, size, and amount of free memory.
* NOTE: Locates PCB via handle so that we are independant of evaluation order (in
* case FreeMem() moves memory).
* NOTE: Assumes FreeMem can not cause ProcessMgrZone to move, since we restore saved
* zone unconditionally, instead of using SafeSetZone and RestoreZone.
*/
pStorage->processLocation = (Ptr) pProc->p_zone;
pStorage->processSize = pProc->p_size;
savezone = THEZONE;
THEZONE = pProc->p_zone;
pStorage->processFreeMem = (unsigned long) (*pProc->p_pcb)->appllimit
- (unsigned long)((pProc->p_zone)->bkLim) + FreeMem();
THEZONE = savezone;
pPCB = *pProc->p_pcb;
/* Get information about launcher */
if ((pDadProc = pProc->p_dadProcess) != nil)
pStorage->processLauncher = pDadProc->p_serialNumber;
else
SetPSN(kNoProcess, &pStorage->processLauncher);
pStorage->processLaunchDate = pPCB->launchDate;
/* Get scheduling information */
pStorage->processActiveTime = pProc->p_activeTime;
/* Get the specification for the application or DA file. */
if ((pFileSpec = pStorage->processAppSpec) != nil)
{
fcbInfo.ioFCBIndx = 0;
fcbInfo.ioRefNum = pPCB->p_fileRefNum;
fcbInfo.ioNamePtr = &pFileSpec->name;
fcbInfo.ioCompletion = nil;
if ((err = PBGetFCBInfo(&fcbInfo, SyncHFS)) == noErr)
{
pFileSpec->vRefNum = fcbInfo.ioFCBVRefNum;
pFileSpec->parID = fcbInfo.ioFCBParID;
}
}
A5SimpleRestore(oldA5);
return(err);
}
/* c_SetFrontProcess. Cause the specified process to become the frontmost. */
pascal OSErr
c_SetFrontProcess(ProcessSerialNumberPtr pPSN)
{
PEntryPtr pProc, pFront;
u_long oldA5;
/* Locate the process */
if ((pProc = PEntryFromPSN(pPSN)) == nil)
return(procNotFound);
/* Can't switch background-only process to the front! */
if ((pProc->p_taskmode & modeOnlyBackground) != 0)
return(appIsDaemon);
oldA5 = ProcessMgrA5SimpleSetup();
pFront = pFrontProcess;
/* Is specified process suspended for high-level debugging? */
if (pProc->p_state == PRNULL)
{
/* Don't allow switch to debuggee unless current process is the debugger. */
if (pCurrentProcess != pDebugProcess)
{
A5SimpleRestore(oldA5);
return(procNotFound);
}
/* If debuggee is still in front, all we need to do is allow it to run */
if (pProc == pFront)
{
pProc->p_state = PRREADY;
A5SimpleRestore(oldA5);
return(noErr);
}
}
/* Don't switch to fg guy! */
if (pProc != pFront)
{
/* Since this may be done from a background app, we wakeup the current
* front process so it can start the coercion.
*/
CancelSleep(pFront);
/* Herd him in */
AddToFrontProcessQueue(pProc);
}
A5SimpleRestore(oldA5);
return(noErr);
}
/* Wakeup. Wake up the given task, or at least tell MF you'd like to. We
* don't adjust the list right now, because this call could be being made by
* an interrupt routine while we are otherwise looking at the list. Instead,
* we flag the list, then do the move at a more synchronous time.
* NOTE: Should we dump this now that WakeupProcess is the public trap?
*/
short
c_Wakeup(ProcessID pid)
{
PEntryPtr pPEntry;
dbmsg("Current app using unpublished TWWakeup trap!");
if ((pPEntry = PEntryFromPID(pid)) == nil)
return(procNotFound);
return(WakeUpProcess(&pPEntry->p_serialNumber));
}
/* c_WakeUpProcess. Rouse the specified process from the sleep induced by waiting
* for an event. We don't adjust the list right now, because this call could be
* being made by an interrupt routine while we are otherwise looking at the list.
* Instead, we flag the list, then do the move at a more synchronous time.
* NOTE: We zero the p_wakeuptime even if p_state != PRSLEEPING. This keeps the
* the app from sleeping at the end of its current event call in some intermediate
* state like PRUPDATE. Of course, this only works if the app is in the event call
* that would sleep him. If instead, it is in the middle of a series (like you might
* see for PRUPDATE), the effect is lost.
*/
pascal OSErr
c_WakeUpProcess(ProcessSerialNumberPtr pPSN)
{
PEntryPtr pPEntry;
u_long oldA5;
/* Can't wake someone who isn't sleeping */
if ((pPEntry = PEntryFromPSN(pPSN)) == nil)
return(procNotFound);
/* Set flag we'll see in scheduler and/or event calls. */
oldA5 = ProcessMgrA5SimpleSetup();
if (pPEntry->p_state == PRSLEEPING)
napOver = true;
pPEntry->p_wakeuptime = 0;
#ifdef HAS_AUX_PROCESSMGR
pPEntry->wakeup_flag++;
#endif HAS_AUX_PROCESSMGR
A5SimpleRestore(oldA5);
return(noErr);
}
/* c_BeginSystemMode. Switch to a mode where GetSystemClientProcess will indicate
* "the system". This is so that the ROM/system can obtain files, memory, etc.
* that will not be tracked by application death.
*/
pascal OSErr
c_BeginSystemMode(void)
{
u_long oldA5;
oldA5 = ProcessMgrA5SimpleSetup();
if (pCurrentProcess != nil)
pCurrentProcess->p_systemModeLevel += 1;
A5SimpleRestore(oldA5);
return(noErr);
}
/* c_EndSystemMode. Potentially switch out of "system mode". Is not really out
* if caller is nested in mode.
*/
pascal OSErr
c_EndSystemMode(void)
{
u_long oldA5;
oldA5 = ProcessMgrA5SimpleSetup();
if ((pCurrentProcess != nil) && (pCurrentProcess->p_systemModeLevel != 0))
pCurrentProcess->p_systemModeLevel -= 1;
A5SimpleRestore(oldA5);
return(noErr);
}
/* NewDesktopLayerOwner. The shell (Finder) calls this trap to gain ownership of the
* desktop appearance. We hand back the DeskPort we found earlier. The shell will
* copy the updateRgn into its own window.
*/
pascal OSErr
c_newdesktoplayerowner(LayerPtr *ppNewLayer)
{
u_long olda5;
OSErr retval;
olda5 = ProcessMgrA5SimpleSetup();
if (desklayerowner == nil)
{
*ppNewLayer = desklayer;
desklayerowner = pCurrentProcess;
retval = noErr;
}
else
retval = protocolErr;
A5SimpleRestore(olda5);
return(retval);
}
// <12> PEntryFromProcessSerialNumber. Locate existing process having given ProcessSerialNumber.
// This routine is a duplicate of PEntryFromPSN in Processes.c so that the Cube-E Finder doesnt
// have hard coded offsets to Process Manager globals to do the application
// assassin stuff. In the long run, we should get rid of this routine, and
// implement the assassin as a new launch flag.
pascal PEntryPtr
c_PEntryFromProcessSerialNumber(ProcessSerialNumberPtr pPSN)
{
register PEntryPtr pProc;
unsigned long oldA5;
/* Weed out the junkies */
if (pPSN == nil)
return(nil);
/* Look first for special value */
oldA5 = ProcessMgrA5SimpleSetup();
if ((pPSN->lowLongOfPSN == kCurrentProcess) && (pPSN->highLongOfPSN == 0))
pProc = pCurrentProcess;
else
{
/* Loop until ProcessSerialNumber matches or end of list */
pProc = pProcessList;
while (pProc != nil)
{
if (EqualPSN(&pProc->p_serialNumber, pPSN))
break;
pProc = pProc->p_NextProcess;
}
}
A5SimpleRestore(oldA5);
return(pProc);
}
/* DisableSwitching. This routine arranges such that the calling process
* will not be switched for any reason.
*/
pascal void
c_DisableSwitching(void)
{
unsigned long olda5;
olda5 = ProcessMgrA5SimpleSetup();
dont_switch++;
A5SimpleRestore(olda5);
}
/* EnableSwitching. This routine arranges such that the calling process
* will be switched for any reason.
*/
pascal void
c_EnableSwitching(void)
{
unsigned long olda5;
olda5 = ProcessMgrA5SimpleSetup();
if (dont_switch > 0)
dont_switch--;
A5SimpleRestore(olda5);
}
PrTypeString globalPrTypeString;
/* [GS]etPrTypeStrings. These routines read and write the name of the current
* printer type for a given process and the current global printer -- the real one.
* NOTE: The interface should be changed to copy the strings because *pLocalStrPtr
* is in the middle of the pcb and thus can move.
*/
pascal char
c_GetPrTypeStrings(PrTypeStringPtr *pLocalStrPtr, PrTypeStringPtr *pGlobalStrPtr)
{
unsigned long olda5;
PrTypeStringHandle prTypeStringHdl;
PCB *pPCB;
char enablePrTypeChanges;
olda5 = ProcessMgrA5SimpleSetup();
#ifndef CHOOSE_CALLS_SETPRTYPESTRINGS
Length(&globalPrTypeString) = 0;
/* Make sure ResLoad is true, so we get the data */
{
Boolean oldResLoad = RESLOAD;
RESLOAD = true;
prTypeStringHdl = GetResource('STR ',-8192);
RESLOAD = oldResLoad;
}
if (prTypeStringHdl != nil)
{
BlockMove(*prTypeStringHdl, &globalPrTypeString, PRTYPE_STRING_SIZE);
ReleaseResource(prTypeStringHdl);
}
#endif
*pGlobalStrPtr = &globalPrTypeString;
assert(pCurrentProcess->p_pcb != nil);
pPCB = *pCurrentProcess->p_pcb;
*pLocalStrPtr = &(pPCB->localPrTypeString);
if (Length(&(pPCB->localPrTypeString)) == 0) /* Is there a local one yet? */
BlockMove(&globalPrTypeString, *pLocalStrPtr, PRTYPE_STRING_SIZE);
enablePrTypeChanges = pPCB->enablePrTypeChanges;
A5SimpleRestore(olda5);
return enablePrTypeChanges;
}
pascal void
c_SetPrTypeStrings(PrTypeStringPtr localStrPtr, PrTypeStringPtr globalStrPtr, char enablePrTypeChanges)
{
unsigned long olda5;
olda5 = ProcessMgrA5SimpleSetup();
if (globalStrPtr != nil)
BlockMove(globalStrPtr, &globalPrTypeString, PRTYPE_STRING_SIZE);
if (localStrPtr != nil)
BlockMove(localStrPtr, &((*pCurrentProcess->p_pcb)->localPrTypeString), PRTYPE_STRING_SIZE);
assert(PRTYPE_CHANGESTATUS_SAME == (-1))
if (enablePrTypeChanges >= 0)
(*pCurrentProcess->p_pcb)->enablePrTypeChanges = enablePrTypeChanges;
A5SimpleRestore(olda5);
}
/* c_TWPostAllPseudoEvent. Don't need anymore. SysError instead. (August 90) */
pascal short
c_TWPostAllPseudoEvent(long signature, long tyype, EventRecord *pEvent, u_short priority)
{
#pragma unused (signature, tyype, pEvent, priority)
SysError(dsCoreErr);
return(noErr);
}
/* c_TWPostPseudoEvent. Don't need anymore. SysError instead. (August 90) */
pascal void
c_TWPostPseudoEvent(ProcessID pid, EventRecord *pEvent, u_short priority)
{
#pragma unused (pid, pEvent, priority)
SysError(dsCoreErr);
}
/* c_SetStdFileDir. Don't support anymore. SysError instead. (August 90) */
pascal void
c_SetStdFileDir(ProcessID pid, short sfSaveDisk, unsigned long curDirID)
{
#pragma unused (pid, sfSaveDisk, curDirID)
SysError(dsCoreErr);
}
/* c_BackgroundNotify. Can't support anymore. SysError instead. (November 89) */
pascal void
c_BackgroundNotify(StringPtr msgStringPtr)
{
#pragma unused (msgStringPtr)
SysError(dsCoreErr);
}
#ifdef MODSQUAD
pascal OSErr c_AcceptDrag(void)
{
u_long oldA5;
OSErr retval = noErr;
//Debugger();
oldA5 = ProcessMgrA5SimpleSetup();
if (pCurrentProcess && pCurrentProcess->p_state == PRSTARTDRAG)
gDragState = DRAG_DONE;
else
retval = protocolErr; // What should I return here?
A5SimpleRestore(oldA5);
return(retval);
}
#endif
/************************************************************************************
* Text Services Manager supporting routine.
************************************************************************************/
pascal Boolean
c_InlineAware(ProcessSerialNumberPtr pPSN, Boolean aware)
{
Boolean prevValue;
PEntryPtr pPEntry;
u_long oldA5;
if ((pPEntry = PEntryFromPSN(pPSN)) == nil)
return(procNotFound);
oldA5 = ProcessMgrA5SimpleSetup();
prevValue = pPEntry->p_inlineAware;
pPEntry->p_inlineAware = aware;
WakeUpProcess(&pFrontProcess->p_serialNumber);
A5SimpleRestore(oldA5);
return(prevValue);
}
pascal OSErr
c_NewTSMLayerOwner( const ProcessSerialNumber *pPSN)
{
OSErr retval;
u_long olda5;
olda5 = ProcessMgrA5SimpleSetup();
if (tsmLayerOwner == nil)
{
tsmLayerOwner = (PEntryPtr)(pPSN->lowLongOfPSN); // owner is the driver refnum
retval = noErr;
}
else
retval = protocolErr;
A5SimpleRestore(olda5);
return(retval);
}
pascal Boolean
c_RouteEventToSWM( Boolean doRoute)
{
Boolean prevValue;
u_long oldA5;
oldA5 = ProcessMgrA5SimpleSetup();
prevValue = routeEvent;
routeEvent = doRoute;
A5SimpleRestore(oldA5);
return(prevValue);
}