tclMacLibrary.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:7k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * tclMacLibrary.c --
  3.  *
  4.  * This file should be included in Tcl extensions that want to 
  5.  * automatically open their resource forks when the code is linked. 
  6.  * These routines should not be exported but should be compiled 
  7.  * locally by each fragment.  Many thanks to Jay Lieske
  8.  * <lieske@princeton.edu> who provide an initial version of this
  9.  * file.
  10.  *
  11.  * Copyright (c) 1996 Sun Microsystems, Inc.
  12.  *
  13.  * See the file "license.terms" for information on usage and redistribution
  14.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  15.  *
  16.  * RCS: @(#) $Id: tclMacLibrary.c,v 1.5 2001/11/23 01:27:39 das Exp $
  17.  */
  18. /*
  19.  * Here is another place that we are using the old routine names...
  20.  */
  21. #include <CodeFragments.h>
  22. #include <Errors.h>
  23. #include <Resources.h>
  24. #include <Strings.h>
  25. #include "tclMacInt.h"
  26. #if defined(TCL_REGISTER_LIBRARY) && defined(USE_TCL_STUBS)
  27. #error "Can't use TCL_REGISTER_LIBRARY and USE_TCL_STUBS at the same time!"
  28. /*
  29.  * Can't register a library with Tcl when using stubs in the current
  30.  * implementation, since Tcl_InitStubs hasn't been called yet
  31.  *  when OpenLibraryResource is executing. 
  32.  */
  33. #endif
  34. /*
  35.  * These function are not currently defined in any header file.  The
  36.  * only place they should be used is in the Initialization and
  37.  * Termination entry points for a code fragment.  The prototypes
  38.  * are included here to avoid compile errors.
  39.  */
  40. OSErr TclMacInitializeFragment _ANSI_ARGS_((
  41. struct CFragInitBlock* initBlkPtr));
  42. void TclMacTerminateFragment _ANSI_ARGS_((void));
  43. /*
  44.  * Static functions in this file.
  45.  */
  46. static OSErr OpenLibraryResource _ANSI_ARGS_((
  47. struct CFragInitBlock* initBlkPtr));
  48. static void CloseLibraryResource _ANSI_ARGS_((void));
  49. /* 
  50.  * The refnum of the opened resource fork.
  51.  */
  52. static short ourResFile = kResFileNotOpened;
  53. /*
  54.  * This is the resource token for the our resource file.
  55.  * It stores the name we registered with the resource facility.
  56.  * We only need to use this if we are actually registering ourselves.
  57.  */
  58.   
  59. #ifdef TCL_REGISTER_LIBRARY
  60. static Tcl_Obj *ourResToken;
  61. #endif
  62. /*
  63.  *----------------------------------------------------------------------
  64.  *
  65.  * TclMacInitializeFragment --
  66.  *
  67.  * Called by MacOS CFM when the shared library is loaded. All this
  68.  * function really does is give Tcl a chance to open and register
  69.  * the resource fork of the library. 
  70.  *
  71.  * Results:
  72.  * MacOS error code if loading should be canceled.
  73.  *
  74.  * Side effects:
  75.  * Opens the resource fork of the shared library file.
  76.  *
  77.  *----------------------------------------------------------------------
  78.  */
  79. OSErr
  80. TclMacInitializeFragment(
  81.     struct CFragInitBlock* initBlkPtr) /* Pointer to our library. */
  82. {
  83.     OSErr err = noErr;
  84. #ifdef __MWERKS__
  85.     {
  86.      extern OSErr __initialize( CFragInitBlock* initBlkPtr);
  87.      err = __initialize((CFragInitBlock *) initBlkPtr);
  88.     }
  89. #endif
  90.     if (err == noErr)
  91.      err = OpenLibraryResource( initBlkPtr);
  92.     return err;
  93. }
  94. /*
  95.  *----------------------------------------------------------------------
  96.  *
  97.  * TclMacTerminateFragment --
  98.  *
  99.  * Called by MacOS CFM when the shared library is unloaded.
  100.  *
  101.  * Results:
  102.  * None.
  103.  *
  104.  * Side effects:
  105.  * The resource fork of the code fragment is closed.
  106.  *
  107.  *----------------------------------------------------------------------
  108.  */
  109. void 
  110. TclMacTerminateFragment()
  111. {
  112.     CloseLibraryResource();
  113. #ifdef __MWERKS__
  114.     {
  115.      extern void __terminate(void);
  116.      __terminate();
  117.     }
  118. #endif
  119. }
  120. /*
  121.  *----------------------------------------------------------------------
  122.  *
  123.  * OpenLibraryResource --
  124.  *
  125.  * This routine can be called by a MacOS fragment's initialiation 
  126.  * function to open the resource fork of the file.  
  127.  * Call it with the same data passed to the initialization function. 
  128.  * If the fragment loading should fail if the resource fork can't 
  129.  * be opened, then the initialization function can pass on this 
  130.  * return value.
  131.  *
  132.  *      If you #define TCL_REGISTER_RESOURCE before compiling this resource, 
  133.  * then your library will register its open resource fork with the
  134.  *      resource command.
  135.  *
  136.  * Results:
  137.  * It returns noErr on success and a MacOS error code on failure.
  138.  *
  139.  * Side effects:
  140.  * The resource fork of the code fragment is opened read-only and 
  141.  * is installed at the head of the resource chain.
  142.  *
  143.  *----------------------------------------------------------------------
  144.  */
  145. static OSErr 
  146. OpenLibraryResource(
  147.     struct CFragInitBlock* initBlkPtr)
  148. {
  149.     /*
  150.      * The 3.0 version of the Universal headers changed CFragInitBlock
  151.      * to an opaque pointer type.  CFragSystem7InitBlock is now the
  152.      * real pointer.
  153.      */
  154.      
  155. #if !defined(UNIVERSAL_INTERFACES_VERSION) || (UNIVERSAL_INTERFACES_VERSION < 0x0300)
  156.     struct CFragInitBlock *realInitBlkPtr = initBlkPtr;
  157. #else 
  158.     CFragSystem7InitBlock *realInitBlkPtr = (CFragSystem7InitBlock *) initBlkPtr;
  159. #endif
  160.     FSSpec* fileSpec = NULL;
  161.     OSErr err = noErr;
  162.     
  163.     if (realInitBlkPtr->fragLocator.where == kDataForkCFragLocator) {
  164.      fileSpec = realInitBlkPtr->fragLocator.u.onDisk.fileSpec;
  165.     } else if (realInitBlkPtr->fragLocator.where == kResourceCFragLocator) {
  166.      fileSpec = realInitBlkPtr->fragLocator.u.inSegs.fileSpec;
  167.     } else {
  168.      err = resFNotFound;
  169.     }
  170.     /*
  171.      * Open the resource fork for this library in read-only mode.  
  172.      * This will make it the current res file, ahead of the 
  173.      * application's own resources.
  174.      */
  175.     
  176.     if (fileSpec != NULL) {
  177. ourResFile = FSpOpenResFile(fileSpec, fsRdPerm);
  178. if (ourResFile == kResFileNotOpened) {
  179.     err = ResError();
  180. } else {
  181. #ifdef TCL_REGISTER_LIBRARY
  182.     ourResToken = Tcl_NewObj();
  183.     Tcl_IncrRefCount(ourResToken);
  184.     p2cstr(realInitBlkPtr->libName);
  185.     Tcl_SetStringObj(ourResToken, (char *) realInitBlkPtr->libName, -1);
  186.     c2pstr((char *) realInitBlkPtr->libName);
  187.     TclMacRegisterResourceFork(ourResFile, ourResToken,
  188.             TCL_RESOURCE_DONT_CLOSE);
  189. #endif
  190.             SetResFileAttrs(ourResFile, mapReadOnly);
  191. }
  192.     }
  193.     
  194.     return err;
  195. }
  196. /*
  197.  *----------------------------------------------------------------------
  198.  *
  199.  * CloseLibraryResource --
  200.  *
  201.  * This routine should be called by a MacOS fragment's termination 
  202.  * function to close the resource fork of the file 
  203.  * that was opened with OpenLibraryResource.  
  204.  *
  205.  * Results:
  206.  * None.
  207.  *
  208.  * Side effects:
  209.  * The resource fork of the code fragment is closed.
  210.  *
  211.  *----------------------------------------------------------------------
  212.  */
  213. static void
  214. CloseLibraryResource()
  215. {
  216.     if (ourResFile != kResFileNotOpened) {
  217. #ifdef TCL_REGISTER_LIBRARY
  218.         int length;
  219.         TclMacUnRegisterResourceFork(
  220.         Tcl_GetStringFromObj(ourResToken, &length),
  221.                 NULL);
  222.         Tcl_DecrRefCount(ourResToken);
  223. #endif
  224. CloseResFile(ourResFile);
  225. ourResFile = kResFileNotOpened;
  226.     }
  227. }