home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / MacGofer 0.22d / MacGofer Sources / mac_utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-31  |  6.0 KB  |  280 lines  |  [TEXT/MPS ]

  1. /*****************************************************************************
  2.  
  3.   mac_undo.c:  Copyright (c) Kevin Hammond 1993.   All rights reserved.
  4.   
  5.   Utility Functions.
  6.   
  7. *****************************************************************************/
  8.  
  9.  
  10. #include "mac.h"
  11.  
  12. #pragma segment Utils
  13.  
  14. extern pascal Boolean AutoScroll();
  15.  
  16. extern jmp_buf      catch_error;
  17. extern CursHandle   watchcurs, gccurs;    /* Watch and GC cursors */
  18. extern CCrsrHandle  gccursc;        /* Colour version of GC cursor */
  19. extern Boolean      CCAvailable;    /* Are colour cursors available */
  20. extern Boolean      inForeground;    /* Are we in the background? */
  21.  
  22. /* 
  23.   See if a trap is available.
  24.   Non-available traps all have the same unique address.
  25. */
  26.  
  27. #define Unimplemented 0xA89F          /* Unimplemented trap */
  28.  
  29.  
  30. Boolean TrapAvailable (trap,type)
  31. short trap, type;
  32. {
  33.   return(NGetTrapAddress(trap, type) != GetTrapAddress(Unimplemented));
  34. }
  35.  
  36. /*
  37.    NB: A Macintosh TN says TextEdit may fail if the size of the 
  38.    viewrect (?destrect?) is greater than 32767 pixels in area. 
  39.    BEWARE: I do not check this!
  40. */
  41.   
  42. /* Defined to make TE handling a little cleaner -- HSL */
  43. #define TE_RECT_INSET    4
  44. #define    TE_RECT_WIDTH    1024
  45.  
  46. void CalculateTERects(Rect *theViewR, Rect *theDestR, short theLineHeight,int fittovr)
  47. /* Calculates the view and destination rectangles for a TE */
  48. /* Assumes that the current port is set to the TE's port */
  49. {
  50.   Rect pr = qd.thePort->portRect;
  51.   short roundedViewHeight;
  52.   short te_rect_width = qd.screenBits.bounds.right > TE_RECT_WIDTH?
  53.                         qd.screenBits.bounds.right: TE_RECT_WIDTH;
  54.  
  55. //  if((pr.right - (SCROLLBARWIDTH - 1))*(pr.bottom - (SCROLLBARWIDTH - 1)) > 32767)
  56. //   AbortError("Internal","View Rectangle too large for TextEdit to handle");
  57.    
  58.   SetRect(theViewR, 0, 0, pr.right - (SCROLLBARWIDTH - 1), pr.bottom - (SCROLLBARWIDTH - 1));
  59.   InsetRect(theViewR, TE_RECT_INSET, TE_RECT_INSET);
  60.   roundedViewHeight = ((theViewR->bottom - theViewR->top) / theLineHeight) * theLineHeight;
  61.   theViewR->bottom = theViewR->top + roundedViewHeight;
  62.  
  63.   if(fittovr)
  64.     {
  65.       *theDestR = *theViewR;
  66.       theDestR->right -= 16;
  67.     }
  68.   else
  69.     {
  70.       SetRect(theDestR, 0, 0, TE_RECT_WIDTH+TE_RECT_INSET, 16384);
  71.       InsetRect(theDestR, TE_RECT_INSET, TE_RECT_INSET);
  72.     }
  73. }
  74.  
  75.  
  76. /* 
  77.   Create a new TE record.
  78. */
  79.  
  80. NewTERec(windex,fittoviewrect)
  81. int windex;
  82. int fittoviewrect;
  83. {
  84.   TEHandle teh;
  85.   Rect vr, dr;
  86.   FontInfo textFontInfo;
  87.   
  88.   TEHANDLE(windex) = NIL;
  89.  
  90.   GetFontInfo(&textFontInfo);
  91.   CalculateTERects(&vr, &dr, textFontInfo.ascent + textFontInfo.descent + textFontInfo.leading, fittoviewrect);
  92.     
  93.   teh = TENew(&dr, &vr);
  94.   
  95.   if(teh == NIL)
  96.     AbortError("Memory ","Out of Memory -- Closing windows may help");
  97.  
  98.   SetClikLoop((ClikLoopProcPtr)AutoScroll,teh); /* Install auto-scroll function */
  99.  
  100.   /* Deactivate the existing TE area */
  101.   if (thefrontwindow != ILLEGAL_WINDOW && TEHANDLE(thefrontwindow) != NIL)
  102.     TEDeactivate(TEHANDLE(thefrontwindow));
  103.  
  104. /*  (*teh)->crOnly = -1;                          /* Don't wrap lines. */
  105.  
  106.   TEHANDLE(windex) = teh;
  107. }
  108.  
  109.  
  110. /*
  111.    Update windows for which there is an outstanding update event.
  112.    This is used to clear up after dialogs when we intend to perform a
  113.    non-trivial action before returning to the main event loop.
  114. */
  115.  
  116. void updatewindows()
  117. {
  118.   extern EventRecord myEvent;
  119.  
  120.   while(EventAvail(updateMask|activMask,&myEvent))
  121.     {
  122.       GetNextEvent(updateMask|activMask,&myEvent);
  123.       if(myEvent.what == activateEvt)
  124.         DoActivate();
  125.       else
  126.         DoUpdate();
  127.     }
  128. }
  129.  
  130.  
  131.  
  132. /*
  133.     Lock a window's TE Handle, using a semaphore.
  134.     We use these routines rather than simply HLock,
  135.     to avoid unlocking a handle during recursive calls.
  136. */
  137.  
  138.  
  139. TEHLock(w)
  140. int w;
  141. {
  142.    if( TELOCK(w)++ == 0)
  143.      if(TEHANDLE(w) != NIL)
  144.        HLock((Handle) TEHANDLE(w));
  145. }
  146.  
  147.  
  148. /*
  149.     Unlock a window's TE Handle, using a semaphore.
  150. */
  151.  
  152.  
  153. TEHUnlock(w)
  154. int w;
  155. {
  156.    if( TELOCK(w) > 0)
  157.      if(--TELOCK(w)==0)
  158.        if(TEHANDLE(w) != NIL)
  159.          HUnlock((Handle) TEHANDLE(w));
  160. }
  161.  
  162. /*
  163.    A safe version of malloc(), which aborts back to the main event loop.
  164. */
  165.  
  166. char *safemalloc(n)
  167. unsigned n;
  168. {
  169.   extern char *malloc();
  170.   char *temp = malloc(n);
  171.  
  172.   if(temp == NIL)
  173.     {
  174.       Error("Memory ","Out of Memory -- Closing windows may help");
  175.       longjmp(catch_error,26);
  176.     }
  177.   return(temp);
  178. }
  179.  
  180.  
  181. char *safecalloc(n,s)
  182. unsigned n,s;
  183. {
  184.   extern char *calloc();
  185.   char *temp = calloc(n,s);
  186.  
  187.   if(temp == NIL)
  188.     {
  189.       mprintf("Failed to allocate %u bytes of memory\n",n*s);
  190. //      Error("Memory ","Out of Memory -- Closing windows may help");
  191.       longjmp(catch_error,27);
  192.     }
  193.   return(temp);
  194. }
  195.  
  196.  
  197. SetGCCursor(set)
  198. Boolean set;
  199. {
  200.   if(inForeground)
  201.     {
  202.       if(set)
  203.         if(CCAvailable)
  204.           SetCCursor(gccursc);
  205.          else
  206.           SetCursor(*gccurs);
  207.       else
  208.         SpinCursor(0);
  209.     }
  210. }
  211.  
  212. /*
  213.     Handle the multitasking event loop.
  214.     In utils.c rather than machine.c so that variables
  215.     etc. are in scope.
  216. */
  217.  
  218. multitaskeventloop()
  219. {
  220.   do {
  221.     eventloop(everyEvent);
  222.   } while (myEvent.what != nullEvent);
  223.  
  224.   if(thefrontwindow == worksheet)
  225.     SpinCursor(4);
  226. }
  227.  
  228.  
  229. #define    LOW_MEM_LIMIT    50000
  230.  
  231. CheckMemory(kind,amount)
  232. char *kind;
  233. unsigned amount;
  234. {
  235.   static Boolean memerr = FALSE, lowmemerr = FALSE;
  236.   unsigned long maxblock = MaxBlock();
  237.  
  238.   /*
  239.      Allow enough room to complete the largest operation.
  240.   */
  241.   if(maxblock < amount)
  242.     {
  243.       if(!lowmemerr)
  244.         {
  245.       char s[256];
  246.       sprintf(s,"Aborting '%s' Operation -- Only %ld Bytes Left",kind,maxblock);
  247.           Error("",s);
  248.     }
  249.       else
  250.         SysBeep(1);
  251.       memerr = lowmemerr = TRUE;
  252.       longjmp(catch_error,33);
  253.     }
  254.        
  255.   else if(maxblock < LOW_MEM_LIMIT)
  256.     {
  257.       if(!memerr)
  258.         {
  259.       char s[256];
  260.       sprintf(s,"Memory Low in %s operation (%ld Bytes Left) -- Try Closing Windows?",kind,maxblock);
  261.           Error("Warning ",s);
  262.     }
  263.       memerr = TRUE;
  264.       lowmemerr = FALSE;
  265.     }
  266.  
  267.   else
  268.     lowmemerr = memerr = FALSE;
  269. }
  270.  
  271.  
  272. ResetCursor()
  273. {
  274.   if(inForeground)
  275.     {
  276.       getnextevent(nullEvent);
  277.       drawcursor(myEvent,FALSE);
  278.     }
  279. }
  280.