home *** CD-ROM | disk | FTP | other *** search
/ MacGames Sampler / PHT MacGames Bundle.iso / MacSource Folder / Samples from the CD / Editors / emacs / Emacs-1.14b1-sources / sources / unix-emulation-src / initunix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-30  |  7.3 KB  |  312 lines  |  [TEXT/EMAC]

  1. /*
  2.  * Copyright (C) 1993, 1994 Marc Parmet.
  3.  * This file is part of the Macintosh port of GNU Emacs.
  4.  *
  5.  * GNU Emacs is distributed in the hope that it will be useful,
  6.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  8.  * GNU General Public License for more details.
  9.  */
  10.  
  11. #if defined(THINK_C)
  12. #include <MacHeaders>
  13. #else
  14. #include <Types.h>
  15. #include <Memory.h>
  16. #include <Quickdraw.h>
  17. #include <Windows.h>
  18. #include <Fonts.h>
  19. #include <Dialogs.h>
  20. #include <TextEdit.h>
  21. #include <ToolUtils.h>
  22. #include <Resources.h>
  23. #endif
  24.  
  25. #include <GestaltEqu.h>
  26. #include <AppleEvents.h>
  27. #include "sys/param.h"
  28. #include "unix-types.h"
  29.  
  30. static Cursor watch,beachball[8];
  31. static int init_argc;
  32. static char ***init_argv;
  33.  
  34. void
  35. spin_beachball(void)
  36. {
  37.     static char k;
  38.     SetCursor(&beachball[k++ & 7]);
  39. }
  40.  
  41. static int
  42. patch(char **h,long code,long replacement)
  43. {
  44.     long i,hsize,*p;
  45.  
  46.     hsize = GetHandleSize(h);
  47.     if (MemError()) return -1;
  48.  
  49.     for (i = 0; i<hsize-3; i += 2) {
  50.         p = (long *)(*h + i);
  51.         if (*p == code) {
  52.             *p = replacement;
  53.             return 0;
  54.         }
  55.     }
  56.     
  57.     return -1;
  58. }
  59.  
  60. static int
  61. have_required_params(AppleEvent *e)
  62. {
  63.     short err;
  64.     long actualSize;
  65.     DescType returnedType;
  66.  
  67.     err = AEGetAttributePtr(e,keyMissedKeywordAttr,typeWildCard,
  68.                             &returnedType,0L,0,&actualSize);
  69.  
  70.     if (err == errAEDescNotFound)
  71.         return 0;
  72.     else if (err == 0)
  73.         return errAEEventNotHandled;
  74.     else
  75.         return err;
  76. }
  77.  
  78. static pascal short
  79. do_ae_peel_args(AppleEvent *e,AppleEvent *reply,long refCon)
  80. {
  81.     FSSpec fs;
  82.     short err;
  83.     FSSpec cwd;
  84.     int have_cwd;
  85.     CInfoPBRec pb;
  86.     AEKeyword keywd;
  87.     char *t,**s;
  88.     unsigned char u[256];
  89.     AEDescList docList;
  90.     DescType returnedType;
  91.     long i,itemsInList,actualSize;
  92.     
  93.     err = AEGetParamDesc(e,keyDirectObject,typeAEList,&docList);
  94.     if (err) return err;
  95.     err = have_required_params(e);
  96.     if (err) return err;
  97.     err = AECountItems(&docList,&itemsInList);
  98.     if (err) return err;
  99.     have_cwd = 0;
  100.     for (i = 1; i<=itemsInList; ++i) {
  101.         err = AEGetNthPtr(&docList,i,typeFSS,&keywd,&returnedType,&fs,
  102.                           sizeof(FSSpec),&actualSize);
  103.         if (err) continue;
  104.         
  105.         if (!have_cwd) {
  106.             pb.dirInfo.ioFDirIndex = -1;
  107.             pb.dirInfo.ioNamePtr = u;
  108.             pb.dirInfo.ioVRefNum = fs.vRefNum;
  109.             pb.dirInfo.ioDrDirID = fs.parID;
  110.             err = PBGetCatInfo(&pb,0);
  111.             if (!err) {
  112.                 err = FSMakeFSSpec(fs.vRefNum,pb.dirInfo.ioDrParID,
  113.                                    pb.dirInfo.ioNamePtr,&cwd);
  114.                 if (!err) {
  115.                     err = FSSpec2unixfn_internal(&cwd,&s);
  116.                     if (!err) {
  117.                         HLock(s);
  118.                         chdir_internal(*s);
  119.                         DisposHandle(s);
  120.                         have_cwd = 1;
  121.                     }
  122.                 }
  123.             }
  124.         }
  125.     
  126.         err = FSSpec2unixfn_internal(&fs,&s);
  127.         if (err) return err;
  128.         SetHandleSize((Handle)init_argv,(init_argc+1) * sizeof(char *));
  129.         err = MemError();
  130.         if (err) { DisposHandle(s); return err; }
  131.         HLock(s);
  132.         t = NewPtr(strlen(*s) + 1);
  133.         (*init_argv)[init_argc] = t;
  134.         err = MemError();
  135.         if (err) { DisposHandle(s); return err; }
  136.         strcpy((char *)(*init_argv)[init_argc],*s);
  137.         DisposHandle(s);
  138.         ++init_argc;
  139.     }
  140.     
  141.     err = AEDisposeDesc(&docList);
  142.     if (err) return err;
  143.     return 0;
  144. }
  145.  
  146. static pascal Boolean
  147. specific_filter(Ptr p,HighLevelEventMsgPtr mb,TargetID sender)
  148. {
  149.     short err;
  150.     long class,id;
  151.     EventRecord *e = &mb->theMsgEvent;
  152.     
  153.     class = e->message;
  154.     id = *(long *)&e->where;
  155.     if (class == kCoreEventClass && id == kAEOpenDocuments) {
  156.         err = AEProcessAppleEvent(e);
  157.         return -1;
  158.     }
  159.     else
  160.         return 0;
  161. }
  162.  
  163. static pascal short
  164. do_nothing(AppleEvent *ae,AppleEvent *reply,long refCon)
  165. {
  166.     return errAEEventNotHandled;
  167. }
  168.  
  169. static void
  170. build_argument_list(void)
  171. {
  172.     char *t,**apParam;
  173.     short err,apRefNum;
  174.     unsigned char s[256];
  175.     static GetSpecificFilterUPP specific_filter_upp;
  176.     
  177.     if (specific_filter_upp == 0L)
  178.         specific_filter_upp = NewGetSpecificFilterProc(specific_filter);
  179.  
  180.     init_argc = 1;
  181.     init_argv = (char ***)NewHandle(1 * sizeof(char *));
  182.     if (MemError()) ExitToShell();
  183.     /* GetAppParms(s,&apRefNum,&apParam); */
  184.     pstrcpy(s,"\pEmacs");
  185.     t = NewPtr(s[0] + 1L);
  186.     if (MemError()) ExitToShell();
  187.     (*init_argv)[0] = t;
  188.     PtoCstr(s);
  189.     strcpy((*init_argv)[0],(char *)s);
  190.  
  191.     while (GetSpecificHighLevelEvent(specific_filter_upp,0L,&err))
  192.         if (err) break;
  193.  
  194.     // Add null pointer to end of argv.
  195.     SetHandleSize((Handle)init_argv,(init_argc+1) * sizeof(char *));
  196.     if (MemError()) ExitToShell();
  197.     (*init_argv)[init_argc] = 0L;
  198. }
  199.  
  200. void
  201. init_unix(int stacksize,char ***environ_address,int *argc,char ****argv)
  202. {
  203.     short err;
  204.     FSSpec spec;
  205.     int i,fd,appsize,n;
  206.     SelectorFunctionUPP oldfunc;
  207.     char *t,**s,**dispatch,u[MAXPATHLEN];
  208.     char *appbottom,*apptop;
  209.     static AEEventHandlerUPP do_ae_peel_args_upp,do_nothing_upp;
  210.     static SelectorFunctionUPP dispatch_upp;
  211.     extern int unix_entry(int,int *,va_list);
  212.     UniversalProcPtr unix_entry_upp;
  213.  
  214.     appbottom = (char *)ApplicationZone();
  215.     apptop = (char *)&appbottom;
  216.     appsize = apptop - appbottom;
  217.     SetApplLimit(appbottom + appsize - stacksize);
  218.     MaxApplZone();
  219.     // StackSpace(); DebugStr("\pStack size is in d0;d0");
  220.  
  221.     if (do_ae_peel_args_upp == 0L) {
  222.         do_ae_peel_args_upp = NewAEEventHandlerProc(do_ae_peel_args);
  223.         do_nothing_upp = NewAEEventHandlerProc(do_nothing);
  224.  
  225.         /* Must make sure routine descriptor is in the system heap */
  226.         dispatch = GetResource('GDEF',128);
  227.         if (dispatch == 0L) goto error;
  228.         DetachResource(dispatch);
  229.         HLock(dispatch);
  230.         HNoPurge(dispatch);
  231. #if defined(powerc)
  232.         SetZone(SystemZone());
  233.         dispatch_upp = NewRoutineDescriptor((long (*)())*dispatch,
  234.             uppSelectorFunctionProcInfo,kM68kISA);
  235.         SetZone(ApplicZone());
  236. #else
  237.         dispatch_upp = NewSelectorFunctionProc((long (*)())*dispatch);
  238. #endif
  239.         unix_entry_upp = NewRoutineDescriptor((long (*)())unix_entry,
  240.             unix_entry_ProcInfo,GetCurrentISA());
  241.         err = patch(dispatch,0x89abcdef,(long)unix_entry_upp);
  242.         if (err) goto error;
  243.     }
  244.  
  245.     LMStkLowPt = 0L;
  246.  
  247.     InitGraf(&qd.thePort);
  248.     FlushEvents(everyEvent,0);
  249.     InitFonts();
  250.     InitWindows();
  251.     InitMenus();
  252.     TEInit();
  253.     InitDialogs(0L);
  254.     InitCursor();
  255.  
  256.     object_list = 0L;
  257.     init_proc();
  258.     
  259.     err = 0;
  260.     err |= AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments,do_ae_peel_args_upp,0,0);
  261.     err |= AEInstallEventHandler(kCoreEventClass,kAEPrintDocuments,do_nothing_upp,0,0);
  262.     err |= AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,do_nothing_upp,0,0);
  263.     err |= AEInstallEventHandler(kCoreEventClass,kAEOpenApplication,do_nothing_upp,0,0);
  264.     if (err) goto error;
  265.     build_argument_list();
  266.     *argc = init_argc;
  267.     *argv = init_argv;
  268.     err = AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments,do_nothing_upp,0,0);
  269.     if (err) goto error;
  270.     if (getwd_internal(u) == 0L) chdir_internal("~/");
  271.  
  272.     watch = **GetCursor(watchCursor);
  273.     beachball[0] = watch;
  274.     for (i = 1; i<8; ++i)
  275.         beachball[i] = **GetCursor(128+i-1);
  276.     SetCursor(&watch);
  277.  
  278.     unix_init_kbd();
  279.  
  280.     err = NewGestalt('uniX',dispatch_upp);
  281.     if (err) {
  282.         err = ReplaceGestalt('uniX',dispatch_upp,&oldfunc);
  283.         if (err) goto error;
  284.     }
  285.  
  286.     fd = open_internal("/dev/tty",0);
  287.     dup_internal(fd);
  288.     dup_internal(fd);
  289.  
  290.     err = unixfn2FSSpec_internal("~/",&spec,0);
  291.     if (err) goto error;
  292.     err = FSSpec2unixfn_internal(&spec,&s);
  293.     if (err) goto error;
  294.     t = NewPtr(GetHandleSize(s) + 5);
  295.     if (MemError()) goto error;
  296.     strcpy(t,"HOME=");
  297.     strcat(t,*s);
  298.     DisposHandle(s);
  299.     if (environ_address) {
  300.         *environ_address = (char **)NewPtr(2 * sizeof(char *));
  301.         if (MemError()) goto error;
  302.         (*environ_address)[0] = t;
  303.         (*environ_address)[1] = 0L;
  304.         proctable[current_process_index].environ_address = environ_address;
  305.     }
  306.     
  307.     return;
  308.  
  309.     error:
  310.     ExitToShell();
  311. }
  312.