home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / MacPerl 5.1.3 / Mac_Perl_513_src / MacPerl5 / MPUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-17  |  19.5 KB  |  809 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. Project    :    MacPerl            -    Real Perl Application
  3. File        :    MPUtils.c    -
  4. Author    :    Matthias Neeracher
  5.  
  6. A lot of this code is borrowed from 7Edit written by
  7. Apple Developer Support UK
  8.  
  9. Language    :    MPW C
  10.  
  11. $Log: MPUtils.c,v $
  12. Revision 1.2  1994/05/04  02:52:40  neeri
  13. Inline Input.
  14.  
  15. Revision 1.1  1994/02/27  23:02:08  neeri
  16. Initial revision
  17.  
  18. Revision 0.5  1993/08/17  00:00:00  neeri
  19. DoPrefDialog()
  20.  
  21. Revision 0.4  1993/08/15  00:00:00  neeri
  22. DoAbout
  23.  
  24. Revision 0.3  1993/08/14  00:00:00  neeri
  25. Preference file
  26.  
  27. Revision 0.2  1993/05/30  00:00:00  neeri
  28. Support Console Windows
  29.  
  30. Revision 0.1  1993/05/29  00:00:00  neeri
  31. Compiles correctly
  32.  
  33. *********************************************************************/
  34.  
  35. #include <PLStringFuncs.h>
  36. #include <Events.h>
  37. #include <Traps.h>
  38. #include <Dialogs.h>
  39. #include <Fonts.h>
  40. #include <Packages.h>
  41. #include <ToolUtils.h>
  42. #include <AppleEvents.h>
  43. #include <TFileSpec.h>
  44. #include <Folders.h>
  45. #include <Resources.h>
  46. #include <Sound.h>
  47. #include <OSUtils.h>
  48. #include <Files.h>
  49. #include <Lists.h>
  50. #include <Icons.h>
  51. #include <TSMTE.h>
  52. #include <string.h>
  53. #include <GUSI.h>
  54. #include <Desk.h>
  55. #include <ctype.h>
  56. #include <stdio.h>
  57.  
  58. #include "MPUtils.h"
  59. #include "MPWindow.h"
  60. #include "patchlevel.h"
  61.  
  62. /**-----------------------------------------------------------------------
  63.         Name:         ShowError
  64.         Purpose:        Reports an error to the user as both string and number.
  65.     -----------------------------------------------------------------------**/
  66. #if !defined(powerc) && !defined(__powerc)
  67. #pragma segment Utils
  68. #endif
  69.  
  70. pascal void ShowError(Str255 theError, long theErrorCode)
  71. {
  72.     short     alertResult;
  73.     Str255    theString;
  74.  
  75.     if (gAppleEventsImplemented)
  76.         if (AEInteractWithUser(kAEDefaultTimeout, nil,nil))
  77.             return;
  78.         
  79.      SetCursor(&qd.arrow);
  80.      NumToString(theErrorCode, theString);
  81.      ParamText(theError, theString, (StringPtr) "\p", (StringPtr) "\p");
  82.      alertResult = Alert(300, nil);
  83. } /* ShowError */
  84.  
  85. /**-----------------------------------------------------------------------
  86.         Name:         Ours
  87.         Purpose:        Checks the frontmost window belongs to the app.
  88.     -----------------------------------------------------------------------**/
  89. #if !defined(powerc) && !defined(__powerc)
  90. #pragma segment Utils
  91. #endif
  92.  
  93. pascal Boolean Ours(WindowPtr aWindow)
  94. {
  95.     return aWindow && (GetWindowKind(aWindow) == PerlWindowKind);
  96. } /* Ours */
  97.  
  98. /**-----------------------------------------------------------------------
  99.         Name:         SetShortMenus
  100.         Purpose:        Cuts the menus down to a minimum - Apple File Edit.
  101.                         Greys out the unavailable options - used when no docs open
  102.     -----------------------------------------------------------------------**/
  103. #if !defined(powerc) && !defined(__powerc)
  104. #pragma segment Utils
  105. #endif
  106.  
  107. pascal void SetShortMenus()
  108. {
  109.     DeleteMenu(windowID);
  110.  
  111.     DrawMenuBar();
  112. }  /* SetShortMenus */
  113.  
  114. /**-----------------------------------------------------------------------
  115.         Name:         SetLongMenus
  116.         Purpose:        Reinstates the full menu bar - called when first document
  117.                     opened.
  118.     -----------------------------------------------------------------------**/
  119. #if !defined(powerc) && !defined(__powerc)
  120. #pragma segment Utils
  121. #endif
  122.  
  123. pascal void SetLongMenus()
  124. {
  125.     InsertMenu(myMenus[windowM], perlID);
  126.  
  127.     DrawMenuBar();
  128. }  /* SetLongMenus */
  129.  
  130. /**-----------------------------------------------------------------------
  131.     Name:       SetEditMenu
  132.     Purpose:    Set the text of the edit menu according to the state of
  133.                      current document.
  134.   -----------------------------------------------------------------------**/
  135.  
  136. #if !defined(powerc) && !defined(__powerc)
  137. #pragma segment Utils
  138. #endif
  139.  
  140. pascal void SetEditMenu(DPtr theDoc)
  141. {
  142. #ifdef EVIL_USELESS_EDITIONS
  143.     if (theDoc->kind == kDocumentWindow && theDoc->u.reg.showBorders)
  144.         SetItem(myMenus[editM], cBorders, (StringPtr) "\pHide Borders");
  145.     else
  146.         SetItem(myMenus[editM], cBorders, (StringPtr) "\pShow Borders");
  147. #endif
  148. }  /* SetEditMenu */
  149.  
  150. /**-----------------------------------------------------------------------
  151.     Name:       GetTempFSSpec
  152.     Purpose:    Fills newstring create temporary file specification.
  153.   -----------------------------------------------------------------------**/
  154.  
  155. #if !defined(powerc) && !defined(__powerc)
  156. #pragma segment Utils
  157. #endif
  158.  
  159. pascal void GetTempFSSpec(DPtr aDoc, FSSpec * temp)
  160. {
  161.     Special2FSSpec(kTempFileType, aDoc->theFSSpec.vRefNum, 0, temp);
  162. }
  163.  
  164. /**-----------------------------------------------------------------------
  165.     Name:       SetText
  166.     Purpose:    Sets the text of the supplied itemNo in aDialog to
  167.                     theString and select it.
  168.   -----------------------------------------------------------------------**/
  169.  
  170. #if !defined(powerc) && !defined(__powerc)
  171. #pragma segment Utils
  172. #endif
  173.  
  174. pascal void SetText(DialogPtr aDialog, short itemNo, Str255 theString)
  175. {
  176.     Handle      itemHandle;
  177.     Rect        box;
  178.     short       kind;
  179.     TEHandle    theTEHandle;
  180.  
  181.     GetDItem(aDialog, itemNo, &kind, &itemHandle, &box);
  182.     SetIText(itemHandle, theString);
  183.  
  184.     theTEHandle = ((DialogPeek)aDialog)->textH;
  185.  
  186.     /*set all the text to be selected*/
  187.     if (theTEHandle)
  188.         TESetSelect(0, 255, theTEHandle);
  189. }
  190.  
  191. /**-----------------------------------------------------------------------
  192.     Name:       RetrieveText
  193.     Purpose:    Returns the text of anItem in aDialog in aString.
  194.   -----------------------------------------------------------------------**/
  195.  
  196. #if !defined(powerc) && !defined(__powerc)
  197. #pragma segment Utils
  198. #endif
  199.  
  200. pascal void RetrieveText(DialogPtr aDialog, short anItem, Str255 aString)
  201. {
  202.     short      kind;
  203.     Rect       box;
  204.     Handle     itemHandle;
  205.  
  206.     GetDItem(aDialog, anItem, &kind, &itemHandle, &box);
  207.     GetIText(itemHandle, aString);
  208. }
  209.  
  210. /**-----------------------------------------------------------------------
  211.     Name:      DrawDefaultOutline
  212.     Purpose:   Draws an outline around theItem.
  213.                     Called as a useritem Proc by the dialog manager.
  214.                     To use place a useritem over the default item in the
  215.                     dialog and install the address of this proc as the item
  216.                     handle.
  217.   -----------------------------------------------------------------------**/
  218.  
  219. #if !defined(powerc) && !defined(__powerc)
  220. #pragma segment Utils
  221. #endif
  222.  
  223. pascal void DrawDefaultOutline(DialogPtr theDialog, short theItem)
  224. {
  225.     short       kind;
  226.     Handle      itemHandle;
  227.     Rect        box;
  228.  
  229.     GetDItem(theDialog, theItem, &kind, &itemHandle, &box);
  230.     PenSize(3, 3);
  231.     InsetRect(&box, -4, -4);
  232.     FrameRoundRect(&box, 16, 16);
  233.     PenNormal();
  234. }  /* DrawDefaultOutline */
  235.  
  236. #if USESROUTINEDESCRIPTORS
  237. RoutineDescriptor    uDrawDefaultOutline = 
  238.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, DrawDefaultOutline);
  239. #endif
  240.  
  241. /**-----------------------------------------------------------------------
  242.     Name:       AdornDefaultButton
  243.     Purpose:    Installs DrawDefaultOutline as the useritem proc
  244.                      for the given item.
  245. -----------------------------------------------------------------------**/
  246.  
  247. #if !defined(powerc) && !defined(__powerc)
  248. #pragma segment Utils
  249. #endif
  250.  
  251. pascal void AdornDefaultButton(DialogPtr theDialog,short theItem)
  252. {
  253.     short        kind;
  254.     Handle    itemHandle;
  255.      Rect        box;
  256.  
  257.     GetDItem(theDialog, theItem, &kind, &itemHandle, &box);
  258.     SetDItem(theDialog, theItem, kind, (Handle)&uDrawDefaultOutline, &box);
  259. }
  260.  
  261. pascal void GetRectOfDialogItem(DialogPtr theDialog, short theItem, Rect *theRect)
  262. {
  263.     short       kind;
  264.     Handle      itemHandle;
  265.  
  266.     GetDItem(theDialog, theItem, &kind, &itemHandle, theRect);
  267. }
  268.  
  269. /**------  FeatureIsImplemented    ------------**/
  270. /*    This is called to use Gestalt to determine if a feature is implemented.
  271.      This applies to only those referenced by OSType    */
  272.  
  273. #if !defined(powerc) && !defined(__powerc)
  274. #pragma segment Utils
  275. #endif
  276.  
  277. pascal Boolean FeatureIsImplemented(OSType theFeature, short theTestBit)
  278. {
  279.      long      result;
  280.  
  281.     return !Gestalt(theFeature, &result) && (result & (1 << theTestBit));
  282. }
  283.  
  284. #if !defined(powerc) && !defined(__powerc)
  285. #pragma segment Utils
  286. #endif
  287.  
  288. pascal Boolean CheckEnvironment()
  289. {
  290.     long result;
  291.     
  292.     /*check for the AppleEvents manager - we certainly can't work without it*/
  293.  
  294.     gAppleEventsImplemented   = FeatureIsImplemented(gestaltAppleEventsAttr, gestaltAppleEventsPresent);
  295.  
  296. #ifdef EVIL_USELESS_EDITIONS
  297.     /*first check if the Edition Manager is present*/
  298.  
  299.     gEditionManagerImplemented = FeatureIsImplemented(gestaltEditionMgrAttr, gestaltEditionMgrPresent);
  300. #endif
  301.  
  302.     /*and for good measure- the Alias manager*/
  303.  
  304.     gAliasManagerImplemented  = FeatureIsImplemented(gestaltAliasMgrAttr, gestaltAliasMgrPresent);
  305.  
  306.     /*check if recording is implemented*/
  307.  
  308.     gRecordingImplemented   = FeatureIsImplemented(gestaltAppleEventsAttr,1);
  309.  
  310.     /*check for the Outline fonts*/
  311.  
  312.     gOutlineFontsImplemented  = FeatureIsImplemented(gestaltFontMgrAttr, gestaltOutlineFonts);
  313.  
  314.     /* check for Text Services and TSMTE */
  315.     gTextServicesImplemented = !Gestalt(gestaltTSMgrVersion, &result) && (result > 0);
  316.     gTSMTEImplemented    = FeatureIsImplemented(gestaltTSMTEAttr, gestaltTSMTEPresent);
  317.  
  318.     return     gAliasManagerImplemented   &&
  319. #ifdef EVIL_USELESS_EDITIONS
  320.                 gEditionManagerImplemented &&
  321. #endif
  322.                 gAppleEventsImplemented    &&
  323.                 gOutlineFontsImplemented;
  324. }  /* CheckEnvironment */
  325.  
  326. /*
  327.     DoPageSetup returns true if the page setup of the document is altered
  328. */
  329.  
  330. pascal Boolean DoPageSetup(DPtr theDoc)
  331. {
  332.     if (theDoc) {
  333.         Boolean result;
  334.  
  335.         PrOpen();
  336.         result =  PrStlDialog(theDoc->thePrintSetup);
  337.         PrClose();
  338.  
  339.         return(result);
  340.     }
  341.     
  342.     return false;
  343. }  /* DoPageSetup */
  344.  
  345. /*
  346.     Name:    CtrlKeyPressed
  347.     Purpose: Returns true if control key pressed during event
  348. */
  349. pascal Boolean CtrlKeyPressed(const EventRecord *theEvent)
  350. {
  351.     return theEvent->modifiers & controlKey;
  352. }
  353.  
  354. /*
  355.     Name:    OptionKeyPressed
  356.     Purpose: Returns true if option key pressed during event
  357. */
  358. pascal Boolean OptionKeyPressed(const EventRecord *theEvent)
  359. {
  360.     return theEvent->modifiers & optionKey;
  361. }
  362.  
  363. pascal void DrawVersion(DialogPtr dlg, short item)
  364. {
  365.     VersRecHndl    vers;
  366.     short         resFile;
  367.     short            base;
  368.     Handle        h;
  369.     Rect            r;
  370.     FontInfo        info;
  371.  
  372.     GetDItem(dlg, item, &base, &h, &r);
  373.     SetPort(dlg);
  374.     TextFont(1);
  375.     TextSize(10);
  376.     GetFontInfo(&info);
  377.     
  378.     base = r.top+2+info.ascent;
  379.     MoveTo(r.left+2, base);
  380.     DrawString((StringPtr) "\pVersion");
  381.     MoveTo((r.left+r.right) >> 1, r.top+2+info.ascent);
  382.  
  383.     resFile = CurResFile();
  384.     UseResFile(gAppFile);
  385.     vers = (VersRecHndl) Get1Resource('vers', 1);
  386.     HLock((Handle) vers);
  387.     DrawString((*vers)->shortVersion);
  388.     ReleaseResource((Handle) vers);
  389.     UseResFile(resFile);
  390. }
  391.  
  392. #if USESROUTINEDESCRIPTORS
  393. RoutineDescriptor    uDrawVersion = 
  394.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, DrawVersion);
  395. #else
  396. #define uDrawVersion *(UserItemUPP)&DrawVersion
  397. #endif
  398.  
  399. static ListHandle    CreditList;
  400.  
  401. pascal void DrawCredits(DialogPtr dlg, short item)
  402. {
  403. #if !defined(powerc) && !defined(__powerc)
  404. #pragma unused(item)
  405. #endif
  406.     Rect    r;
  407.     
  408.     TextFont(1);
  409.     TextSize(9);
  410.     r = (*CreditList)->rView;
  411.     MoveTo(r.left + 4, r.top - 8);
  412.     TextFace(bold);
  413.     DrawString("\pThanks to:");
  414.     TextFace(normal);
  415.     LUpdate(dlg->visRgn, CreditList);
  416. }
  417.  
  418. #if USESROUTINEDESCRIPTORS
  419. RoutineDescriptor    uDrawCredits = 
  420.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, DrawCredits);
  421. #else
  422. #define uDrawCredits *(UserItemUPP)&DrawCredits
  423. #endif
  424.  
  425. pascal void DoAbout(Boolean easter)
  426. {
  427.     DialogPtr        dlg;
  428.     WindowPtr        win;
  429.     short                kind;
  430.     short                count;
  431.     Handle            hdl;
  432.     Handle            sound;
  433.     SndChannelPtr     channel = nil;
  434.     long                nextAction;
  435.     Point             cell;
  436.     Rect                bounds;
  437.     Rect                dbounds;
  438.     Str255            string;
  439.     EventRecord     ev;
  440.     
  441.     SetCursor(&qd.arrow);
  442.     
  443.     dlg     = GetNewDialog(AboutDialog, nil, (WindowPtr) -1);
  444.     sound = GetResource('snd ', AlertSoundID+easter);
  445.     hdl     = GetResource('STR#', CreditID);
  446.     count    = **(short **) hdl;
  447.  
  448.     GetDItem(dlg, ad_PatchLevel, &kind, &hdl, &bounds);
  449.     SetDItem(dlg, ad_PatchLevel, kind, (Handle) &uDrawVersion, &bounds);
  450.     GetDItem(dlg, ad_Credits, &kind, &hdl, &bounds);
  451.     SetDItem(dlg, ad_Credits, kind, (Handle) &uDrawCredits, &bounds);
  452.  
  453.     bounds.top   += 20;
  454.  
  455.     SetPort(dlg);
  456.     TextFont(1);
  457.     TextSize(9);
  458.     SetPt(&cell, bounds.right - bounds.left, 12);
  459.     SetRect(&dbounds, 0, 0, 1, count);
  460.     CreditList = LNew(&bounds, &dbounds, cell, 0, dlg, false, false, false, false);
  461.     
  462.     SetPt(&cell, 0, 0);
  463.     for (; cell.v < count; ++cell.v) {
  464.         GetIndString(string, CreditID, cell.v+1);
  465.         LSetCell((Ptr)(string+1), *string, cell, CreditList);
  466.     }
  467.     LDoDraw(true, CreditList);
  468.     
  469.     HideDialogItem(dlg, ad_Version);
  470.     ShowWindow(dlg);
  471.     DrawDialog(dlg);
  472.     
  473.     nextAction = TickCount()+30;
  474.     SetPt(&cell, 0, count-1);
  475.     
  476.     while (dlg) {
  477.         if (TickCount() > nextAction) {
  478.             if (sound) {
  479.                 RgnHandle versRgn = NewRgn();
  480.  
  481.                 HLock(sound);
  482.                 if (!SndNewChannel(&channel, sampledSynth, initMono, nil))
  483.                     SndPlay(channel, (SndListHandle) sound, true);
  484.                     
  485.                 ShowDialogItem(dlg, ad_Version);
  486.                 GetDItem(dlg, ad_Version, &kind, &hdl, &bounds);
  487.                 RectRgn(versRgn, &bounds);
  488.                 UpdateDialog(dlg, versRgn);
  489.                 DisposeRgn(versRgn);
  490.                 
  491.                 if (channel)
  492.                     SndDisposeChannel(channel, false);
  493.                     
  494.                 ReleaseResource(sound);
  495.                 sound = nil;
  496.             } else {
  497.                 LSetSelect(false, cell, CreditList);
  498.                 cell.v = (cell.v+1) % count;
  499.                 LSetSelect(true, cell, CreditList);
  500.                 LAutoScroll(CreditList);
  501.             }
  502.             nextAction += 30;
  503.         }
  504.         
  505.         if (WaitNextEvent(mDownMask+keyDownMask+activMask+updateMask+osMask, &ev, 1, nil))
  506.             switch (ev.what) {
  507.             case activateEvt:
  508.                 if ((WindowPtr) ev.message != dlg)
  509.                     DoActivate((WindowPtr)ev.message, (ev.modifiers & activeFlag) != 0);
  510.                 else 
  511.                     LActivate(ev.modifiers & activeFlag, CreditList);
  512.     
  513.                 break;
  514.     
  515.             case updateEvt:
  516.                 win = (WindowPtr) ev.message;
  517.                 if (win == dlg) {
  518.                     BeginUpdate(dlg);
  519.                     UpdateDialog(dlg, dlg->visRgn);
  520.                     EndUpdate(dlg);
  521.                 } else
  522.                     DoUpdate(DPtrFromWindowPtr(win), win);
  523.                 break;
  524.     
  525.             case kOSEvent:
  526.                 switch (ev.message & osEvtMessageMask) { /*high byte of message*/
  527.                 case 0x01000000:
  528.                         gInBackground = ((ev.message & resumeFlag) == 0);
  529.                 }
  530.                 if (!gInBackground)
  531.                     break;
  532.             default:
  533.                 DisposeDialog(dlg);
  534.                 
  535.                 dlg = nil;
  536.                 break;
  537.             }
  538.     }
  539. }
  540.  
  541. static void CenterWindow(DialogPtr dlg)
  542. {
  543.     Rect    *        screen;
  544.     short            hPos;
  545.     short            vPos;
  546.     
  547.     screen    =    &qd.screenBits.bounds;
  548.     hPos    =    screen->right+screen->left-dlg->portRect.right >> 1;
  549.     vPos    =    (screen->bottom-screen->top-dlg->portRect.bottom)/3;
  550.     vPos    +=    screen->top;
  551.     MoveWindow(dlg, hPos, vPos, true);
  552. }    
  553.  
  554. pascal void Separator(DialogPtr dlg, short item)
  555. {
  556.     short        kind;
  557.     Handle    h;
  558.     Rect        r;
  559.     
  560.     PenPat(&qd.gray);
  561.     GetDItem(dlg, item, &kind, &h, &r);
  562.     FrameRect(&r);
  563.     PenPat(&qd.black);
  564. }
  565.  
  566. #if USESROUTINEDESCRIPTORS
  567. RoutineDescriptor    uSeparator = 
  568.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, Separator);
  569. #endif
  570.  
  571. static DPtr        Documents[50];
  572. static short    DocCount = 0;
  573.  
  574. pascal void RegisterDocument(DPtr doc)
  575. {
  576.     Documents[DocCount++] = doc;
  577. }
  578.  
  579. pascal void UnregisterDocument(DPtr doc)
  580. {
  581.     short    i,j;
  582.     
  583.     for (i = 0, j = 0; i < DocCount; ++i)
  584.         if (Documents[i] != doc)
  585.             Documents[j++] = Documents[i];
  586.     
  587.     DocCount = j;
  588. }
  589.  
  590. pascal void SetupWindowMenu()
  591. {
  592.     short            i;
  593.     short            item = 0;
  594.     WindowPtr    front;
  595.     WindowPtr    win;
  596.     MenuHandle    menu;
  597.     Str255        name;
  598.     int             needsSeparator = 0;
  599.     
  600.     DisposeMenu(myMenus[windowM]);
  601.     menu = myMenus[windowM]    = GetMenu(windowID);
  602.     
  603.     front = FrontWindow();
  604.     
  605.     for (i = 0; i < DocCount; ++i)
  606.         if (Documents[i]->kind != kDocumentWindow) {
  607.             AppendMenu(menu, (StringPtr) "\px");
  608.             GetWTitle(Documents[i]->theWindow, name);
  609.             SetMenuItemText(menu, ++item, name);
  610.             
  611.             if (!IsWindowVisible(Documents[i]->theWindow))
  612.                 SetItemStyle(menu, item, italic);
  613.             else if (Documents[i]->theWindow == front)
  614.                 SetItemMark(menu, item, checkMark);
  615.             
  616.             EnableItem(menu, item);
  617.             needsSeparator = 1;
  618.         }
  619.     
  620.     for (i = 0; i < DocCount; ++i)
  621.         if (Documents[i]->kind == kDocumentWindow) {
  622.             if (needsSeparator && needsSeparator < 2) {
  623.                 AppendMenu(menu, (StringPtr) "\p-(");
  624.                 ++item;
  625.             }
  626.             
  627.             AppendMenu(menu, (StringPtr) "\px");
  628.             GetWTitle(Documents[i]->theWindow, name);
  629.             SetMenuItemText(menu, ++item, name);
  630.             
  631.             if (!IsWindowVisible(Documents[i]->theWindow))
  632.                 SetItemStyle(menu, item, Documents[i]->dirty ? underline + italic : italic);
  633.             else {
  634.                 if (Documents[i]->dirty)
  635.                     SetItemStyle(menu, item, underline);
  636.                 if (Documents[i]->theWindow == front)
  637.                     SetItemMark(menu, item, checkMark);
  638.             }
  639.             
  640.             EnableItem(menu, item);
  641.             needsSeparator = 2;
  642.         }
  643.     
  644.     for (win = front; win; win = GetNextWindow(win)) {
  645.         if (IsWindowVisible(win) && !Ours(win)) {
  646.             if (needsSeparator && needsSeparator < 3) {
  647.                 AppendMenu(menu, (StringPtr) "\p-(");
  648.                 ++item;
  649.             }
  650.             
  651.             AppendMenu(menu, (StringPtr) "\px");
  652.             GetWTitle(win, name);
  653.             SetMenuItemText(menu, ++item, name);
  654.             
  655.             if (win == front)
  656.                 SetItemMark(menu, item, checkMark);
  657.             
  658.             EnableItem(menu, item);
  659.             needsSeparator = 3;
  660.         }
  661.     }
  662. }
  663.  
  664. static void AnointWindow(WindowPtr win)
  665. {
  666.     if (!IsWindowVisible(win))
  667.         ShowWindow(win);
  668.     SelectWindow(win);
  669. }
  670.  
  671. pascal void DoSelectWindow(short item)
  672. {
  673.     short            i;
  674.      WindowPtr    win;
  675.     MenuHandle    menu;
  676.     int             needsSeparator = 0;
  677.     
  678.     menu = myMenus[windowM];
  679.     
  680.     for (i = 0; i < DocCount; ++i)
  681.         if (Documents[i]->kind != kDocumentWindow) {
  682.             if (!--item) {
  683.                 AnointWindow(Documents[i]->theWindow);
  684.                 
  685.                 return;
  686.             }
  687.             needsSeparator = 1;
  688.         }
  689.     
  690.     for (i = 0; i < DocCount; ++i)
  691.         if (Documents[i]->kind == kDocumentWindow) {
  692.             if (needsSeparator && needsSeparator < 2) {
  693.                 --item;
  694.             }
  695.             
  696.             if (!--item) {
  697.                 AnointWindow(Documents[i]->theWindow);
  698.                 
  699.                 return;
  700.             }
  701.             
  702.             needsSeparator = 2;
  703.         }
  704.     
  705.     for (win = FrontWindow(); win; win = GetNextWindow(win)) {
  706.         if (IsWindowVisible(win) && !Ours(win)) {
  707.             if (needsSeparator && needsSeparator < 3) {
  708.                 --item;
  709.             }
  710.             
  711.             if (!--item) {
  712.                 AnointWindow(win);
  713.                 
  714.                 return;
  715.             }
  716.             
  717.             needsSeparator = 3;
  718.         }
  719.     }
  720. }
  721.  
  722. /* Borrowed from tech note 263 */
  723.  
  724. #define kKosherModifiers    0x0E00        // We keep only option & shift
  725. #define kMaskVirtualKey     0x0000FF00     // get virtual key from event message
  726.                                            // for KeyTrans
  727. #define kUpKeyMask          0x0080
  728. #define kShiftWord          8              // we shift the virtual key to mask it
  729.                                            // into the keyCode for KeyTrans
  730. #define kMaskASCII1         0x00FF0000     // get the key out of the ASCII1 byte
  731. #define kMaskASCII2         0x000000FF     // get the key out of the ASCII2 byte
  732.  
  733. pascal Boolean WeirdChar(const EventRecord * ev, short modifiers, char ch)
  734. {
  735.       short            keyCode;
  736.       long             virtualKey, keyInfo, lowChar, highChar, keyCId;
  737.     unsigned long    state;
  738.       Handle           hKCHR;
  739.     Ptr                 KCHRPtr;
  740.  
  741.     if ((ev->what == keyDown) || (ev->what == autoKey)) {
  742.  
  743.         // see if the command key is down.  If it is, find out the ASCII
  744.         // equivalent for the accompanying key.
  745.  
  746.         if ((ev->modifiers & 0xFF00) == modifiers) {
  747.  
  748.             virtualKey     = (ev->message & kMaskVirtualKey) >> kShiftWord;
  749.             keyCode          = (ev->modifiers & kKosherModifiers & ~modifiers) | virtualKey;
  750.             state           = 0;
  751.  
  752.             hKCHR            = nil;  /* set this to nil before starting */
  753.              KCHRPtr         = (Ptr)GetEnvirons(smKCHRCache);
  754.  
  755.             if ( !KCHRPtr ) {
  756.                 keyCId     =    GetScript((short) GetEnvirons(smKeyScript), smScriptKeys);
  757.                 hKCHR        =    GetResource('KCHR', (short) keyCId);
  758.                 KCHRPtr    = *hKCHR;
  759.             }
  760.  
  761.             if (KCHRPtr) {
  762.                 keyInfo = KeyTrans(KCHRPtr, keyCode, &state);
  763.                 if (hKCHR)
  764.                     ReleaseResource(hKCHR);
  765.             } else
  766.                 keyInfo = ev->message;
  767.  
  768.             lowChar =  keyInfo &  kMaskASCII2;
  769.             highChar = (keyInfo & kMaskASCII1) >> 16;
  770.             if (lowChar == ch || highChar == ch)
  771.                 return true;
  772.  
  773.         }  // end the command key is down
  774.     }  // end key down event
  775.  
  776.     return false;
  777. }
  778.  
  779.  
  780. pascal Boolean SameFSSpec(FSSpec * one, FSSpec * other)
  781. {
  782.     return     one->vRefNum    ==        other->vRefNum 
  783.         &&        one->parID        ==        other->parID
  784.         &&     EqualString(one->name, other->name, false, true);
  785. }
  786.  
  787. void RemoveConsole()
  788. {
  789. }
  790.  
  791. int faccess()
  792. {
  793.     return -1;
  794. }
  795.  
  796. #ifndef powerc
  797. #pragma far_data off
  798. #endif
  799.  
  800. int StandAlone = 1;
  801.  
  802. #ifndef powerc
  803. #pragma far_data reset
  804. #endif
  805.  
  806. void __ttyname()
  807. {
  808. }
  809.