home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff386.lzh / XLispStat / src3.lzh / Mac / maciviewwindow.c < prev    next >
C/C++ Source or Header  |  1990-07-30  |  18KB  |  684 lines

  1. #ifdef MPWC
  2. #include <Windows.h>
  3. #include <Menus.h>
  4. #include <ToolUtils.h>
  5. #include <Events.h>
  6. #include <Controls.h>
  7. #include <Fonts.h>
  8. #include <Memory.h>
  9. #include <Script.h>
  10. #include <Resources.h>
  11. #else
  12. #include <WindowMgr.h>
  13. #include <MenuMgr.h>
  14. #include <ToolboxUtil.h>
  15. #include <EventMgr.h>
  16. #include <ControlMgr.h>
  17. #include <FontMgr.h>
  18. #include <ColorToolbox.h>
  19. #include <ResourceMgr.h>
  20. #endif MPWC
  21.  
  22. #include "StGWWindow.h"
  23. #include "macgraphwindow.h"
  24. #include "stmem.h"
  25.  
  26. extern mac_update_action(), mac_activate_action(), mac_close_action();
  27.  
  28.  
  29. char *IViewWindowWinInfo(w)
  30.     WindowPtr w;
  31. {
  32.   return((w != nil) ? (char *) GetWRefCon(w) : nil);
  33. }
  34.  
  35. /**************************************************************************/
  36. /**                                                                      **/
  37. /**                       Initialization Functions                       **/
  38. /**                                                                      **/
  39. /**************************************************************************/
  40.  
  41. StInitGraphics()
  42. {
  43.   initialize_static_globals();
  44.   init_mac_colors();
  45.   init_mac_cursors();
  46. }
  47.  
  48. /**************************************************************************/
  49. /**                                                                      **/
  50. /**                       Window Creation Functions                      **/
  51. /**                                                                      **/
  52. /**************************************************************************/
  53.  
  54. Rect scroll_bar_bounds(w, which)
  55.     WindowPtr w;
  56.     int which;
  57. {
  58.   Rect r;
  59.   
  60.   r = w->portRect;
  61.   switch(which) {
  62.   case 'H':
  63.     r.top = r.bottom - 15; r.right -= 14; r.left--; r.bottom++; break;
  64.   case 'V':
  65.     r.left = r.right - 15; r.bottom -= 14; r.top--; r.right++; break;
  66.   }
  67.   return(r);
  68. }
  69.  
  70. static int which_scroll, old_view_h, old_view_v;
  71.  
  72. static pascal void scroll_action(theCtl, part)
  73.     ControlHandle theCtl;
  74.     short part;
  75. {
  76.   StGWWinInfo *gwinfo = (StGWWinInfo *) GetWRefCon(thePort);
  77.   int value = GetCtlValue(theCtl);
  78.   int left, top, width, height, inc, pageInc;
  79.   WindowPtr w = thePort;
  80.   char *object;
  81.   
  82.   object = (char *) StGWGetObject(gwinfo);
  83.  
  84.   if (gwinfo == nil) return;
  85.   
  86.   switch (which_scroll) {
  87.   case 'H': 
  88.     inc = gwinfo->h_scroll_inc[0];
  89.     pageInc = gwinfo->h_scroll_inc[1];
  90.     break;
  91.   case 'V': 
  92.     inc = gwinfo->v_scroll_inc[0];
  93.     pageInc = gwinfo->v_scroll_inc[1];
  94.     break;
  95.   }
  96.   
  97.   switch(part) {
  98.   case inUpButton: value -= inc; break;
  99.   case inDownButton: value += inc; break;
  100.   case inPageUp: value -= pageInc; break;
  101.   case inPageDown: value += pageInc; break;
  102.   }
  103.   switch (which_scroll) {
  104.   case 'H': StGWSetScroll(gwinfo, value, gwinfo->view_v, FALSE); break;
  105.   case 'V': StGWSetScroll(gwinfo, gwinfo->view_h, value, FALSE); break;
  106.   }
  107.   reset_clip_rect(gwinfo);
  108.   StGWGetViewRect(gwinfo, &left, &top, &width, &height);
  109.   StGWStartBuffering(gwinfo);
  110.   StGWObRedraw(object);
  111.   StGWBufferToScreen(gwinfo, left, top, width, height);
  112.   SetPort(w);
  113.   SetOrigin(old_view_h, old_view_v);
  114.   ClipRect(&w->portRect);
  115. }
  116.  
  117. static mouse_action(pt, t, mods)
  118.      Point pt;
  119.      long t;
  120.      int mods;
  121. {
  122.   StGWWinInfo *gwinfo = (StGWWinInfo *) GetWRefCon(thePort);
  123.   ControlHandle theCtl;
  124.   int part, h, v, option, extend;
  125.   WindowPtr w = thePort;
  126.   Rect r;
  127.   char *object;
  128.   
  129.   object = (char *) StGWGetObject(gwinfo);
  130.  
  131.   if (gwinfo == nil) return;
  132.   
  133.   if ((part = FindControl(pt, w, &theCtl)) != 0) {
  134.     if (theCtl == gwinfo->hscroll) which_scroll = 'H';
  135.     else which_scroll = 'V';
  136.     ClipRect(&w->portRect);
  137.     if (part != 0 && part != inThumb) {
  138.       old_view_h = GetCtlValue(gwinfo->hscroll);
  139.       old_view_v = GetCtlValue(gwinfo->vscroll);
  140.       TrackControl(theCtl, pt, (ProcPtr) scroll_action);
  141.       SetPort(w);
  142.       SetOrigin(gwinfo->view_h, gwinfo->view_v);
  143.       SetRect(&r, 0, 0, 0, 0);
  144.       ClipRect(&r);
  145.       r = scroll_bar_bounds(w, 'H');
  146.       MoveControl(gwinfo->hscroll, r.left, r.top);
  147.       r = scroll_bar_bounds(w, 'V');
  148.       MoveControl(gwinfo->vscroll, r.left, r.top);
  149.     }
  150.     else if (part == inThumb) 
  151.       if (TrackControl(theCtl, pt, nil) == inThumb) {
  152.         h = GetCtlValue(gwinfo->hscroll);
  153.         v = GetCtlValue(gwinfo->vscroll);
  154.         StGWSetScroll(gwinfo, h, v, TRUE);
  155.         reset_clip_rect(gwinfo);
  156.         StGWObRedraw(object);
  157.       }
  158.     reset_clip_rect(gwinfo);
  159.   }
  160.   else {
  161.     extend = BitAnd(mods, shiftKey);
  162.     option = BitAnd(mods, optionKey);
  163.     mods = (extend) ? ExtendModifier : NoModifiers;
  164.     if (option) mods += 2;
  165.     StGWObDoMouse(gwinfo->Object, pt.h, pt.v, MouseClick, (MouseClickModifier) mods);
  166.   }
  167.   SetPort(w);                 /* I don't know why this is here - maybe it is needed */
  168. /*  ValidRect(&w->portRect);*//* This definitely causes problems */
  169. }
  170.  
  171. static key_action(key, mods)
  172.      char key;
  173.      int mods;
  174. {
  175.   StGWWinInfo *gwinfo = (StGWWinInfo *) GetWRefCon(thePort);
  176.   char *object;
  177.   int shift, opt;
  178.   
  179.   if (gwinfo == nil) return;
  180.   object = (char *) StGWGetObject(gwinfo);
  181.   shift = BitAnd(mods, shiftKey);
  182.   opt = BitAnd(mods, optionKey);
  183.   if (key == '\r') key = '\n';
  184.   StGWObDoKey(object, key, shift, opt);
  185. }
  186.  
  187. graph_update_action(gwinfo, resized)
  188.     StGWWinInfo *gwinfo;
  189.     int resized;
  190. {
  191.   WindowPtr w;
  192.   int width, height;
  193.   GrafPtr savePort;
  194.   Rect r;
  195.   char *object;
  196.   
  197.   if (gwinfo == nil || (w = gwinfo->window) == nil) return;
  198.   
  199.   object = (char *) StGWGetObject(gwinfo);
  200.  
  201.   GetPort(&savePort);
  202.   SetPort(w);
  203.   if (! gwinfo->initialized) {
  204.     resized = TRUE;
  205.     gwinfo->initialized = TRUE;
  206.   }
  207.   
  208.   if (resized) {
  209.     reset_clip_rect(gwinfo);
  210.     EraseRect(&w->portRect);
  211.     StGWGetViewRect(gwinfo, nil, nil, &width, &height);
  212.     
  213.     if (gwinfo->hasHscroll) {
  214.       HideControl(gwinfo->hscroll);
  215.       width = (gwinfo->canvasWidth > width) ? gwinfo->canvasWidth - width : 0;
  216.       SetCtlMax(gwinfo->hscroll, width);
  217.       SetCtlValue(gwinfo->hscroll, gwinfo->view_h);
  218.       gwinfo->view_h = GetCtlValue(gwinfo->hscroll);
  219.     }
  220.  
  221.     if (gwinfo->hasVscroll) {
  222.       HideControl(gwinfo->vscroll);
  223.       height = (gwinfo->canvasHeight > height) ? gwinfo->canvasHeight - height : 0;
  224.       SetCtlMax(gwinfo->vscroll, height);
  225.       SetCtlValue(gwinfo->vscroll, gwinfo->view_v);
  226.       gwinfo->view_v = GetCtlValue(gwinfo->vscroll);
  227.     }
  228.  
  229.     SetOrigin(gwinfo->view_h, gwinfo->view_v);
  230.     r = scroll_bar_bounds(w, 'H');
  231.     MoveControl(gwinfo->hscroll, r.left, r.top);
  232.     SizeControl(gwinfo->hscroll, r.right - r.left, r.bottom - r.top);
  233.     r = scroll_bar_bounds(w, 'V');
  234.     MoveControl(gwinfo->vscroll, r.left, r.top);
  235.     SizeControl(gwinfo->vscroll, r.right - r.left, r.bottom - r.top);
  236.     ClipRect(&w->portRect);
  237.     if (gwinfo->hasHscroll) ShowControl(gwinfo->hscroll);
  238.     if (gwinfo->hasVscroll) ShowControl(gwinfo->vscroll);
  239.  
  240.     reset_clip_rect(gwinfo);
  241.   }
  242.   
  243.   if (resized && gwinfo != nil) {
  244.     if (! gwinfo->hasHscroll)
  245.       gwinfo->canvasWidth = w->portRect.right
  246.                          - w->portRect.left - 15;
  247.     if (! gwinfo->hasVscroll) {
  248.       gwinfo->canvasHeight = w->portRect.bottom
  249.                           - w->portRect.top;
  250.       if (gwinfo->hasHscroll) gwinfo->canvasHeight -= 15;
  251.     }
  252.     StGWObResize(object);
  253.   }
  254.   
  255.   StGWObRedraw(object);
  256.   
  257.   DrawGWGrowBox(gwinfo);
  258.   SetPort(w);
  259.   ClipRect(&w->portRect);
  260.   DrawControls(w);
  261.   reset_clip_rect(gwinfo);
  262.   SetHardwareState(gwinfo);
  263.   SetPort(w);
  264. }
  265.  
  266. DrawGWGrowBox(gwinfo)
  267.     StGWWinInfo *gwinfo;
  268. {
  269.   WindowPtr w;
  270.   Rect r;
  271.   GrafPtr savePort;
  272.   int reverse;
  273.   
  274.   if (gwinfo == nil || (w = gwinfo->window) == nil) return;
  275.   
  276.   reverse = (StGWBackColor(gwinfo) != 0);
  277.   GetPort(&savePort);
  278.   SetPort(w);
  279.     
  280.   r = w->portRect;
  281.   r.left = r.right - 15;
  282.   ClipRect(&r);
  283.   ForeColor(blackColor);
  284.   BackColor(whiteColor);
  285.   if (! StGWHasVscroll(gwinfo)) EraseRect(&r);
  286.   DrawGrowIcon(w);
  287.   if (reverse) {
  288.     r = w->portRect;
  289.     r.left = r.right - 15;
  290.     if (StGWHasVscroll(gwinfo)) r.top = r.bottom - 15;
  291.     if (! StGWHasVscroll(gwinfo)) InvertRect(&r);
  292.   }
  293.   set_fore_color(gwinfo);
  294.   set_back_color(gwinfo);
  295.   
  296.   reset_clip_rect(gwinfo);
  297.   SetHardwareState(gwinfo);
  298.   SetPort(savePort);
  299. }
  300.  
  301. graph_activate_action(gwinfo, active)
  302.     StGWWinInfo *gwinfo;
  303.     int active;
  304. {
  305.   WindowPtr w;
  306.   Point pt;
  307.   int value;
  308.   
  309.   if (gwinfo == nil || (w = gwinfo->window) == nil) return;
  310.   
  311.   if (active) DoCursor(gwinfo);
  312.   else SetCursor(&arrow);
  313.   
  314.   GetMouse(&pt);
  315.   gwinfo->mouse_x = pt.h; gwinfo->mouse_y = pt.v;
  316.   DrawGWGrowBox(gwinfo);
  317.   
  318.   SetPort(w);
  319.   ClipRect(&w->portRect);
  320.   value = (active) ? 0 : 255;
  321.   HiliteControl(gwinfo->hscroll, value);
  322.   HiliteControl(gwinfo->vscroll, value);
  323.   reset_clip_rect(gwinfo);
  324. }
  325.  
  326. static clobber_action()
  327. {
  328.   WindowPtr wind = thePort;
  329.   StGWWinInfo *gwinfo = (StGWWinInfo *) GetWRefCon(thePort);
  330.  
  331.   if (IViewInternalIsLinked(wind)) IViewUnlinkWindow(wind);
  332.   StGWObDoClobber(gwinfo->Object);
  333.   if (gwinfo != nil && gwinfo->FreeMem != nil) (*gwinfo->FreeMem)(wind);
  334.  
  335.   gwinfo->window = nil;
  336.  
  337.   DisposeWindow(wind);
  338. }
  339.  
  340. static idle_action() 
  341. {
  342.   WindowPtr wind = thePort;
  343.   StGWWinInfo *gwinfo = (StGWWinInfo *) GetWRefCon(wind);
  344.   Point pt;
  345.   int old_x, old_y;
  346.   
  347.   if (gwinfo != nil && wind == FrontWindow()) {
  348.     DoCursor(gwinfo);
  349.     old_x = gwinfo->mouse_x; old_y = gwinfo->mouse_y;
  350.     GetMouse(&pt);
  351.     gwinfo->mouse_x = pt.h; gwinfo->mouse_y = pt.v;
  352.     if ((abs(gwinfo->mouse_x - old_x) > MOUSE_TOLERANCE
  353.          || abs(gwinfo->mouse_y - old_y) > MOUSE_TOLERANCE)) {
  354.       GetMouse(&pt);
  355.       gwinfo->mouse_x = pt.h; gwinfo->mouse_y = pt.v;     
  356.       StGWObDoMouse(gwinfo->Object, pt.h, pt.v, MouseMove, 0);
  357.     }
  358.   }
  359.   if (gwinfo != nil && gwinfo->idleOn) StGWObDoIdle(gwinfo->Object);
  360. }
  361.  
  362. StGWWinInfoSize() { return(sizeof(StGWWinInfo)); }
  363.  
  364. StGWInitWinInfo(object)
  365.     char *object;
  366. {
  367.   StGWWinInfo *gwinfo = (StGWWinInfo *) StGWObWinInfo(object);
  368.  
  369.   gwinfo->Object = (long) object;
  370.   gwinfo->initialized = FALSE;
  371.   gwinfo->symbolMode = srcCopy;
  372.   gwinfo->canvasWidth = 0;
  373.   gwinfo->canvasHeight = 0;
  374.   gwinfo->hasHscroll = FALSE;
  375.   gwinfo->hasVscroll = FALSE;
  376.   gwinfo->view_h = 0;
  377.   gwinfo->view_v = 0;
  378.   gwinfo->h_scroll_inc[0] = 1; gwinfo->h_scroll_inc[1] = 50;
  379.   gwinfo->v_scroll_inc[0] = 1; gwinfo->v_scroll_inc[1] = 50;
  380.   gwinfo->lineType = 0;
  381.   gwinfo->drawMode = 0;
  382.   gwinfo->backColor = 0;
  383.   gwinfo->drawColor = 1;
  384.   gwinfo->lineWidth = 1;
  385.   gwinfo->window = nil;
  386.   gwinfo->idleOn = FALSE;
  387.   gwinfo->use_color = FALSE;
  388.   gwinfo->cursor = 0;
  389.   gwinfo->RefCon = nil;
  390. }
  391.  
  392. WindowPtr IViewWindowNew(object, is_GW)
  393.     char *object;
  394.     int is_GW;
  395. {
  396.   char *title;
  397.   int left, top, width, height, goAway;
  398.   StGWWinInfo *gwinfo;
  399.   WindowPtr wind;
  400.   Rect r;
  401.   
  402.   StGWGetAllocInfo(object, &title, &left, &top, &width, &height, &goAway);
  403.   if (title == nil || strlen(title) <= 0) title = "Graph Window";
  404.   
  405.   SetRect(&r, left, top, left + width + 15, top + height);
  406.               
  407.   CtoPstr(title);
  408.   if (StScreenHasColor())
  409.     wind = NewCWindow(nil, &r, title, FALSE, 8, (WindowPtr) -1L, goAway, 0L);
  410.   else  
  411.     wind = NewWindow(nil, &r, title, FALSE, 8, (WindowPtr) -1L, goAway, 0L);
  412.   PtoCstr(title);
  413.   if (wind == nil) StPerror("allocation Failed");
  414.   
  415.   SkelWindow(wind, mouse_action, key_action, mac_update_action, 
  416.          mac_activate_action, mac_close_action, clobber_action,
  417.          idle_action, FALSE);
  418.          
  419.   SetPort(wind);
  420.   TextSize(9);
  421.   TextMode(srcXor);
  422.   
  423.   gwinfo = (StGWWinInfo *) StGWObWinInfo(object);
  424.   
  425.   r = wind->portRect;
  426.   r.top = r.bottom - 15; r.right -= 14; r.left--; r.bottom++;
  427.   gwinfo->hscroll = NewControl(wind, &r, "\p", FALSE, 0, 0, 0, 
  428.                               scrollBarProc, 0L);
  429.   r = wind->portRect;
  430.   r.left = r.right - 15; r.bottom -= 14; r.top--; r.right++;
  431.   gwinfo->vscroll = NewControl(wind, &r, "\p", FALSE, 0, 0, 0, 
  432.                               scrollBarProc, 0L);
  433.  
  434.   gwinfo->window = wind;
  435.   if (! gwinfo->hasHscroll) gwinfo->canvasWidth = width;
  436.   if (! gwinfo->hasVscroll) gwinfo->canvasHeight = height;
  437.   gwinfo->initialized = FALSE;
  438.  
  439.   SetWRefCon(wind, (long) gwinfo);
  440.   SetHardwareState(gwinfo);
  441.   StGWEraseRect(gwinfo, 0, 0, width, height);
  442.   StGWSetClipRect(gwinfo, FALSE, 0, 0, 0, 0);
  443.   
  444.   if (is_GW) set_iview_window_address(wind, object);
  445.   else set_iview_address(wind, object);
  446.  
  447.   return(wind);
  448. }
  449.  
  450. /**************************************************************************/
  451. /**                                                                      **/
  452. /**                          Clipping  Functions                         **/
  453. /**                                                                      **/
  454. /**************************************************************************/
  455.  
  456. StGWSetClipRect(gwinfo, clipped, left, top, width, height)
  457.     StGWWinInfo *gwinfo;
  458.     int clipped, left, top, width, height;
  459. {
  460.   if (gwinfo == nil) return;
  461.   gwinfo->clipped = clipped;
  462.   if (clipped) {
  463.     SetRect(&gwinfo->clip_rect, left, top, left + width, top + height);
  464.   }
  465.   reset_clip_rect(gwinfo);
  466. }
  467.  
  468. StGWGetClipRect(gwinfo, left, top, width, height)
  469.     StGWWinInfo *gwinfo;
  470.     int *left, *top, *width, *height;
  471. {
  472.   if (gwinfo == nil) return(FALSE);
  473.   if (gwinfo->clipped) {
  474.     if (left != nil) *left = gwinfo->clip_rect.left;
  475.     if (top != nil) *top = gwinfo->clip_rect.top;
  476.     if (width != nil) *width = gwinfo->clip_rect.right - gwinfo->clip_rect.left;
  477.     if (height != nil) *height = gwinfo->clip_rect.bottom - gwinfo->clip_rect.top;
  478.   }
  479.   return(gwinfo->clipped);
  480. }
  481.  
  482. /**************************************************************************/
  483. /**                                                                      **/
  484. /**                         Miscelaneous Functions                       **/
  485. /**                                                                      **/
  486. /**************************************************************************/
  487.  
  488. extern char *realloc();
  489.  
  490. #define NumBasicCursors 9
  491. static int NumCursors;
  492.  
  493. typedef struct {
  494.   CursHandle curs;
  495.   long refcon;
  496. } cursor_entry;
  497.  
  498. static cursor_entry *curstab;
  499.  
  500. init_mac_cursors()
  501. {
  502.   NumCursors = NumBasicCursors;
  503.   curstab = (cursor_entry *) StCalloc(NumCursors, sizeof(cursor_entry));
  504. }
  505.  
  506. StGWSetCursRefCon(index, rc)
  507.     unsigned int index;
  508.     long rc;
  509. {
  510.   if (index < NumCursors) curstab[index].refcon = rc;
  511. }
  512.  
  513. long StGWGetCursRefCon(index)
  514.     unsigned int index;
  515. {    
  516.   if (index < NumCursors) return(curstab[index].refcon);
  517.   else return(nil);
  518. }
  519.  
  520. static set_image_bits(n, bits, image)
  521.     int n;
  522.     char *bits, *image;
  523. {
  524.   int i;
  525.   
  526.   for (i = 0; i < n; i++) {
  527.     if (image[i] == 0) BitClr(bits, i);
  528.     else BitSet(bits, i);
  529.   }
  530. }
  531.  
  532. static clear_image_bits(n, bits)
  533.     int n;
  534.     char *bits;
  535. {
  536.   int i;
  537.   
  538.   for (i = 0; i < n; i++) BitClr(bits, i);
  539. }
  540.   
  541. StGWMakeCursor(n, image, mask, h, v, refcon)
  542.     int n, h, v;
  543.     char *image, *mask;
  544.     long refcon;
  545. {
  546.   int index;
  547.   char *temp;
  548.   CursHandle curs;
  549.   
  550.   if (n != 16 || image == nil) return(-1);
  551.   for (index = 0; index < NumCursors && StGWGetCursRefCon(index) != nil; index++);
  552.   if (index >= NumCursors) {
  553.     temp = realloc(curstab, (NumCursors + 1) * sizeof(cursor_entry));
  554.     if (temp == nil) return(-1);
  555.     curstab = (cursor_entry *) temp;
  556.     NumCursors++;
  557.     curstab[index].curs = nil;
  558.     curstab[index].refcon = nil;
  559.   }
  560.   if (curstab[index].curs != nil) DisposHandle((Handle) curstab[index].curs);
  561.   curs = (CursHandle) NewHandle(sizeof(Cursor));
  562.   if (curs == nil) return(-1);
  563.   
  564.   if (mask == nil) clear_image_bits(n * n, (*curs)->mask);
  565.   else set_image_bits(n * n, (*curs)->mask, mask);
  566.   set_image_bits(n * n, (*curs)->data, image);
  567.   (*curs)->hotSpot.h = h;
  568.   (*curs)->hotSpot.v = v;
  569.   curstab[index].curs = curs;
  570.   curstab[index].refcon = refcon;
  571.   return(index);
  572. }
  573.  
  574. StGWMakeResCursor(name, num, refcon)
  575.     char *name;
  576.     int num;
  577.     long refcon;
  578. {
  579.   int index;
  580.   char *temp;
  581.   CursHandle curs, curs_copy;
  582.   
  583.   for (index = 0; index < NumCursors && StGWGetCursRefCon(index) != nil; index++);
  584.   if (index >= NumCursors) {
  585.     temp = realloc(curstab, (NumCursors + 1) * sizeof(cursor_entry));
  586.     if (temp == nil) return(-1);
  587.     curstab = (cursor_entry *) temp;
  588.     NumCursors++;
  589.     curstab[index].curs = nil;
  590.     curstab[index].refcon = nil;
  591.   }
  592.   if (curstab[index].curs != nil) DisposHandle((Handle) curstab[index].curs);
  593.   
  594.   if (name != nil) {
  595.     CtoPstr(name);
  596.     curs = (CursHandle) GetNamedResource('CURS', name);
  597.     PtoCstr(name);
  598.   }
  599.   else curs = GetCursor(num);
  600.   
  601.   if (curs == nil) return(-1);
  602.   curs_copy = (CursHandle) NewHandle(sizeof(Cursor));
  603.   if (curs_copy == nil) return(-1);
  604.   **curs_copy = **curs;
  605.   
  606.   curstab[index].curs = curs_copy;
  607.   curstab[index].refcon = refcon;
  608.   return(index);
  609. }
  610.  
  611. StGWFreeCursor(index)
  612.     unsigned int index;
  613. {
  614.   if (index < NumCursors && index >= NumBasicCursors) {
  615.     if (curstab[index].curs != nil)
  616.       DisposHandle((Handle) curstab[index].curs);
  617.     curstab[index].curs = nil;
  618.     curstab[index].refcon = nil;
  619.   }
  620.   else StPerror("can't free standard cursor");
  621. }
  622.  
  623. static CursHandle get_cursor(index)
  624.     unsigned int index;
  625. {
  626.   CursHandle curs = nil;
  627.   
  628.   if (index < NumBasicCursors) {
  629.     switch (index) {
  630.     case ARROW_CURSOR:      curs = nil;                    break;
  631.     case WATCH_CURSOR:      curs = GetCursor(watchCursor); break;
  632.     case CROSS_CURSOR:      curs = GetCursor(crossCursor); break;
  633.     case BRUSH_CURSOR:      curs = GetCursor(BRUSH_RES);   break;
  634.     case HAND_CURSOR:       curs = GetCursor(HAND_RES);    break;
  635.     case FINGER_CURSOR:     curs = GetCursor(FINGER_RES);  break;
  636.     case HOUR_GLASS_CURSOR: curs = GetCursor(GLASS_RES);   break;
  637.     case TRASH_BAG_CURSOR:  curs = GetCursor(BAG_RES);     break;
  638.     case TRASH_CAN_CURSOR:  curs = GetCursor(CAN_RES);     break;
  639.     }
  640.   }
  641.   else if (index < NumCursors)
  642.     curs = curstab[index].curs;
  643.     
  644.   return(curs);
  645. }
  646.   
  647. mac_do_cursor(gwinfo) StGWWinInfo *gwinfo; { DoCursor(gwinfo); }
  648.  
  649. static DoCursor(gwinfo)
  650.     StGWWinInfo *gwinfo;
  651. {
  652.   int left, top, width, height;
  653.   Point pt;
  654.   CursHandle curs = nil;
  655.   WindowPtr w;
  656.   
  657.   if (gwinfo == nil || (w = gwinfo->window) == nil) return;
  658.   GetMouse(&pt);
  659.   StGWGetViewRect(gwinfo, &left, &top, &width, &height);
  660.     
  661.   if (w == FrontWindow()
  662.       && pt.h > left && pt.h < left + width
  663.       && pt.v > top && pt.v < top + height)
  664.     curs = get_cursor(StGWCursor(gwinfo));
  665.   if (curs != nil) SetCursor(*curs);
  666.   else SetCursor(&arrow);
  667. }
  668.  
  669. StGWSetCursor(gwinfo, cursor)
  670.     StGWWinInfo *gwinfo;
  671.     int cursor;
  672. {
  673.   if (gwinfo == nil) return;
  674.   gwinfo->cursor = cursor;
  675. }
  676.  
  677. StGWCursor(gwinfo)
  678.     StGWWinInfo *gwinfo;
  679. {
  680.   if (gwinfo == nil) return(FALSE);
  681.   return(gwinfo->cursor);
  682. }
  683.  
  684.