eudora-mac/menusharing.c

1 line
53 KiB
C
Executable File

/* Copyright (c) 2017, Computer History Museum
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted (subject to
the limitations in the disclaimer below) provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of Computer History Museum nor the names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE
COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. */
/*
Copyright (c) 1991-2000 UserLand Software, Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
Version 4.1:
------------
8/28/00 rth: Carbonized the source and header files for use under Mac OS X
7/17/96 dmb: Give client more control over menu insertion & deletion
1. Frontier 4.1 now allows client to do actual menu insertion and
deletion. Even for default operation, we use these callbacks so
we can recover in the case of a server crash
2. Added SetMenusInserterCallback and SetMenusRemoverCallback to allow
client to provide altername menu placement
3. we override the server's default HandleMenuDirty event handler to
insure its validity in the case of a server crash
4. if the (component) server disappears unexpectedly, set fldirtysharedmenus
Version 3.0.2:
--------------
3/22/94 dmb: Updated for Universal Headers and Power PC.
If you're using Think C/Symantec C++, make sure you're
using the Universal Headers, not the headers that came on
your program disks. Universal Headers are on the Macintosh
on Risk SDK CD.
Version 3.0:
------------
11/1/93 DW: Minor changes to support Frontier 3.0
1. Frontier 3.0 implements an even more efficient menu sharing protocol
using the System 7.1 Component Manager. If possible, we use that protocol,
otherwise we are prepared to use the Frontier 2.0-compatible protocol, or
even the Frontier 1.0 protocol.
2. Added a ComponentInstance field to the MSglobals struct. As with all
other fields of MSglobals, this is read-only and really only there to
support debugging..
3. Added a procedure pointer field, scripterrorcallback, to the MSglobals
struct to allow error reporting. It replaces scriptcompletedcallback.
4. Added a procedure pointer field, eventfiltercallback, to the MSglobals
struct to allow error reporting. It allows the client app to handle
update, activate, OS and null events while a script is running.
4. InitSharedMenus takes a parameter, a pointer to a routine that
displays script error messages in a modal dialog
5. Replaced calls to the IAC Tools library with direct calls to the
Apple Event Manager. Apps no longer have to include any iacxxx.c files
in the project or #include <iac.h>.
11/3/93 DW: Minor code cleanup
1. Removed the #pragma from HandleMenuDirty.
2. Edited the headers on several routines to conform to the prototypes-
required format. Allows this code to be compiled by the MetroWerks C++
compiler.
3. Updated copyright notices in this file and in menusharing.h.
11/4/93 DW: MPW-compatible & ifdefs
6. built menusharing.c in MPW C. added #pragmas to head off warnings.
7. implemented two ifdefs that allow you to turn off support for
Frontier 2.0 and 1.0, or turn off support for component menu sharing.
11/16/93 dmb: a tweak and a fix
1. In the unlikely case that we're running on a system that supports
recording, which requires the Component Manager, but the Apple Event-
based protocol is being used, we set the DontRecord bit in the AESend
mode flags. [Note: in case the AppleEvents.h header file is out of date,
we #defined it, below (the value of this constant is 0x00001000).]
2. In CheckSharedMenus, if the component instance has gone bad, clear out
the menuserver global so that we'll try to reconnect the next time.
Version 2.0:
------------
1/22/92 DW: provide for dialog on receipt of a 'done' message
1. Frontier sets the 'errs' parameter if a shared script ended in an
error. we set up the IAC globals so that the scriptcomplete handler
can get the error string and display it in a dialog.
6/29/92 DW: fast menu sharing if Frontier 2.0 is present.
1. this is possible because Frontier 2.0 installs system event handlers
for the most time-consuming of the menu sharing operations.
8/13/92 DW: cleaner way of killing scripts.
1. In CancelSharedScript, we now send a message to the menu sharing server
asking that the script be killed. But only if we're talking to a server
that supports fast messages.
*/
#include <processes.h>
#include <Menus.h>
#include <Gestalt.h>
#define kAEDontRecord 0x00001000 /*this isn't defined in all versions of <AppleEvents.h>*/
#define componentMenuSharing /*undef this to disable component-based menu sharing.*/
#define frontierMenuSharing /*undef this to disable support for Frontier 1.0 and 2.0 menu sharing*/
tyMSglobals MSglobals = {0, 0, nil, false, false, false, false, 0, 0, nil};
enum {
uppMSerrordialogProcInfo = kPascalStackBased
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(char *)))
};
enum {
uppMSeventfilterProcInfo = kPascalStackBased
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(EventRecord *)))
};
enum {
uppMSmenusinstallerProcInfo = kPascalStackBased
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(hdlmenuarray)))
};
#if TARGET_API_MAC_CARBON
typedef UniversalProcPtr MSerrordialogUPP;
#define NewMSerrordialogProc(userRoutine) \
(MSerrordialogUPP) NewComponentFunctionUPP((ProcPtr)userRoutine, uppMSerrordialogProcInfo)
#else
#if GENERATINGCFM
typedef UniversalProcPtr MSerrordialogUPP;
#define CallMSerrordialogProc(userRoutine, theString) \
CallUniversalProc((UniversalProcPtr)(userRoutine), uppMSerrordialogProcInfo, (theString))
#define NewMSerrordialogProc(userRoutine) \
(MSerrordialogUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppMSerrordialogProcInfo, GetCurrentISA())
#else
typedef tyMSerrordialog MSerrordialogUPP;
#define CallMSerrordialogProc(userRoutine, theString) \
(*(userRoutine))((theString))
#define NewMSerrordialogProc(userRoutine) \
(MSerrordialogUPP)(userRoutine)
#endif
#endif
#if TARGET_API_MAC_CARBON
typedef UniversalProcPtr MSeventfilterUPP;
#define NewMSeventfilterProc(userRoutine) \
(MSeventfilterUPP) NewComponentFunctionUPP((ProcPtr)(userRoutine), uppMSeventfilterProcInfo)
#else
#if GENERATINGCFM
typedef UniversalProcPtr MSeventfilterUPP;
#define CallMSeventfilterProc(userRoutine, theEvent) \
CallUniversalProc((UniversalProcPtr)(userRoutine), uppMSeventfilterProcInfo, (theEvent))
#define NewMSeventfilterProc(userRoutine) \
(MSeventfilterUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppMSeventfilterProcInfo, GetCurrentISA())
#else
typedef tyMSeventfilter MSeventfilterUPP;
#define CallMSeventfilterProc(userRoutine, theEvent) \
(*(userRoutine))((theEvent))
#define NewMSeventfilterProc(userRoutine) \
(MSeventfilterUPP)(userRoutine)
#endif
#endif
#if TARGET_API_MAC_CARBON
typedef UniversalProcPtr MSmenusinstallerUPP;
#define NewMSmenusinstallerProc(userRoutine) \
(MSmenusinstallerUPP) NewComponentFunctionUPP((ProcPtr)(userRoutine), uppMSmenusinstallerProcInfo)
#else
#if GENERATINGCFM
typedef UniversalProcPtr MSmenusinstallerUPP;
#define CallMSmenusinstallerProc(userRoutine, theMenus) \
CallUniversalProc((UniversalProcPtr)(userRoutine), uppMSmenusinstallerProcInfo, (theMenus))
#define NewMSmenusinstallerProc(userRoutine) \
(MSmenusinstallerUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppMSmenusinstallerProcInfo, GetCurrentISA())
#else
typedef tyMSmenusinstaller MSmenusinstallerUPP;
#define CallMSmenusinstallerProc(userRoutine, theMenus) \
(*(userRoutine))((theMenus))
#define NewMSmenusinstallerProc(userRoutine) \
(MSmenusinstallerUPP)(userRoutine)
#endif
#endif
#ifdef componentMenuSharing
#define msComponentType 'SHMN'
#define msComponentSubType 0
#define msInitSharedMenusCommand 0x2001
#define msSharedMenuHitCommand 0x2002
#define msSharedScriptRunningCommand 0x2003
#define msCancelSharedScriptCommand 0x2004
#define msCheckSharedMenusCommand 0x2005
#define msDisposeSharedMenusCommand 0x2007
#define msIsSharedMenuCommand 0x2008
#define msEnableSharedMenusCommand 0x2009
#define msRunSharedMenuItemCommand 0x200A
#define msSetScriptErrorCallbackCommand 0x200B
#define msSetEventFilterCallbackCommand 0x200C
#define msSetMenusInserterCallbackCommand 0x200D
#define msSetMenusRemoverCallbackCommand 0x200E
#define msDirtySharedMenusCommand 0x200F
#define glue static pascal ComponentResult
#if powerc
enum {
uppCallComponentProcInfo = kPascalStackBased
| RESULT_SIZE(kFourByteCode)
| STACK_ROUTINE_PARAMETER(1, kFourByteCode)
};
#pragma options align=mac68k
glue initsharedmenusGlue (ComponentInstance comp) {
#define initsharedmenusParamSize (0L)
struct initsharedmenusGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
ComponentInstance comp;
};
struct initsharedmenusGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = initsharedmenusParamSize;
pb.componentWhat = msInitSharedMenusCommand;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*initsharedmenusGlue*/
glue sharedmenuhitGlue (ComponentInstance comp, short idmenu, short iditem, Boolean *flshareditem) {
#define sharedmenuhitParamSize (sizeof (idmenu) + sizeof (iditem) + sizeof (flshareditem))
struct sharedmenuhitGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
Boolean *flshareditem;
short iditem;
short idmenu;
ComponentInstance comp;
};
struct sharedmenuhitGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = sharedmenuhitParamSize;
pb.componentWhat = msSharedMenuHitCommand;
pb.flshareditem = flshareditem;
pb.iditem = iditem;
pb.idmenu = idmenu;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*sharedmenuhitGlue*/
glue sharedscriptrunningGlue (ComponentInstance comp, Boolean *flrunning) {
#define sharedscriptrunningParamSize (sizeof (flrunning))
struct sharedscriptrunningGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
Boolean *flrunning;
ComponentInstance comp;
};
struct sharedscriptrunningGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = sharedscriptrunningParamSize;
pb.componentWhat = msSharedScriptRunningCommand;
pb.flrunning = flrunning;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*sharedscriptrunningGlue*/
glue cancelsharedscriptGlue (ComponentInstance comp) {
#define cancelsharedscriptParamSize (0L)
struct cancelsharedscriptGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
ComponentInstance comp;
};
struct cancelsharedscriptGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = cancelsharedscriptParamSize;
pb.componentWhat = msCancelSharedScriptCommand;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*cancelsharedscriptGlue*/
glue checksharedmenusGlue (ComponentInstance comp, short idinsertafter) {
#define checksharedmenusParamSize (sizeof (idinsertafter))
struct checksharedmenusGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
short idinsertafter;
ComponentInstance comp;
};
struct checksharedmenusGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = checksharedmenusParamSize;
pb.componentWhat = msCheckSharedMenusCommand;
pb.idinsertafter = idinsertafter;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*checksharedmenusGlue*/
glue disposesharedmenusGlue (ComponentInstance comp) {
#define disposesharedmenusParamSize (0L)
struct disposesharedmenusGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
ComponentInstance comp;
};
struct disposesharedmenusGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = disposesharedmenusParamSize;
pb.componentWhat = msDisposeSharedMenusCommand;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*disposesharedmenusGlue*/
glue issharedmenuGlue (ComponentInstance comp, short idmenu, Boolean *flsharedmenu) {
#define issharedmenuParamSize (sizeof (idmenu) + sizeof (flsharedmenu))
struct issharedmenuGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
Boolean *flsharedmenu;
short idmenu;
ComponentInstance comp;
};
struct issharedmenuGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = issharedmenuParamSize;
pb.componentWhat = msIsSharedMenuCommand;
pb.flsharedmenu = flsharedmenu;
pb.idmenu = idmenu;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*issharedmenuGlue*/
glue enablesharedmenusGlue (ComponentInstance comp, Boolean flenable) {
#define enablesharedmenusParamSize (sizeof (short))
struct enablesharedmenusGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
Boolean flenable;
ComponentInstance comp;
};
struct enablesharedmenusGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = enablesharedmenusParamSize;
pb.componentWhat = msEnableSharedMenusCommand;
pb.flenable = flenable;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*enablesharedmenusGlue*/
glue runsharedmenuitemGlue (ComponentInstance comp, short idmenu, short iditem) {
#define runsharedmenuitemParamSize (sizeof (idmenu) + sizeof (iditem))
struct runsharedmenuitemGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
short iditem;
short idmenu;
ComponentInstance comp;
};
struct runsharedmenuitemGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = runsharedmenuitemParamSize;
pb.componentWhat = msRunSharedMenuItemCommand;
pb.iditem = iditem;
pb.idmenu = idmenu;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*runsharedmenuitemGlue*/
glue setscripterrorcallbackGlue (ComponentInstance comp, MSerrordialogUPP scripterrorproc) {
#define setscripterrorcallbackParamSize (sizeof (scripterrorproc))
struct setscripterrorcallbackGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
MSerrordialogUPP scripterrorproc;
ComponentInstance comp;
};
struct setscripterrorcallbackGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = setscripterrorcallbackParamSize;
pb.componentWhat = msSetScriptErrorCallbackCommand;
pb.scripterrorproc = scripterrorproc;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*setscripterrorcallbackGlue*/
glue seteventfiltercallbackGlue (ComponentInstance comp, MSeventfilterUPP eventfilterproc) {
#define seteventfiltercallbackParamSize (sizeof (eventfilterproc))
struct seteventfiltercallbackGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
MSeventfilterUPP eventfilterproc;
ComponentInstance comp;
};
struct seteventfiltercallbackGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = seteventfiltercallbackParamSize;
pb.componentWhat = msSetEventFilterCallbackCommand;
pb.eventfilterproc = eventfilterproc;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*seteventfiltercallbackGlue*/
glue setmenusinsertercallbackGlue (ComponentInstance comp, MSmenusinstallerUPP menusinserterproc) {
#define setmenusinsertercallbackParamSize (sizeof (menusinserterproc))
struct setmenusinsertercallbackGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
MSmenusinstallerUPP menusinserterproc;
ComponentInstance comp;
};
struct setmenusinsertercallbackGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = setmenusinsertercallbackParamSize;
pb.componentWhat = msSetMenusInserterCallbackCommand;
pb.menusinserterproc = menusinserterproc;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*setmenusinsertercallbackGlue*/
glue setmenusremovercallbackGlue (ComponentInstance comp, MSmenusinstallerUPP menusremoverproc) {
#define setmenusremovercallbackParamSize (sizeof (menusremoverproc))
struct setmenusremovercallbackGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
MSmenusinstallerUPP menusremoverproc;
ComponentInstance comp;
};
struct setmenusremovercallbackGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = setmenusremovercallbackParamSize;
pb.componentWhat = msSetMenusRemoverCallbackCommand;
pb.menusremoverproc = menusremoverproc;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*setmenusremovercallbackGlue*/
glue dirtysharedmenusGlue (ComponentInstance comp) {
#define dirtysharedmenusParamSize (0L)
struct dirtysharedmenusGluePB {
unsigned char componentFlags;
unsigned char componentParamSize;
short componentWhat;
ComponentInstance comp;
};
struct dirtysharedmenusGluePB pb;
pb.componentFlags = 0;
pb.componentParamSize = dirtysharedmenusParamSize;
pb.componentWhat = msDirtySharedMenusCommand;
pb.comp = comp;
#if TARGET_API_MAC_CARBON
return CallComponentDispatch ((ComponentParameters*) &pb);
#else
return CallUniversalProc(CallComponentUPP, uppCallComponentProcInfo, &pb);
#endif
} /*dirtysharedmenusGlue*/
#pragma options align=reset
#else
glue initsharedmenusGlue (ComponentInstance) /*3.0*/
ComponentCallNow (msInitSharedMenusCommand, 0L);
/*initsharedmenusGlue*/
glue sharedmenuhitGlue (ComponentInstance, short, short, Boolean *) /*3.0*/
ComponentCallNow (msSharedMenuHitCommand, sizeof (short) + sizeof (short) + sizeof (Boolean *));
/*sharedmenuhitGlue*/
glue sharedscriptrunningGlue (ComponentInstance, Boolean *) /*3.0*/
ComponentCallNow (msSharedScriptRunningCommand, sizeof (Boolean *));
/*sharedscriptrunningGlue*/
glue cancelsharedscriptGlue (ComponentInstance) /*3.0*/
ComponentCallNow (msCancelSharedScriptCommand, 0L);
/*cancelsharedscriptGlue*/
glue checksharedmenusGlue (ComponentInstance, short) /*3.0*/
ComponentCallNow (msCheckSharedMenusCommand, sizeof (short));
/*checksharedmenusGlue*/
glue disposesharedmenusGlue (ComponentInstance) /*3.0*/
ComponentCallNow (msDisposeSharedMenusCommand, 0L);
/*disposesharedmenusGlue*/
glue issharedmenuGlue (ComponentInstance, short, Boolean *) /*3.0*/
ComponentCallNow (msIsSharedMenuCommand, sizeof (short) + sizeof (Boolean *));
/*issharedmenuGlue*/
glue enablesharedmenusGlue (ComponentInstance, Boolean) /*3.0*/
ComponentCallNow (msEnableSharedMenusCommand, sizeof (short));
/*enablesharedmenusGlue*/
glue runsharedmenuitemGlue (ComponentInstance, short, short) /*3.0*/
ComponentCallNow (msRunSharedMenuItemCommand, sizeof (short) + sizeof (short));
/*runsharedmenuitemGlue*/
glue setscripterrorcallbackGlue (ComponentInstance, MSerrordialogUPP) /*3.0*/
ComponentCallNow (msSetScriptErrorCallbackCommand, sizeof (MSerrordialogUPP));
/*setscripterrorcallbackGlue*/
glue seteventfiltercallbackGlue (ComponentInstance, MSeventfilterUPP) /*3.0*/
ComponentCallNow (msSetEventFilterCallbackCommand, sizeof (MSeventfilterUPP));
/*seteventfiltercallbackGlue*/
glue setmenusinsertercallbackGlue (ComponentInstance, MSmenusinstallerUPP) /*3.0*/
ComponentCallNow (msSetMenusInserterCallbackCommand, sizeof (MSmenusinstallerUPP));
/*setmenusinsertercallbackGlue*/
glue setmenusremovercallbackGlue (ComponentInstance, MSmenusinstallerUPP) /*3.0*/
ComponentCallNow (msSetMenusRemoverCallbackCommand, sizeof (MSmenusinstallerUPP));
/*setmenusremovercallbackGlue*/
glue dirtysharedmenusGlue (ComponentInstance) /*3.0*/
ComponentCallNow (msDirtySharedMenusCommand, 0L);
/*dirtysharedmenusGlue*/
#endif
static Boolean InstallEventHandlers (void); /*forward*/
static Boolean RemoveEventHandlers (void); /*forward*/
static Boolean HaveComponentManager (void) { /*3.0*/
static Boolean initialized = false;
static Boolean haveit;
long result;
if (!initialized) {
initialized = true;
if (Gestalt (gestaltComponentMgr, &result) != noErr)
haveit = false;
else
haveit = result != 0;
}
return (haveit);
} /*HaveComponentManager*/
static pascal void InsertMenusCallback (hdlmenuarray hsharedmenus) {
/*
layer to be called by the menusharing server component only
we leave our global set to a copy of the menu array so that we
can clean up if the server crashes
*/
hdlmenuarray hm = hsharedmenus;
if (MSglobals.hsharedmenus != nil)
DisposeHandle ((Handle) MSglobals.hsharedmenus);
MSglobals.hsharedmenus = hm;
(*MSglobals.menusinsertercallback) (hm);
HandToHand ((Handle *) &MSglobals.hsharedmenus);
} /*InsertMenusCallback*/
static pascal void RemoveMenusCallback (hdlmenuarray hsharedmenus) {
/*
layer to be called by the menusharing server component only
we leave our global set to nil when we're done
*/
hdlmenuarray hm = hsharedmenus;
if (MSglobals.hsharedmenus != nil)
DisposeHandle ((Handle) MSglobals.hsharedmenus);
MSglobals.hsharedmenus = hm;
(*MSglobals.menusremovercallback) (hm);
MSglobals.hsharedmenus = nil;
} /*RemoveMenusCallback*/
#if TARGET_API_MAC_CARBON
#define InsertMenusCallbackDesc \
NewComponentFunctionUPP((ProcPtr)InsertMenusCallback, uppMSmenusinstallerProcInfo)
#define RemoveMenusCallbackDesc \
NewComponentFunctionUPP((ProcPtr)RemoveMenusCallback, uppMSmenusinstallerProcInfo)
#define InsertMenusCallbackUPP (InsertMenusCallbackDesc)
#define RemoveMenusCallbackUPP (RemoveMenusCallbackDesc)
#else
#if GENERATINGCFM
static RoutineDescriptor InsertMenusCallbackDesc = BUILD_ROUTINE_DESCRIPTOR (uppMSmenusinstallerProcInfo, InsertMenusCallback);
static RoutineDescriptor RemoveMenusCallbackDesc = BUILD_ROUTINE_DESCRIPTOR (uppMSmenusinstallerProcInfo, RemoveMenusCallback);
#define InsertMenusCallbackUPP (&InsertMenusCallbackDesc)
#define RemoveMenusCallbackUPP (&RemoveMenusCallbackDesc)
#else
#define InsertMenusCallbackUPP InsertMenusCallback
#define RemoveMenusCallbackUPP RemoveMenusCallback
#endif
#endif
static void ConnectWithComponent (void) { /*3.0*/
if (!HaveComponentManager ())
return;
if (MSglobals.menuserver != 0) /*already connected*/
return;
MSglobals.menuserver = OpenDefaultComponent (msComponentType, msComponentSubType);
if (MSglobals.menuserver == 0) /*didn't connect*/
return;
MSglobals.serverversion = GetComponentVersion (MSglobals.menuserver);
if (initsharedmenusGlue (MSglobals.menuserver) != noErr)
goto error;
if (setscripterrorcallbackGlue (MSglobals.menuserver, NewMSerrordialogProc (MSglobals.scripterrorcallback)) != noErr)
goto error;
if (seteventfiltercallbackGlue (MSglobals.menuserver, NewMSeventfilterProc (MSglobals.eventfiltercallback)) != noErr)
goto error;
if (MSglobals.serverversion >= 0x04100000) {
setmenusinsertercallbackGlue (MSglobals.menuserver, InsertMenusCallbackUPP);
setmenusremovercallbackGlue (MSglobals.menuserver, RemoveMenusCallbackUPP);
RemoveEventHandlers (); /*remove server's defaults*/
InstallEventHandlers (); /*use ours*/
}
return; /*everything worked*/
error:
CloseComponent (MSglobals.menuserver); /*error initializing menu sharing*/
MSglobals.menuserver = 0;
} /*ConnectWithComponent*/
#endif
static short CountMenuArray (void) {
/*
return the number of menus in the menu array.
*/
hdlmenuarray hm = MSglobals.hsharedmenus;
if (hm == nil)
return (0);
return ((short) (GetHandleSize ((Handle) hm) / sizeof (tysharedmenurecord)));
} /*CountMenuArray*/
#ifdef frontierMenuSharing
static OSType GetProcessCreator (void) {
/*
get the 4-character creator identifier for the application we're running
inside of.
*/
ProcessSerialNumber psn;
ProcessInfoRec info;
GetCurrentProcess (&psn);
info.processInfoLength = (long) sizeof (info);
info.processName = nil;
info.processAppSpec = nil;
GetProcessInformation (&psn, &info);
return (info.processSignature);
} /*GetProcessCreator*/
static Boolean HaveAppleEventManager (void) {
/*
return true if Apple Events are available.
*/
long gestaltAppleEventsPresent;
if (Gestalt (gestaltAppleEventsAttr, &gestaltAppleEventsPresent) != noErr)
return (false);
return (gestaltAppleEventsPresent != 0);
} /*HaveAppleEventManager*/
static Boolean PushLongParam (long val, OSType keyword, AppleEvent *event) { /*3.0*/
OSErr ec;
ec = AEPutParamPtr (
event, (AEKeyword) keyword, typeLongInteger,
(Ptr) &val, sizeof (long));
return (ec == noErr);
} /*PushLongParam*/
static Boolean PushShortParam (short val, OSType keyword, AppleEvent *event) { /*3.0*/
OSErr ec;
ec = AEPutParamPtr (
event, (AEKeyword) keyword, typeShortInteger,
(Ptr) &val, sizeof (short));
return (ec == noErr);
} /*PushShortParam*/
static Boolean GetLongParam (AppleEvent *event, OSType keyword, long *val) { /*3.0*/
OSErr ec;
DescType actualtype;
Size actualsize;
ec = AEGetParamPtr (
event, (AEKeyword) keyword, typeLongInteger,
&actualtype, (Ptr) val, sizeof (long), &actualsize);
if (ec != noErr) {
return (false);
}
return (true);
} /*GetLongParam*/
static Boolean GetBinaryParam (AppleEvent *event, OSType keyword, Handle *hbinary, OSType *binarytype) { /*3.0*/
AEDesc result;
OSErr ec;
Size theDataSize;
Ptr srcDataPtr;
ec = AEGetParamDesc (event, (AEKeyword) keyword, typeWildCard, &result);
if (ec != noErr) {
return (false);
}
#if TARGET_API_MAC_CARBON
theDataSize = AEGetDescDataSize(&result);
srcDataPtr = NewPtrClear(theDataSize);
if (srcDataPtr == nil)
return false;
ec = AEGetDescData(&result, srcDataPtr, theDataSize);
if (ec != nil)
{
DisposePtr(srcDataPtr);
return false;
}
BlockMove(srcDataPtr, **hbinary, theDataSize);
DisposePtr(srcDataPtr);
#else
*hbinary = result.dataHandle;
#endif
*binarytype = result.descriptorType;
return (true);
} /*GetBinaryParam*/
static Boolean SendAppleEvent (AppleEvent *event, AppleEvent *reply, Boolean noreply) { /*3.0*/
OSErr ec;
long mode;
if (noreply) {
mode = kAENoReply + kAENeverInteract;
ec = AESend (event, reply, mode, kAEHighPriority, kNoTimeOut, nil, nil);
}
else {
mode = kAEWaitReply + kAECanInteract + kAECanSwitchLayer + kAEDontRecord;
ec = AESend (
event, reply, mode, kAENormalPriority, kNoTimeOut,
nil /*(ProcPtr) IACwaitroutine*/, nil);
}
AEDisposeDesc (event);
return (ec == noErr);
} /*SendAppleEvent*/
static Boolean ServerSupportsFastMessages (void) {
/*
return true if there's a system event handler registered to support the
get-menu-array message. Frontier 2.0 installs such a handler, other servers
(e.g. Frontier 1.0) don't.
*/
OSErr ec;
AEEventHandlerUPP handler;
long refcon;
ec = AEGetEventHandler (MSglobals.serverid, 'gmry', &handler, &refcon, true);
return (ec == noErr);
} /*ServerSupportsFastMessages*/
static Boolean NewAppleEvent (OSType verbtoken, Boolean fast, AppleEvent *event) {
AEAddressDesc adr;
OSErr errcode;
if (fast && ServerSupportsFastMessages ()) {
ProcessSerialNumber psn;
psn.highLongOfPSN = 0;
psn.lowLongOfPSN = kCurrentProcess;
errcode = AECreateDesc (typeProcessSerialNumber, (Ptr) &psn, sizeof (psn), &adr);
}
else {
errcode = AECreateDesc (typeApplSignature, (Ptr) &MSglobals.serverid, sizeof (MSglobals.serverid), &adr);
}
errcode = AECreateAppleEvent (
MSglobals.serverid, verbtoken, &adr, kAutoGenerateReturnID, kAnyTransactionID, event);
AEDisposeDesc (&adr);
return (errcode == noErr);
} /*NewAppleEvent*/
static Boolean ProcessInForeground () {
/*
return true if we're running in the foreground, false if we're in the
background.
*/
ProcessSerialNumber currentprocess, frontprocess;
Boolean fl;
GetCurrentProcess (&currentprocess);
GetFrontProcess (&frontprocess);
SameProcess (&currentprocess, &frontprocess, &fl);
return (fl);
} /*ProcessInForeground*/
static Boolean ServerIsRunning (void) {
/*
return true if the server application is running.
*/
ProcessInfoRec info;
ProcessSerialNumber psn;
Str255 bsname;
FSSpec fss;
info.processInfoLength = sizeof (info);
info.processName = bsname; /*place to store process name*/
info.processAppSpec = &fss; /*place to store process filespec*/
psn.highLongOfPSN = kNoProcess;
psn.lowLongOfPSN = kNoProcess;
while (GetNextProcess (&psn) == noErr) {
info.processInfoLength = sizeof (ProcessInfoRec);
if (GetProcessInformation (&psn, &info) != noErr)
continue; /*keep going -- ignore error*/
if (info.processSignature == MSglobals.serverid)
return (true);
} /*while*/
return (false); /*loop completed, no server*/
} /*ServerIsRunning*/
static Boolean InstallSharedMenus (void) {
/*
insert all of the menus in the menuarray into the menu bar.
4.1 dmb: use menusinsertercallback to actually insert the menus
*/
(*MSglobals.menusinsertercallback) (MSglobals.hsharedmenus);
return (true);
} /*InstallSharedMenus*/
static Boolean GetMenuHandles (void) {
/*
loop through the menuarray, send an IAC message to the menu server requesting
that each MenuHandle be sent to us.
*/
hdlmenuarray hm = MSglobals.hsharedmenus;
short i, ct;
AppleEvent event, reply;
short fl;
MenuHandle hmenu;
OSType binarytype;
ct = CountMenuArray ();
for (i = 0; i < ct; i++) {
if (!NewAppleEvent ('gmhd', true, &event))
return (false);
if (!PushLongParam ((long)MSglobals.clientid, 'menp', &event))
return (false);
if (!PushShortParam (i, 'idix', &event))
return (false);
if (!SendAppleEvent (&event, &reply, false))
return (false);
fl = GetBinaryParam (&reply, keyDirectObject, (Handle *) &hmenu, &binarytype);
AEDisposeDesc (&reply);
if (!fl)
return (false);
(**hm) [i].hmenu = hmenu;
} /*for*/
return (true);
} /*GetMenuHandles*/
static Boolean GetSharedMenus (short firstresource) {
/*
call the menu server to get a menuarray, keyed off of our application id.
firstresource is the starting id to be used for the menus; if there are
n menus, their ids will range from firstresource to firstresource + n - 1.
*/
AppleEvent event, reply;
short fl;
OSType binarytype;
if (!NewAppleEvent ('gmry', true, &event))
return (false);
if (!PushLongParam ((long)MSglobals.clientid, 'menp', &event))
return (false);
if (!PushShortParam (firstresource, 'res1', &event))
return (false);
if (!SendAppleEvent (&event, &reply, false))
return (false);
fl = GetBinaryParam (&reply, keyDirectObject, (Handle *) &MSglobals.hsharedmenus, &binarytype);
AEDisposeDesc (&reply);
if (!fl)
return (false);
return (GetMenuHandles ());
} /*GetSharedMenus*/
static pascal OSErr HandleMenuDirty (const AppleEvent *event, AppleEvent *reply, SInt32 refcon) {
/*
this Apple event handler is called when the application's menu bar has been
edited by the script writer in the menu server's menu editor.
we just record the dirty-ness of the menus in a boolean, we'll actually re-
load the menus when we become the foreground process.
*/
#pragma unused (event, reply, refcon)
MSglobals.fldirtysharedmenus = true;
#ifdef componentMenuSharing
dirtysharedmenusGlue (MSglobals.menuserver);
#endif
return (noErr);
} /*HandleMenuDirty*/
static pascal OSErr HandleScriptComplete (const AppleEvent *event, AppleEvent *reply, SInt32 refcon) {
/*
this Apple event handler is called when a menu script has completed running.
we update a couple of menu-sharing globals and re-enable the shared menus.
10/8/91 DW: added callback to support Applet Toolkit.
11/2/93 DW: replaced call to scriptcompletedcallback with a call to
scripterrorcallback if there was an error in the script.
*/
#pragma unused (reply, refcon)
MSglobals.flscriptcancelled = MSglobals.flscriptrunning = false;
EnableSharedMenus (true);
if (MSglobals.scripterrorcallback != nil) {
Str255 errormessage;
AEDesc result;
OSErr ec;
long lentext;
Ptr srcDataPtr;
ec = AEGetParamDesc (event, 'errs', typeChar, &result);
if (ec != noErr) /*no error to report*/
return (noErr);
if (result.dataHandle == nil)
goto exit;
#if TARGET_API_MAC_CARBON
lentext = AEGetDescDataSize(&result);
#else
lentext = GetHandleSize (result.dataHandle);
#endif
if (lentext > 255)
lentext = 255;
if (lentext == 0) /*no error to report*/
goto exit;
errormessage [0] = (unsigned char) lentext;
#if TARGET_API_MAC_CARBON
srcDataPtr = NewPtrClear(lentext);
if (srcDataPtr == nil)
return (ec = memFullErr);
ec = AEGetDescData(&result, srcDataPtr, lentext);
if (ec != noErr)
return ec;
BlockMove (srcDataPtr, &errormessage[1], lentext);
#else
BlockMove (*result.dataHandle, &errormessage [1], lentext);
#endif
#if !TARGET_API_MAC_CARBON
Debugger();
CallMSerrordialogProc (MSglobals.scripterrorcallback, errormessage);
#endif
exit:
AEDisposeDesc (&result);
}
return (noErr);
} /*HandleScriptComplete*/
#endif
static pascal void InsertSharedMenus (hdlmenuarray hsharedmenus) {
/*
insert all of the menus in the menuarray into the menu bar. main
menus are inserted to the right of all others.
if the menus passed in are not the same as our current global,
assume that we're being called from a component-based server, and
it owns the handle and the menus hanging off of it. dispose our
global and set it to a copy of those passed in, so it will still be
around if the server crashes and we need to get rid of them.
*/
hdlmenuarray hm = hsharedmenus;
short i;
short ctmenus;
tysharedmenurecord item;
ctmenus = CountMenuArray ();
for (i = 0; i < ctmenus; i++) {
item = (**hm) [i];
if (item.flhierarchic)
InsertMenu (item.hmenu, -1);
else
InsertMenu (item.hmenu, 0);
(**hm) [i].flinserted = true; /*so we'll know it needs to be removed*/
} /*for*/
} /*InsertSharedMenus*/
static pascal void RemoveSharedMenus (hdlmenuarray hsharedmenus) {
/*
remove the shared menus from the menubar, reversing the action of InsertSharedMenus.
Unless, for some strange reason, we installed a menuinserter callback that
didn't set MSglobals.hsharedmenus, we can safely ignore the menus parameter.
note that we carefully avoid disposing anything, a requirement for working
with component menusharing. But we must clear the hsharedmenus global to
maintain a consistent state.
*/
hdlmenuarray hm = hsharedmenus;
short i;
short ctmenus;
tysharedmenurecord item;
ctmenus = CountMenuArray ();
for (i = 0; i < ctmenus; i++) {
item = (**hm) [i];
if (item.flinserted)
DeleteMenu (item.idmenu);
} /*for*/
} /*RemoveSharedMenus*/
pascal Boolean DisposeSharedMenus (void) {
/*
completely dispose of the menuarray and the menu handles it contains.
10/10/91 DW: check for no shared menus before disposing, save code if
its ever called from more than one place. also set the global handle to
nil after disposing and redraw the menu bar.
4.1 dmb: use menusremovercallback to actually remove the menus
*/
hdlmenuarray hm = MSglobals.hsharedmenus;
short i;
short ctmenus;
tysharedmenurecord item;
#ifdef componentMenuSharing
if (MSglobals.menuserver != 0) /*3.0*/
return (disposesharedmenusGlue (MSglobals.menuserver) == noErr);
#endif
#ifdef frontierMenuSharing
MSglobals.fldirtysharedmenus = true; /*4.1 dmb: for clients with dynamic menubars*/
if (hm == nil) /*no shared menus to toss*/
return (true);
(*MSglobals.menusremovercallback) (hm);
ctmenus = CountMenuArray ();
for (i = 0; i < ctmenus; i++) {
item = (**hm) [i];
DisposeMenu (item.hmenu);
} /*for*/
DisposeHandle ((Handle) hm);
MSglobals.hsharedmenus = nil;
DrawMenuBar ();
return (true);
#endif
return (false); /* JWB 5/4/95 */
} /*DisposeSharedMenus*/
pascal Boolean IsSharedMenu (short idmenu) {
/*
return true if the indicated menu is one of the shared menus.
*/
hdlmenuarray hm = MSglobals.hsharedmenus;
short ct, i;
tysharedmenurecord item;
#ifdef componentMenuSharing
/*3.0*/ {
Boolean flshared;
if (MSglobals.menuserver != 0) {
if (issharedmenuGlue (MSglobals.menuserver, idmenu, &flshared) == noErr)
return (flshared);
return (false);
}
}
#endif
#ifdef frontierMenuSharing
ct = CountMenuArray ();
for (i = 0; i < ct; i++) {
item = (**hm) [i];
if (item.idmenu == idmenu)
return (true);
} /*for*/
return (false);
#endif
return (false); /* JWB 5/4/95 */
} /*IsSharedMenu*/
pascal Boolean EnableSharedMenus (Boolean flenable) {
/*
Enables or disables the the menus in the specified menu array.
Always returns true.
*/
hdlmenuarray hm = MSglobals.hsharedmenus;
short i;
short ctmenus;
MenuHandle hmenu;
#ifdef componentMenuSharing
if (MSglobals.menuserver != 0) /*3.0*/
return (enablesharedmenusGlue (MSglobals.menuserver, flenable) == noErr);
#endif
#ifdef frontierMenuSharing
ctmenus = CountMenuArray ();
for (i = 0; i < ctmenus; i++)
{
hmenu = (**hm) [i].hmenu;
if (flenable)
{
#if TARGET_API_MAC_CARBON
EnableMenuItem (hmenu, 0);
#else
EnableItem (hmenu, 0);
#endif
}
else
{
#if TARGET_API_MAC_CARBON
DisableMenuItem (hmenu, 0);
#else
DisableItem (hmenu, 0);
#endif
}
}
DrawMenuBar ();
return (true);
#endif
return (false); /* JWB 5/4/95 */
} /*EnableSharedMenus*/
pascal Boolean RunSharedMenuItem (short idmenu, short iditem) {
/*
call the menu server to run the script linked to the indicated menu item.
the script will execute asynchonously, after this call returns.
SDK 2.0: if the server isn't running, remove the shared menus and return
false. this will only happen if the server has crashed without letting us
know that our menus are dirty.
*/
AppleEvent event, reply;
Boolean fl;
if (!MSglobals.flinitialized) /*3.0*/
return (false);
#ifdef componentMenuSharing
if (MSglobals.menuserver != 0) /*3.0*/
return (runsharedmenuitemGlue (MSglobals.menuserver, idmenu, iditem) == noErr);
#endif
#ifdef frontierMenuSharing
if (!ServerIsRunning ()) {
MSglobals.fldirtysharedmenus = true;
return (false);
}
if (!NewAppleEvent ('runm', false, &event))
return (false);
if (!PushLongParam ((long)MSglobals.clientid, 'menp', &event))
return (false);
if (!PushShortParam (idmenu, 'mid ', &event))
return (false);
if (!PushShortParam (iditem, 'mitm', &event))
return (false);
if (!SendAppleEvent (&event, &reply, false))
return (false);
fl = GetLongParam (&reply, keyDirectObject, &MSglobals.idscript);
AEDisposeDesc (&reply);
return (fl && (MSglobals.idscript != 0));
#endif
return (false); /* JWB 5/4/95 */
} /*RunSharedMenuItem*/
pascal Boolean CheckSharedMenus (short idinsertafter) {
/*
call this from your main event loop after receiving and processing every
event. if the menus need updating, we send a message to the server asking
for our shared menus.
if we load menus, they are assigned resource ids starting with idinsertafter.
this number must be less than 255 to allow for hierarchic menus, and must be
small enough so that no menu has an id of greater than 255.
9/28/91 DW: only update menus if we're the front process. this catches the
delay on re-loading a changed menu structure on the Multifinder switch. No
extra burden on the script writer editing the menu bar.
11/1/93 DW: add support for component menu sharing.
11/16/93 dmb: clear MSglobals.menuserver if we get a badComponentInstance error.
the next call to CheckSharedMenus will attempt to reconnect.
7/16/96 dmb: if the component menuserver goes bad, remove the event handler that
it installed on our behalf. it may be orphanced code now if the server crashed.
*/
#ifdef componentMenuSharing
/*3.0*/ {
ConnectWithComponent (); /*does nothing if already connected*/
if (MSglobals.menuserver != 0) {
if (checksharedmenusGlue (MSglobals.menuserver, idinsertafter) == badComponentInstance) {
if (MSglobals.hsharedmenus != nil) { /*dmb 4.1*/
(*MSglobals.menusremovercallback) (MSglobals.hsharedmenus);
DisposeHandle ((Handle) MSglobals.hsharedmenus);
MSglobals.hsharedmenus = nil;
DrawMenuBar ();
}
RemoveEventHandlers (); /*dmb 4.1*/
MSglobals.menuserver = 0;
return (false);
}
return (true);
}
}
#endif
#ifdef frontierMenuSharing
if (!ProcessInForeground ()) /*only update menus if we're the front process*/
return (true);
if (!MSglobals.fldirtysharedmenus) /*no need for an update, return quickly*/
return (true);
DisposeSharedMenus ();
if (ServerIsRunning ()) {
if (GetSharedMenus (idinsertafter)) {
InstallSharedMenus (); /*install to the right of all other menus*/
DrawMenuBar ();
}
MSglobals.fldirtysharedmenus = false;
}
else { /*server not running, menus have been updated (ie there are no shared menus)*/
MSglobals.fldirtysharedmenus = false;
}
return (true);
#endif
return (false); /* JWB 5/4/95 */
} /*CheckSharedMenus*/
pascal Boolean SharedScriptRunning () {
/*
returns true if a shared script is currently running, false otherwise.
it's provided so that an application can intelligently handle cmd-period
script termination in its keystroke handling routine.
*/
return (MSglobals.flscriptrunning);
} /*SharedScriptRunning*/
pascal Boolean CancelSharedScript () {
/*
call this when the user presses cmd-period or otherwise indicates to you that
he or she wants the currently running script to be halted.
8/13/92 DW: if we're talking to post-2.0 Frontier or Runtime 1.0, we send a
message to the server telling it to kill the script. otherwise we do it the
old less elegant way, by setting a flag that gets monitored in calls to
SharedScriptCancelled.
*/
#ifdef frontierMenuSharing
AppleEvent event, reply;
if (!MSglobals.flscriptrunning) /*nothing to do*/
return (true);
if (!ServerSupportsFastMessages ()) {
MSglobals.flscriptcancelled = true;
return (true);
}
if (!NewAppleEvent ('kill', false, &event))
return (false);
if (!PushLongParam (MSglobals.idscript, '----', &event))
return (false);
if (!SendAppleEvent (&event, &reply, true))
return (false);
return (true);
#endif
} /*CancelSharedScript*/
pascal Boolean SharedMenuHit (short idmenu, short iditem) {
/*
returns true if the indicated menu and item indicate a shared menu item.
if not, we return false -- the item is in one of your menus, you should
process the command as you normally would.
we send an IAC message to the menu server, requesting that the script
linked into that item be run.
we disable the shared menus, awaiting a 'done' message to re-enable them.
*/
if (!MSglobals.flinitialized) /*3.0*/
return (false);
#ifdef componentMenuSharing
/*3.0*/ {
Boolean flshareditem;
if (MSglobals.menuserver != 0) {
if (sharedmenuhitGlue (MSglobals.menuserver, idmenu, iditem, &flshareditem) != noErr)
return (false);
return (flshareditem); /*client handles if it wasn't a shared item*/
}
}
#endif
#ifdef frontierMenuSharing
if (!IsSharedMenu (idmenu)) /*not a shared menu*/
return (false);
HiliteMenu (0);
if (RunSharedMenuItem (idmenu, iditem)) {
MSglobals.flscriptrunning = true;
EnableSharedMenus (false);
}
return (true);
#endif
return (false); /* covers the case when Frontier is not running, and only Component Menu Sharing
is enabled. JWB 5/4/95 */
} /*SharedMenuHit*/
pascal Boolean SharedScriptCancelled (AppleEvent *event, AppleEvent *reply) {
/*
call this routine in each Apple event message handler that could conceivably
be used in a script being run by the menu server. if we return false continue
processing the message as you normally would. if we return true, that means
that the script that's running has been cancelled by the user; you should
return noErr from your Apple event handler when we return true.
before we return true, we reply to the message on behalf of the message
handler. we send a specific error code of 6, this should be interpreted by
the scripting system as "stop running the script, but don't display an
error dialog.
we admit this mechanism is somewhat klunky, but it proved too difficult to have
Frontier be ready to respond to a "Cancel Script" Apple event while running
the script and also giving time slices to agents.
12/16/92 dmb: this minimal version supports the old protocol, but it's not
needed for Frontier/Runtime 2.0 and greater.
11/2/93 DW: this klunky method is no longer recommended, but it is still
supported.
*/
#pragma unused (event)
#ifdef frontierMenuSharing
if (MSglobals.flscriptcancelled && MSglobals.flscriptrunning) {
MSglobals.flscriptcancelled = MSglobals.flscriptrunning = false;
PushLongParam (6, keyErrorNumber, reply); /*server watches for this special error code*/
return (true);
}
return (false); /*script not cancelled, keep processing message*/
#else
#pragma unused (reply)
#endif
} /*SharedScriptCancelled*/
pascal Boolean SetMenusInserterCallback (tyMSmenusinstaller menusinserter) {
MSglobals.menusinsertercallback = menusinserter;
return (true);
} /*SetMenusInserterCallback*/
pascal Boolean SetMenusRemoverCallback (tyMSmenusinstaller menusremover) {
MSglobals.menusremovercallback = menusremover;
return (true);
} /*SetMenusRemoverCallback*/
static Boolean InstallEventHandlers (void) {
if (AEInstallEventHandler (MSglobals.clientid, 'updm', NewAEEventHandlerUPP (HandleMenuDirty), 0, false) != noErr)
return (false);
#ifdef frontierMenuSharing
if (AEInstallEventHandler (MSglobals.clientid, 'done', NewAEEventHandlerUPP (HandleScriptComplete), 0, false) != noErr)
return (false);
#endif
return (true);
} /*InstallEventHandlers*/
static Boolean RemoveEventHandlers (void) {
if (AERemoveEventHandler (MSglobals.clientid, 'updm', nil, false) != noErr)
return (false);
#ifdef frontierMenuSharing
if (AERemoveEventHandler (MSglobals.clientid, 'done', nil, false) != noErr)
return (false);
#endif
return (true);
} /*RemoveEventHandlers*/
pascal Boolean InitSharedMenus (tyMSerrordialog errordialogcallback, tyMSeventfilter eventfiltercallback) {
/*
sets the program up for menu sharing. we initialize the IAC Tools library and
then initialize the fields of MSglobals.
we install two Apple event message handlers -- one to catch the "menu needs update"
message, and another to handle the "script has completed" message.
11/2/93 DW: Complete rewrite for 3.0.
*/
MSglobals.flinitialized = false;
MSglobals.scripterrorcallback = errordialogcallback;
MSglobals.menusinsertercallback = InsertSharedMenus;
MSglobals.menusremovercallback = RemoveSharedMenus;
if (!HaveAppleEventManager ())
return (false);
#ifdef componentMenuSharing
MSglobals.menuserver = 0;
MSglobals.eventfiltercallback = eventfiltercallback;
MSglobals.flinitialized = true;
#endif
MSglobals.serverid = 'LAND'; /*Frontier's creator id, for pre-3.0 protocol only*/
MSglobals.clientid = GetProcessCreator ();
MSglobals.hsharedmenus = nil; /*haven't loaded shared menus yet*/
MSglobals.fldirtysharedmenus = true; /*force update 1st time thru event loop*/
MSglobals.flscriptcancelled = false; /*script hasn't been cancelled*/
MSglobals.flscriptrunning = false; /*no menu script running*/
MSglobals.flinitialized = true;
if (InstallEventHandlers () == false)
return (false);
return (true);
} /*InitSharedMenus*/