home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1997: The Complete Utilities Toolkit / macworld-complete-utilities-1997.iso / Programming / GlueWindow4.2.1 / source(CodeWarrior5) / GW-INIT4.2.1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-15  |  33.9 KB  |  1,393 lines  |  [TEXT/MMCC]

  1. //    GW-INIT4.2.1.c
  2.  
  3. #include    "GW-INIT4.2.1.h"
  4.  
  5. //    Declaration of global variables
  6.  
  7. QDGlobals        myQDGlobals;
  8. SndListHandle    pushSndH, popSndH;
  9. CursHandle        handCursorH, gripCursorH;
  10. initDataHandle    settingH;
  11.  
  12. //    Main -----
  13.  
  14. void main(void)
  15. {
  16.     long    oldA4;
  17.     
  18.     oldA4 = SetCurrentA4();
  19.     RememberA4();
  20.     
  21.     if(isSystem7()) {
  22.         InitGraf(&myQDGlobals.thePort);
  23.         setupINIT();
  24.     }
  25.     SetA4(oldA4);
  26. }
  27.  
  28. Boolean isSystem7(void)
  29. {
  30.     Boolean    f = false;
  31.     OSErr    err;
  32.     long    res;
  33.     
  34.     if(trapAvailable(_Gestalt)) {
  35.         err = Gestalt(gestaltSystemVersion, &res);
  36.         if(err == noErr && res >= 0x0700)    f = true;
  37.     }
  38.     return(f);
  39. }
  40.  
  41. //    Utils -----
  42.  
  43. Boolean trapAvailable(short theTrap)
  44. {
  45.     TrapType    tType;
  46.     
  47.     tType = getTrapType(theTrap);
  48.     if(tType == ToolTrap)
  49.         theTrap = theTrap & 0x07FF;
  50.     if(theTrap >= numToolboxTrap())
  51.         theTrap = _Unimplemented;
  52.     
  53.     return(NGetTrapAddress(theTrap, tType) !=
  54.             NGetTrapAddress(_Unimplemented, ToolTrap));
  55. }
  56.  
  57. TrapType getTrapType(short theTrap)
  58. {
  59.     if((theTrap & trapMask) > 0)
  60.         return(ToolTrap);
  61.     else
  62.         return(OSTrap);
  63. }
  64.  
  65. short numToolboxTrap(void)
  66. {
  67.     if(NGetTrapAddress(_InitGraf, ToolTrap) ==
  68.             NGetTrapAddress(0xAA6E, ToolTrap))
  69.         return(0x0200);
  70.     else
  71.         return(0x0400);
  72. }
  73.  
  74. //
  75.  
  76. pascal Handle get1Resource(OSType rsrcType, short id)
  77. {
  78.     THz        oldZone;
  79.     Handle    h;
  80.     
  81.     oldZone = GetZone();
  82.     SetZone(SystemZone());
  83.     h = Get1Resource(rsrcType, id);
  84.     SetZone(oldZone);
  85.     return(h);
  86. }
  87.  
  88. pascal CursHandle getCursor(short id)
  89. {
  90.     THz            oldZone;
  91.     CursHandle    h;
  92.     
  93.     oldZone = GetZone();
  94.     SetZone(SystemZone());
  95.     h = GetCursor(id);
  96.     SetZone(oldZone);
  97.     return(h);
  98. }
  99. //    Setup -----
  100.  
  101. void setupINIT(void)
  102. {
  103.     short                iconID = OK_cicn_id;
  104.     Handle                h;
  105.     UniversalProcPtr    awayAddress, growAddress, dragAddress;
  106.     SelectorFunctionUPP    selectorFuncAddress;
  107.     
  108.     h = get1Resource('INIT', my_INIT_id);
  109.     if(h) {
  110.         settingH = loadSetting();
  111.         if(settingH) {
  112.             HLock(h);
  113.             HNoPurge(h);
  114.             DetachResource(h);
  115.             
  116.             awayAddress = NGetTrapAddress(_TrackGoAway,    ToolTrap);
  117.             dragAddress = NGetTrapAddress(_DragWindow,    ToolTrap);
  118.             growAddress = NGetTrapAddress(_GrowWindow,    ToolTrap);
  119.             
  120.             trackGoAwayProc    = (pascal Boolean (*)(WindowPtr, Point))awayAddress;
  121.             dragWindowProc    = (pascal void (*)(WindowPtr, Point, Rect*))dragAddress;
  122.             growWindowProc    = (pascal long (*)(WindowPtr, Point, Rect*))growAddress;
  123.             
  124.             NSetTrapAddress((UniversalProcPtr)trackGoAway, _TrackGoAway, ToolTrap);
  125.             NSetTrapAddress((UniversalProcPtr)dragWindow, _DragWindow, ToolTrap);
  126.             NSetTrapAddress((UniversalProcPtr)growWindow, _GrowWindow, ToolTrap);
  127.             
  128.             handCursorH = getCursor(hand_CURS_id);
  129.             if(handCursorH) {
  130.                 HNoPurge((Handle)handCursorH);
  131.                 DetachResource((Handle)handCursorH);
  132.             }
  133.             
  134.             gripCursorH = getCursor(grip_CURS_id);
  135.             if(gripCursorH) {
  136.                 HNoPurge((Handle)gripCursorH);
  137.                 DetachResource((Handle)gripCursorH);
  138.             }
  139.             
  140.             if(trapAvailable(_SndPlay)) {
  141.                 pushSndH    = (SndListHandle)get1Resource('snd ', push_sndx_id);
  142.                 popSndH        = (SndListHandle)get1Resource('snd ', pop_sndx_id);
  143.                 if(pushSndH) {
  144.                     DetachResource((Handle)pushSndH);
  145.                     HNoPurge((Handle)pushSndH);
  146.                 }
  147.                 else {
  148.                     (**settingH).pushSound = false;
  149.                 }
  150.                 if(popSndH) {
  151.                     DetachResource((Handle)popSndH);
  152.                     HNoPurge((Handle)popSndH);
  153.                 }
  154.                 else {
  155.                     (**settingH).popSound = false;
  156.                 }
  157.             }
  158.             
  159.             selectorFuncAddress = (SelectorFunctionUPP)gestaltSelector;
  160.             setSelectorFunc(selectorFuncAddress);
  161.             
  162.             if(!(**settingH).showIcon)
  163.                             iconID = NO_icon;
  164.         }
  165.         else {
  166.             iconID = NG_cicn_id;
  167.             ReleaseResource(h);
  168.         }
  169.     }
  170.     else {
  171.         iconID = NG_cicn_id;
  172.     }
  173.     drawIcon(iconID);
  174. }
  175.  
  176. void drawIcon(short iconID)
  177. {
  178.     Handle        iconH = nil;
  179.     GrafPtr        savedPortP;
  180.     GrafPort    tempPort;
  181.     Rect        r;
  182.     short        screenWidth;
  183.     Boolean        hasColor;
  184.     
  185.     if(iconID != NO_icon) {
  186.         hasColor = trapAvailable(_GetCIcon);
  187.         if(hasColor)
  188.             iconH = (Handle)GetCIcon(iconID);
  189.         else
  190.             iconH = GetIcon(iconID);
  191.         if(iconH) {
  192.             HNoPurge(iconH);
  193.             GetPort(&savedPortP);
  194.             OpenPort(&tempPort);
  195.             SetPort(&tempPort);
  196.             if(((iconLoc_h << 1) ^ 0x1021) != iconLoc_cs)    iconLoc_h = 8;
  197.             screenWidth = ((tempPort.portRect.right -
  198.                             tempPort.portRect.left) / 40) * 40;
  199.             r.left    = iconLoc_h % screenWidth;
  200.             r.right    = r.left + 32;
  201.             r.top    = tempPort.portRect.bottom -
  202.                         (40 * (1 + iconLoc_h / screenWidth));
  203.             r.bottom = r.top + 32;
  204.             
  205.             if(hasColor) {
  206.                 PlotCIcon(&r, (CIconHandle)iconH);
  207.                 DisposeCIcon((CIconHandle)iconH);
  208.             }
  209.             else {
  210.                 PlotIcon(&r, iconH);
  211.                 DisposeHandle(iconH);
  212.             }
  213.             
  214.             iconLoc_h += 40;
  215.             iconLoc_cs = (iconLoc_h << 1) ^ 0x1021;
  216.             
  217.             SetPort(savedPortP);
  218.             ClosePort(&tempPort);
  219.         }
  220.     }
  221. }
  222.  
  223. //    Selector -----
  224.  
  225. void setSelectorFunc(SelectorFunctionUPP selectorFuncAddress)
  226. {
  227.     long    oldA4;
  228.     OSErr    err;
  229.     
  230.     oldA4 = SetUpA4();
  231.     err = NewGestalt(myCreator, selectorFuncAddress);
  232.     RestoreA4(oldA4);
  233. }
  234.  
  235. pascal OSErr gestaltSelector(OSType selector, long *response)
  236. {
  237.     long    oldA4;
  238.     
  239.     oldA4 = SetUpA4();
  240.     *response = (long)settingH;
  241.     RestoreA4(oldA4);
  242.     return(noErr);
  243. }
  244.  
  245. //    Load -----
  246.  
  247. initDataHandle loadSetting(void)
  248. {
  249.     initDataHandle    dH = nil;
  250.     prefsFileSpec    pfSpec;
  251.     OSErr            err;
  252.     short            savedRefNum;
  253.     
  254.     savedRefNum = CurResFile();
  255.     err = openPrefsFile(&pfSpec);
  256.     if(err == noErr) {
  257.         dH = load420Data();
  258.         if(dH == nil) {
  259.             dH = load412Data();
  260.         }
  261.         if(dH == nil) {
  262.             dH = load401Data();
  263.         }
  264.         if(dH == nil) {
  265.             err = ResError();
  266.             if(err == resNotFound) {
  267.                 dH = setDefaultData();
  268.                 if(dH) {
  269.                     saveSetting(dH);
  270.                 }
  271.             }
  272.         }
  273.         CloseResFile(pfSpec.RsrcRefNum);
  274.         UseResFile(savedRefNum);
  275.     }
  276.     else if(err == resFNotFound || err == fnfErr) {
  277.         err = createPrefsFile();
  278.         if(err == noErr)
  279.             err = openPrefsFile(&pfSpec);
  280.         if(err == noErr) {
  281.             dH = setDefaultData();
  282.             if(dH) {
  283.                 saveSetting(dH);
  284.             }
  285.             CloseResFile(pfSpec.RsrcRefNum);
  286.             UseResFile(savedRefNum);
  287.         }
  288.     }
  289.     
  290.     return(dH);
  291. }
  292.  
  293. initDataHandle load420Data(void)
  294. {
  295.     initDataHandle    dH = nil;
  296.  
  297.     dH = (initDataHandle)get1Resource(myDataType, gw420_DATA_id);
  298.     if(dH) {
  299.         HNoPurge((Handle)dH);
  300.         DetachResource((Handle)dH);
  301.     }
  302.     return(dH);
  303. }
  304.  
  305. initDataHandle load412Data(void)
  306. {
  307.     initDataHandle    dH = nil;
  308.     gw412DataHandle    oldH = nil;
  309.     
  310.     oldH = (gw412DataHandle)get1Resource(myDataType, gw412_DATA_id);
  311.     if(oldH) {
  312.         dH = (initDataHandle)NewHandleSys(sizeof(initData));
  313.         if(dH) {
  314.             (**dH).dragOn        = (**oldH).dragOn;
  315.             (**dH).noMarquee    = (**oldH).noMarquee;
  316.             (**dH).glueOn        = defaultGlueOn;
  317.             (**dH).growOn        = (**oldH).growOn;
  318.             (**dH).pushOn        = (**oldH).pushOn;
  319.             (**dH).popOn        = (**oldH).popOn;
  320.             (**dH).pushSound    = (**oldH).pushSound;
  321.             (**dH).popSound        = (**oldH).popSound;
  322.             (**dH).dragKey[0]    = (**oldH).dragKey[0];
  323.             (**dH).dragKey[1]    = (**oldH).dragKey[1];
  324.             (**dH).dragKey[2]    = (**oldH).dragKey[2];
  325.             (**dH).dragKey[3]    = (**oldH).dragKey[3];
  326.             (**dH).glueKey[0]    = defaultGlueKey0;
  327.             (**dH).glueKey[1]    = defaultGlueKey1;
  328.             (**dH).glueKey[2]    = defaultGlueKey2;
  329.             (**dH).glueKey[3]    = defaultGlueKey3;
  330.             (**dH).pushKey[0]    = (**oldH).pushKey[0];
  331.             (**dH).pushKey[1]    = (**oldH).pushKey[1];
  332.             (**dH).pushKey[2]    = (**oldH).pushKey[2];
  333.             (**dH).pushKey[3]    = (**oldH).pushKey[3];
  334.             (**dH).popKey[0]    = (**oldH).popKey[0];
  335.             (**dH).popKey[1]    = (**oldH).popKey[1];
  336.             (**dH).popKey[2]    = (**oldH).popKey[2];
  337.             (**dH).popKey[3]    = (**oldH).popKey[3];
  338.             (**dH).showIcon        = (**oldH).showIcon;
  339.             HNoPurge((Handle)dH);
  340.             saveSetting(dH);
  341.         }
  342.         ReleaseResource((Handle)oldH);
  343.     }
  344.     return(dH);
  345. }
  346.  
  347. initDataHandle load401Data(void)
  348. {
  349.     initDataHandle    dH = nil;
  350.     gw401DataHandle    oldH;
  351.     
  352.     oldH = (gw401DataHandle)Get1Resource(myDataType, gw401_DATA_id);
  353.     if(oldH) {
  354.         dH = (initDataHandle)NewHandleSys(sizeof(initData));
  355.         if(dH) {
  356.             (**dH).dragOn        = (**oldH).dragOn;
  357.             (**dH).noMarquee    = defaultNoMarquee;
  358.             (**dH).glueOn        = defaultGlueOn;
  359.             (**dH).growOn        = (**oldH).growOn;
  360.             (**dH).pushOn        = (**oldH).pushOn;
  361.             (**dH).popOn        = (**oldH).popOn;
  362.             (**dH).pushSound    = (**oldH).pushSound;
  363.             (**dH).popSound        = (**oldH).popSound;
  364.             (**dH).dragKey[0]    = defaultDragKey0;
  365.             (**dH).dragKey[1]    = defaultDragKey1;
  366.             (**dH).dragKey[2]    = defaultDragKey2;
  367.             (**dH).dragKey[3]    = defaultDragKey3;
  368.             (**dH).glueKey[0]    = defaultGlueKey0;
  369.             (**dH).glueKey[1]    = defaultGlueKey1;
  370.             (**dH).glueKey[2]    = defaultGlueKey2;
  371.             (**dH).glueKey[3]    = defaultGlueKey3;
  372.             (**dH).pushKey[0]    = (**oldH).pushKey[0];
  373.             (**dH).pushKey[1]    = (**oldH).pushKey[1];
  374.             (**dH).pushKey[2]    = (**oldH).pushKey[2];
  375.             (**dH).pushKey[3]    = (**oldH).pushKey[3];
  376.             (**dH).popKey[0]    = (**oldH).popKey[0];
  377.             (**dH).popKey[1]    = (**oldH).popKey[1];
  378.             (**dH).popKey[2]    = (**oldH).popKey[2];
  379.             (**dH).popKey[3]    = (**oldH).popKey[3];
  380.             (**dH).showIcon        = (**oldH).showIcon;
  381.             HNoPurge((Handle)dH);
  382.             saveSetting(dH);
  383.         }
  384.         ReleaseResource((Handle)oldH);
  385.     }
  386.     return(dH);
  387. }
  388.  
  389. initDataHandle setDefaultData(void)
  390. {
  391.     initDataHandle    dH;
  392.     
  393.     dH = (initDataHandle)NewHandleSys(sizeof(initData));
  394.     if(dH) {        
  395.         (**dH).dragOn        = defaultDragOn;
  396.         (**dH).noMarquee    = defaultNoMarquee;
  397.         (**dH).glueOn        = defaultGlueOn;
  398.         (**dH).growOn        = defaultGrowOn;    //
  399.         (**dH).pushOn        = defaultPushOn;
  400.         (**dH).popOn        = defaultPopOn;
  401.         (**dH).pushSound    = defaultPushSound;
  402.         (**dH).popSound        = defaultPopSound;
  403.         (**dH).dragKey[0]    = defaultDragKey0;
  404.         (**dH).dragKey[1]    = defaultDragKey1;
  405.         (**dH).dragKey[2]    = defaultDragKey2;
  406.         (**dH).dragKey[3]    = defaultDragKey3;
  407.         (**dH).glueKey[0]    = defaultGlueKey0;
  408.         (**dH).glueKey[1]    = defaultGlueKey1;
  409.         (**dH).glueKey[2]    = defaultGlueKey2;
  410.         (**dH).glueKey[3]    = defaultGlueKey3;
  411.         (**dH).pushKey[0]    = defaultPushKey0;
  412.         (**dH).pushKey[1]    = defaultPushKey1;
  413.         (**dH).pushKey[2]    = defaultPushKey2;
  414.         (**dH).pushKey[3]    = defaultPushKey3;
  415.         (**dH).popKey[0]    = defaultPopKey0;
  416.         (**dH).popKey[1]    = defaultPopKey1;
  417.         (**dH).popKey[2]    = defaultPopKey2;
  418.         (**dH).popKey[3]    = defaultPopKey3;
  419.         (**dH).showIcon        = defaultShowIcon;
  420.         HNoPurge((Handle)dH);
  421.     }
  422.     return(dH);
  423. }
  424.  
  425. OSErr openPrefsFile(prefsFileSpec *pfSpecP)
  426. {
  427.     OSErr    err;
  428.     short    refNum;
  429.     Str255    prefsFileName;
  430.     
  431.     GetIndString(prefsFileName, prefs_STRx_id, nameIndex);
  432.     err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder,
  433.                         &pfSpecP->vRefNum, &pfSpecP->DirID);
  434.     if(err == noErr) {
  435.         refNum = HOpenResFile(pfSpecP->vRefNum, pfSpecP->DirID,
  436.                                                     prefsFileName, fsRdWrPerm);    
  437.         if(refNum == -1)
  438.             return(ResError());
  439.         else {
  440.             pfSpecP->RsrcRefNum = refNum;
  441.             return(noErr);
  442.         }
  443.     }
  444.     return(err);
  445. }
  446.  
  447. //    Save -----
  448.  
  449. void saveSetting(initDataHandle dH)
  450. {
  451.     initDataHandle    tempH;
  452.     Handle            h;
  453.     
  454.     tempH = (initDataHandle)NewHandle(sizeof(initData));
  455.     if(tempH) {
  456.         **tempH = **dH;
  457.         h = Get1Resource(myDataType, gw420_DATA_id);
  458.         if(h)
  459.             RmveResource(h);
  460.         AddResource((Handle)tempH, myDataType, gw420_DATA_id, "\p");
  461.         ReleaseResource((Handle)tempH);
  462.     }
  463. }
  464.  
  465. OSErr createPrefsFile(void)
  466. {
  467.     short            savedRefNum;
  468.     OSErr            err;
  469.     FInfo            finderInfo;
  470.     prefsFileSpec    pfSpec;
  471.     Str255            prefsFileName;
  472.     
  473.     GetIndString(prefsFileName, prefs_STRx_id, nameIndex);
  474.     savedRefNum = CurResFile();
  475.     err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder,
  476.                         &pfSpec.vRefNum, &pfSpec.DirID);
  477.     if(err == noErr) {
  478.         HCreateResFile(pfSpec.vRefNum, pfSpec.DirID,
  479.                             prefsFileName);
  480.         finderInfo.fdType        = 'pref';
  481.         finderInfo.fdCreator    = myCreator;
  482.         finderInfo.fdFlags        = prefsFileFlag;
  483.         HSetFInfo(pfSpec.vRefNum, pfSpec.DirID, prefsFileName, &finderInfo);
  484.     }
  485.     UseResFile(savedRefNum);
  486.     return(err);
  487. }
  488.  
  489. //    Trap -----
  490.  
  491. pascal Boolean trackGoAway(WindowPtr wp, Point mp)
  492. {
  493.     Boolean        f;
  494.     long        oldA4;
  495.     
  496.     oldA4 = SetUpA4();
  497.     
  498.     if((**settingH).popOn && checkKeys(&(**settingH).popKey[0]))
  499.         f = customGoAway(wp, mp);
  500.     else
  501.         f = (*trackGoAwayProc)(wp, mp);
  502.     
  503.     RestoreA4(oldA4);
  504.     return(f);
  505. }
  506.  
  507. pascal void dragWindow(WindowPtr wp, Point mp, Rect *r)
  508. {
  509.     long    oldA4;
  510.     KeyMap    keyMap;
  511.     
  512.     oldA4 = SetUpA4();
  513.     
  514.     if(!settingH) {
  515.         (*dragWindowProc)(wp, mp, r);
  516.     }
  517.     else if((**settingH).noMarquee    && checkKeys(&(**settingH).dragKey[0])) {
  518.         directDrag(wp, mp, r);
  519.     }
  520.     else if((**settingH).glueOn        && checkKeys(&(**settingH).glueKey[0])) {
  521.         strongGlue(wp, mp, r);
  522.     }
  523.     else if((**settingH).pushOn        && checkKeys(&(**settingH).pushKey[0])) {
  524.         pushWindow(wp, mp, r);
  525.     }
  526.     else if((**settingH).popOn        && checkKeys(&(**settingH).popKey[0])) {
  527.         popWindow(wp, mp, r);
  528.     }
  529.     else if(!(**settingH).dragOn) {
  530.         (*dragWindowProc)(wp, mp, r);
  531.     }
  532.     else
  533.         customDrag(wp, mp, r);
  534.     
  535.     GetKeys(keyMap);
  536.     if(!BitTst(keyMap, commandKeyBit))
  537.         SelectWindow(wp);
  538.     
  539.     RestoreA4(oldA4);
  540. }
  541.  
  542. pascal long growWindow(WindowPtr wp, Point mp, Rect *r)
  543. {
  544.     long    oldA4, value;
  545.     
  546.     oldA4 = SetUpA4();
  547.     
  548.     if(!settingH) {
  549.         value = (*growWindowProc)(wp, mp, r);
  550.     }
  551.     else if(!(**settingH).growOn) {
  552.         value = (*growWindowProc)(wp, mp, r);
  553.     }
  554.     else
  555.         value = customGrow(wp, mp, r);
  556.     
  557.     RestoreA4(oldA4);
  558.     return(value);
  559. }
  560.  
  561. Boolean checkKeys(Boolean *key)
  562. {
  563.     KeyMap    keyMap;
  564.  
  565.     GetKeys(keyMap);
  566.     if(    (key[0] == BitTst(keyMap, controlKeyBit))    &&
  567.         (key[1] == BitTst(keyMap, shiftKeyBit))    &&
  568.         (key[2] == BitTst(keyMap, optionKeyBit))    &&
  569.         (key[3] == BitTst(keyMap, commandKeyBit))    )
  570.         return(true);
  571.     else
  572.         return(false);
  573. }
  574.  
  575. pascal void pushWindow(WindowPtr wp, Point mp, Rect *r)
  576. {
  577.     GrafPtr        savedPortP;
  578.     OSErr        err;
  579.     Point        pt;
  580.     
  581.     GetPort(&savedPortP);
  582.     SetPort(wp);
  583.     
  584.     pt.h = wp->portRect.left;
  585.     pt.v = wp->portRect.top;
  586.     LocalToGlobal(&pt);
  587.     if(PtInRect(pt, r)) {    
  588.         stdState.left    = pt.h;
  589.         stdState.top    = pt.v;
  590.         
  591.         SetPort(savedPortP);
  592.         
  593.         if((**settingH).pushSound) {
  594.             if(trapAvailable(_SndPlay)) {
  595.                 if(pushSndH)
  596.                     err = SndPlay(nil, pushSndH, false);
  597.                 else
  598.                     SysBeep(1);
  599.             }
  600.             else
  601.                 SysBeep(1);
  602.         }
  603.     }
  604.     else {
  605.         customDrag(wp, mp, r);
  606.     }    
  607. }
  608.  
  609. pascal void popWindow(WindowPtr wp, Point mp, Rect *r)
  610. {
  611.     OSErr            err;
  612.     
  613.     popFunc(wp, r);
  614.     if((**settingH).popSound) {
  615.         if(trapAvailable(_SndPlay)) {
  616.             if(popSndH)
  617.                 err = SndPlay(nil, popSndH, false);
  618.             else
  619.                 SysBeep(1);
  620.         }
  621.         else
  622.             SysBeep(1);
  623.     }
  624. }
  625.  
  626. pascal Boolean customGoAway(WindowPtr wp, Point mp)
  627. {
  628.     Boolean            f;
  629.     OSErr            err;
  630.     Rect            r;
  631.     
  632.     f = (*trackGoAwayProc)(wp, mp);
  633.     if(f) {
  634.         SetRect(&r, -32768, -32768, 32767, 32767);
  635.         popFunc(wp, &r);
  636.     }
  637.     if((**settingH).popSound) {
  638.         if(trapAvailable(_SndPlay)) {
  639.             if(popSndH)
  640.                 err = SndPlay(nil, popSndH, false);
  641.             else
  642.                 SysBeep(1);
  643.         }
  644.         else
  645.             SysBeep(1);
  646.     }
  647.     return(f);
  648. }
  649.  
  650. void popFunc(WindowPtr wp, Rect *r)
  651. {
  652.     GrafPtr            savedPortP;
  653.     RgnHandle        grH;
  654.     Rect            ristRect, titleRect;
  655.     Point            pt, globalPt;
  656.     
  657.     GetPort(&savedPortP);
  658.     SetPort(wp);
  659.     
  660.     globalPt.h = wp->portRect.left;
  661.     globalPt.v = wp->portRect.top;
  662.     LocalToGlobal(&globalPt);
  663.     
  664.     grH = LMGetGrayRgn();
  665.     ristRect = (**grH).rgnBBox;
  666.     InsetRect(&ristRect, 4, 4);
  667.     SectRect(&ristRect, r, &ristRect);
  668.     
  669.     if(!EmptyRect(&wp->portRect)) {
  670.         if(contRect.top - strucRect.top > contRect.left - strucRect.left) {
  671.             SetRect(&titleRect, strucRect.left, strucRect.top,
  672.                                         strucRect.right, contRect.top);
  673.         }
  674.         else {
  675.             SetRect(&titleRect, strucRect.left, strucRect.top,
  676.                                         contRect.left, strucRect.bottom);
  677.         }
  678.         if(titleRect.left > titleRect.right || titleRect.top > titleRect.bottom) {
  679.             titleRect = strucRect;
  680.         }
  681.     }
  682.     else {
  683.         titleRect = strucRect;
  684.     }
  685.     
  686.     pt.h = stdState.left;
  687.     pt.v = stdState.top;
  688.  
  689.     OffsetRect(&titleRect, stdState.left - globalPt.h,
  690.                                 stdState.top - globalPt.v);
  691.     
  692.     if(SectRect(&titleRect, &ristRect, &titleRect)) {
  693.         MoveWindow(wp, pt.h, pt.v, false);
  694.     }
  695.     SetPort(savedPortP);
  696. }
  697.  
  698. //    Drag -----
  699.  
  700. pascal void customDrag(WindowPtr wp, Point mp, Rect *r)
  701. {
  702.     GrafPtr        savedPortP;
  703.     GrafPort    myPort;
  704.     Point        oldPt, newPt, diff;
  705.     short        offset_h, offset_v;
  706.     WindowPeek    wpk;
  707.     Boolean        h_isChanged, v_isChanged;
  708.     Rect        wpkRect, ristRect;    //    Not restrict!
  709.     short        wLeft, wTop;
  710.     short        wWidth, wHeight;
  711.     short        gapLeft, gapTop, gapRight, gapBottom;
  712.     RgnHandle    grH;
  713.     
  714.     GetPort(&savedPortP);
  715.     SetPort(wp);
  716.     diff.h = wp->portRect.left;
  717.     diff.v = wp->portRect.top;
  718.     LocalToGlobal(&diff);
  719.     diff.h -= contRect.left;
  720.     diff.v -= contRect.top;
  721.     OpenPort(&myPort);
  722.     SetPort(&myPort);
  723.     
  724.     grH = LMGetGrayRgn();
  725.     CopyRgn(grH, myPort.visRgn);
  726.     myPort.portRect = (**grH).rgnBBox;
  727.     offset_h    = mp.h - contRect.left;
  728.     offset_v    = mp.v - contRect.top;
  729.     gapLeft        = contRect.left        - strucRect.left;
  730.     gapTop        = contRect.top        - strucRect.top;
  731.     gapRight    = strucRect.right    - contRect.right;
  732.     gapBottom    = strucRect.bottom    - contRect.bottom;
  733.     wWidth    = contRect.right    - contRect.left;
  734.     wHeight    = contRect.bottom    - contRect.top;
  735.     
  736.     PenSize(1, 1);
  737.     PenPat(&myQDGlobals.gray);
  738.     PenMode(patXor);
  739.     oldPt = mp;
  740.     wLeft    = oldPt.h - offset_h;
  741.     wTop    = oldPt.v - offset_v;
  742.     
  743.     ristRect = myPort.portRect;
  744.     InsetRect(&ristRect, 4, 4);
  745.     SectRect(&ristRect, r, &ristRect);
  746.     
  747.     frameRgn(((WindowPeek)wp)->strucRgn, wLeft - gapLeft, wTop - gapTop);
  748.     while(StillDown()) {
  749.         GetMouse(&newPt);
  750.         LocalToGlobal(&newPt);
  751.         if(PtInRect(newPt, &ristRect)) {
  752.             if(!EqualPt(newPt, oldPt)) {
  753.                 frameRgn(((WindowPeek)wp)->strucRgn, wLeft - gapLeft, wTop - gapTop);
  754.                 wLeft    = newPt.h - offset_h;
  755.                 wTop    = newPt.v - offset_v;
  756.                 h_isChanged = v_isChanged = false;
  757.                 wpk = (WindowPeek)FrontWindow();
  758.                 while(wpk)    {
  759.                     if(wpk != (WindowPeek)wp) {
  760.                         wpkRect = (**wpk->strucRgn).rgnBBox;
  761.                         if (!h_isChanged &&(abs(wpkRect.left - (wLeft - gapLeft)) <= 5)) {
  762.                             wLeft = wpkRect.left + gapLeft;
  763.                             h_isChanged = true;
  764.                         }
  765.                         if (!h_isChanged &&(abs(wpkRect.right - (wLeft - gapLeft)) <= 5)) {
  766.                             wLeft = wpkRect.right + gapLeft;
  767.                             h_isChanged = true;
  768.                         }
  769.                         if (!h_isChanged &&(abs(wpkRect.left - (wLeft + wWidth + gapRight)) <= 5)) {
  770.                             wLeft = wpkRect.left - wWidth - gapRight;
  771.                             h_isChanged = true;
  772.                         }
  773.                         if (!h_isChanged &&(abs(wpkRect.right - (wLeft + wWidth + gapRight)) <= 5)) {
  774.                             wLeft = wpkRect.right - wWidth - gapRight;
  775.                             h_isChanged = true;
  776.                         }
  777.                         if (!v_isChanged &&(abs(wpkRect.top - (wTop - gapTop)) <= 5)) {
  778.                             wTop = wpkRect.top + gapTop;
  779.                             v_isChanged = true;
  780.                         }
  781.                         if (!v_isChanged &&(abs(wpkRect.bottom - (wTop - gapTop)) <= 5)) {
  782.                             wTop = wpkRect.bottom + gapTop;
  783.                             v_isChanged = true;
  784.                         }
  785.                         if (!v_isChanged &&(abs(wpkRect.top - (wTop + wHeight + gapBottom)) <= 5)) {
  786.                             wTop = wpkRect.top - wHeight - gapBottom;
  787.                             v_isChanged = true;
  788.                         }
  789.                         if (!v_isChanged &&(abs(wpkRect.bottom - (wTop + wHeight + gapBottom)) <= 5)) {
  790.                             wTop = wpkRect.bottom - wHeight - gapBottom;
  791.                             v_isChanged = true;
  792.                         }
  793.                         wpk = wpk->nextWindow;
  794.                         if(h_isChanged && v_isChanged)    wpk = (WindowPeek)0;
  795.                     } else {
  796.                         wpk = wpk->nextWindow;
  797.                     }
  798.                 }
  799.                 frameRgn(((WindowPeek)wp)->strucRgn, wLeft - gapLeft, wTop - gapTop);
  800.                 oldPt = newPt;
  801.             }
  802.         }
  803.     }
  804.     frameRgn(((WindowPeek)wp)->strucRgn, wLeft - gapLeft, wTop - gapTop);
  805.     MoveWindow(wp, wLeft + diff.h, wTop + diff.v, false);
  806.     SetPort(savedPortP);
  807.     ClosePort(&myPort);
  808. }
  809.  
  810. pascal void strongGlue(WindowPtr wp, Point mp, Rect *r)
  811. {
  812.     GrafPtr        savedPortP;
  813.     GrafPort    myPort;
  814.     Point        oldPt, newPt, startPt, wkPt;
  815.     short        offset_h, offset_v;
  816.     WindowPeek    wpk;
  817.     Boolean        h_isChanged, v_isChanged;
  818.     Boolean        isSelected;
  819.     Rect        wpkRect, ristRect, marqueeRect;
  820.     short        wLeft, wTop;
  821.     short        wWidth, wHeight;
  822.     short        gapLeft, gapTop, gapRight, gapBottom;
  823.     short        wNum, ct;
  824.     RgnHandle    grH, invisRgnH, strucVisRgnH, clipRgnH;
  825.     CursHandle    curs;
  826.     WindowPeek    wList[MaxWindowList];     
  827.  
  828.     GetPort(&savedPortP);
  829.     OpenPort(&myPort);
  830.     SetPort(&myPort);
  831.  
  832.     grH = LMGetGrayRgn();
  833.     CopyRgn(grH, myPort.visRgn);
  834.     myPort.portRect = (**grH).rgnBBox;
  835.     curs = GetCursor(crossCursor);
  836.     SetCursor(*curs);
  837.     
  838.     gapLeft        = contRect.left        - strucRect.left;
  839.     gapTop        = contRect.top        - strucRect.top;
  840.     gapRight    = strucRect.right    - contRect.right;
  841.     gapBottom    = strucRect.bottom    - contRect.bottom;
  842.     wWidth    = contRect.right    - contRect.left;
  843.     wHeight    = contRect.bottom    - contRect.top;
  844.     
  845.     PenSize(1, 1);
  846.     PenPat(&myQDGlobals.gray);
  847.     PenMode(patXor);
  848.     oldPt = mp;
  849.     
  850.     ristRect = myPort.portRect;
  851.     InsetRect(&ristRect, 4, 4);
  852.     SectRect(&ristRect, r, &ristRect);
  853.     
  854.     invisRgnH = NewRgn();
  855.     strucVisRgnH = NewRgn();
  856.     clipRgnH = NewRgn();
  857.     
  858.     SetRect(&marqueeRect, oldPt.h, oldPt.v, oldPt.h, oldPt.v);
  859.     
  860.     frameRect(&marqueeRect);
  861.     wNum = 0;
  862.     while(StillDown()) {
  863.         GetMouse(&newPt);
  864.         LocalToGlobal(&newPt);
  865.         if(!EqualPt(newPt, oldPt)) {
  866.             frameRect(&marqueeRect);
  867.             marqueeRect.right    = newPt.h;
  868.             marqueeRect.bottom    = newPt.v;
  869.             frameRect(&marqueeRect);
  870.             wpk = (WindowPeek)FrontWindow();
  871.             SetEmptyRgn(invisRgnH);
  872.             while(wpk)    {
  873.                 wpkRect = (**(wpk->strucRgn)).rgnBBox;
  874.                 DiffRgn(wpk->strucRgn, invisRgnH, strucVisRgnH);
  875.                 isSelected = false;
  876.                 for(ct = 0; ct <= wNum - 1; ct++) {
  877.                     if(wpk == wList[ct]) {
  878.                         isSelected = true;
  879.                     }
  880.                 }
  881.                 if(!isSelected) {
  882.                     if(!EqualRect(&myPort.portRect, &wpk->port.portRect) &&
  883.                         !EmptyRgn(strucVisRgnH) && 
  884.                             rectInRgn(&marqueeRect, strucVisRgnH)) {
  885.                         PenPat(&myQDGlobals.black);
  886.                         paintRgn(strucVisRgnH);
  887.                         UnionRgn(clipRgnH, strucVisRgnH, clipRgnH);
  888.                         PenPat(&myQDGlobals.gray);
  889.                         wList[wNum++] = wpk;
  890.                         if(wNum >= MaxWindowList)    wNum = MaxWindowList - 1;
  891.                     }
  892.                 }
  893.                 else {
  894.                     if(EmptyRgn(strucVisRgnH) ||
  895.                             !rectInRgn(&marqueeRect, strucVisRgnH)) {
  896.                         PenPat(&myQDGlobals.black);
  897.                         paintRgn(strucVisRgnH);
  898.                         DiffRgn(clipRgnH, strucVisRgnH, clipRgnH);
  899.                         PenPat(&myQDGlobals.gray);
  900.                         ct = 0;
  901.                         while(wList[ct] != wpk)    ct++;
  902.                         for(--wNum; ct <= wNum - 1; ct++)
  903.                             wList[ct] = wList[ct + 1];
  904.                     }
  905.                 }
  906.                 UnionRgn(invisRgnH, wpk->strucRgn, invisRgnH);
  907.                 SetEmptyRgn(strucVisRgnH);
  908.                 wpk = wpk->nextWindow;
  909.             }
  910.         }
  911.         oldPt = newPt;
  912.     }
  913.     frameRect(&marqueeRect);
  914.     PenPat(&myQDGlobals.black);
  915.     paintRgn(clipRgnH);
  916.     PenPat(&myQDGlobals.gray);
  917.     
  918.     DisposeRgn(strucVisRgnH);
  919.     DisposeRgn(invisRgnH);
  920.     DisposeRgn(clipRgnH);
  921.     
  922. // --------------------------------
  923.     
  924.     if(handCursorH)
  925.         SetCursor(*handCursorH);
  926.     for(ct = 0; ct <= wNum -1; ct++) {
  927.         frameRgn(wList[ct]->strucRgn, (**(wList[ct]->strucRgn)).rgnBBox.left,
  928.                                         (**(wList[ct]->strucRgn)).rgnBBox.top);
  929.     }
  930.     while(!Button()) {
  931.     }
  932.     FlushEvents(mDownMask + mUpMask, 0);
  933.     if(gripCursorH)
  934.         SetCursor(*gripCursorH);
  935.     GetMouse(&oldPt);
  936.     LocalToGlobal(&oldPt);
  937.     startPt = oldPt;
  938.     offset_h = startPt.h - contRect.left;
  939.     offset_v = startPt.v - contRect.top;
  940.     wLeft    = oldPt.h - offset_h;
  941.     wTop    = oldPt.v - offset_v;
  942.     
  943.     while(StillDown()) {
  944.         GetMouse(&newPt);
  945.         LocalToGlobal(&newPt);
  946.         if(PtInRect(newPt, &ristRect)) {
  947.             if(!EqualPt(newPt, oldPt)) {
  948.                 for(ct = 0; ct <= wNum -1; ct++) {
  949.                     frameRgn(wList[ct]->strucRgn,
  950.                         (**(wList[ct]->strucRgn)).rgnBBox.left + wLeft - contRect.left,
  951.                             (**(wList[ct]->strucRgn)).rgnBBox.top + wTop - contRect.top);
  952.                 }
  953.                 wLeft    = newPt.h - offset_h;
  954.                 wTop    = newPt.v - offset_v;
  955.                 h_isChanged = v_isChanged = false;
  956.                 wpk = (WindowPeek)FrontWindow();
  957.                 while(wpk)    {
  958.                     if(wpk != (WindowPeek)wp) {
  959.                         wpkRect = (**wpk->strucRgn).rgnBBox;
  960.                         if (!h_isChanged &&(abs(wpkRect.left - (wLeft - gapLeft)) <= 5)) {
  961.                             wLeft = wpkRect.left + gapLeft;
  962.                             h_isChanged = true;
  963.                         }
  964.                         if (!h_isChanged &&(abs(wpkRect.right - (wLeft - gapLeft)) <= 5)) {
  965.                             wLeft = wpkRect.right + gapLeft;
  966.                             h_isChanged = true;
  967.                         }
  968.                         if (!h_isChanged &&(abs(wpkRect.left - (wLeft + wWidth + gapRight)) <= 5)) {
  969.                             wLeft = wpkRect.left - wWidth - gapRight;
  970.                             h_isChanged = true;
  971.                         }
  972.                         if (!h_isChanged &&(abs(wpkRect.right - (wLeft + wWidth + gapRight)) <= 5)) {
  973.                             wLeft = wpkRect.right - wWidth - gapRight;
  974.                             h_isChanged = true;
  975.                         }
  976.                         if (!v_isChanged &&(abs(wpkRect.top - (wTop - gapTop)) <= 5)) {
  977.                             wTop = wpkRect.top + gapTop;
  978.                             v_isChanged = true;
  979.                         }
  980.                         if (!v_isChanged &&(abs(wpkRect.bottom - (wTop - gapTop)) <= 5)) {
  981.                             wTop = wpkRect.bottom + gapTop;
  982.                             v_isChanged = true;
  983.                         }
  984.                         if (!v_isChanged &&(abs(wpkRect.top - (wTop + wHeight + gapBottom)) <= 5)) {
  985.                             wTop = wpkRect.top - wHeight - gapBottom;
  986.                             v_isChanged = true;
  987.                         }
  988.                         if (!v_isChanged &&(abs(wpkRect.bottom - (wTop + wHeight + gapBottom)) <= 5)) {
  989.                             wTop = wpkRect.bottom - wHeight - gapBottom;
  990.                             v_isChanged = true;
  991.                         }
  992.                         wpk = wpk->nextWindow;
  993.                         if(h_isChanged && v_isChanged)    wpk = (WindowPeek)0;
  994.                     } else {
  995.                         wpk = wpk->nextWindow;
  996.                     }
  997.                 }
  998.                 for(ct = 0; ct <= wNum -1; ct++) {
  999.                     frameRgn(wList[ct]->strucRgn,
  1000.                         (**(wList[ct]->strucRgn)).rgnBBox.left + wLeft - contRect.left,
  1001.                             (**(wList[ct]->strucRgn)).rgnBBox.top + wTop - contRect.top);
  1002.                 }
  1003.                 oldPt = newPt;
  1004.             }
  1005.         }
  1006.     }
  1007.     for(ct = 0; ct <= wNum -1; ct++) {
  1008.         frameRgn(wList[ct]->strucRgn,
  1009.             (**(wList[ct]->strucRgn)).rgnBBox.left + wLeft - contRect.left,
  1010.                 (**(wList[ct]->strucRgn)).rgnBBox.top + wTop - contRect.top);
  1011.     }
  1012.     offset_h = wLeft - contRect.left;
  1013.     offset_v = wTop - contRect.top;
  1014.     for(ct = 0; ct <= wNum -1; ct++) {
  1015.         if(titleInRect(wList[ct], offset_h, offset_v, &ristRect)) {
  1016.             wkPt.h = ((WindowPtr)wList[ct])->portRect.left;
  1017.             wkPt.v = ((WindowPtr)wList[ct])->portRect.top;
  1018.             getGlobal(wList[ct], &wkPt);
  1019.             MoveWindow((WindowPtr)wList[ct], wkPt.h + offset_h,
  1020.                                                 wkPt.v + offset_v, false);
  1021.         }
  1022.     }
  1023.  
  1024.     if(handCursorH)
  1025.         SetCursor(&myQDGlobals.arrow);
  1026.     
  1027.     SetPort(savedPortP);
  1028.     ClosePort(&myPort);
  1029. }
  1030.  
  1031. pascal void directDrag(WindowPtr wp, Point mp, Rect *r)
  1032. {
  1033.     GrafPtr        savedPortP;
  1034.     Point        oldPt, newPt, diff;
  1035.     short        offset_h, offset_v;
  1036.     WindowPeek    wpk;
  1037.     Boolean        h_isChanged, v_isChanged;
  1038.     Rect        wpkRect, ristRect;
  1039.     short        wLeft, wTop;
  1040.     short        wWidth, wHeight;
  1041.     short        gapLeft, gapTop, gapRight, gapBottom;
  1042.     RgnHandle    grH;
  1043.     
  1044.     GetPort(&savedPortP);
  1045.     SetPort(wp);
  1046.     diff.h = wp->portRect.left;
  1047.     diff.v = wp->portRect.top;
  1048.     LocalToGlobal(&diff);
  1049.     diff.h -= contRect.left;
  1050.     diff.v -= contRect.top;
  1051.     
  1052.     offset_h    = mp.h - contRect.left;
  1053.     offset_v    = mp.v - contRect.top;
  1054.     gapLeft        = contRect.left        - strucRect.left;
  1055.     gapTop        = contRect.top        - strucRect.top;
  1056.     gapRight    = strucRect.right    - contRect.right;
  1057.     gapBottom    = strucRect.bottom    - contRect.bottom;
  1058.     wWidth    = contRect.right    - contRect.left;
  1059.     wHeight    = contRect.bottom    - contRect.top;
  1060.     
  1061.     oldPt = mp;
  1062.     
  1063.     grH = LMGetGrayRgn();
  1064.     ristRect = (**grH).rgnBBox;
  1065.     InsetRect(&ristRect, 4, 4);
  1066.     SectRect(&ristRect, r, &ristRect);
  1067.     
  1068.     while(StillDown()) {
  1069.         GetMouse(&newPt);
  1070.         LocalToGlobal(&newPt);
  1071.         if(PtInRect(newPt, &ristRect)) {
  1072.             if(!EqualPt(newPt, oldPt)) {
  1073.                 wLeft = newPt.h - offset_h;
  1074.                 wTop  = newPt.v - offset_v;
  1075.                 h_isChanged = v_isChanged = false;
  1076.  
  1077.                 wpk = (WindowPeek)FrontWindow();
  1078.                 while(wpk)    {
  1079.                     if(wpk != (WindowPeek)wp) {
  1080.                         wpkRect = (**wpk->strucRgn).rgnBBox;
  1081.                         if (!h_isChanged &&(abs(wpkRect.left - (wLeft - gapLeft)) <= 5)) {
  1082.                             wLeft = wpkRect.left + gapLeft;
  1083.                             h_isChanged = true;
  1084.                         }
  1085.                         if (!h_isChanged &&(abs(wpkRect.right - (wLeft - gapLeft)) <= 5)) {
  1086.                             wLeft = wpkRect.right + gapLeft;
  1087.                             h_isChanged = true;
  1088.                         }
  1089.                         if (!h_isChanged &&(abs(wpkRect.left - (wLeft + wWidth + gapRight)) <= 5)) {
  1090.                             wLeft = wpkRect.left - wWidth - gapRight;
  1091.                             h_isChanged = true;
  1092.                         }
  1093.                         if (!h_isChanged &&(abs(wpkRect.right - (wLeft + wWidth + gapRight)) <= 5)) {
  1094.                             wLeft = wpkRect.right - wWidth - gapRight;
  1095.                             h_isChanged = true;
  1096.                         }
  1097.                         if (!v_isChanged &&(abs(wpkRect.top - (wTop - gapTop)) <= 5)) {
  1098.                             wTop = wpkRect.top + gapTop;
  1099.                             v_isChanged = true;
  1100.                         }
  1101.                         if (!v_isChanged &&(abs(wpkRect.bottom - (wTop - gapTop)) <= 5)) {
  1102.                             wTop = wpkRect.bottom + gapTop;
  1103.                             v_isChanged = true;
  1104.                         }
  1105.                         if (!v_isChanged &&(abs(wpkRect.top - (wTop + wHeight + gapBottom)) <= 5)) {
  1106.                             wTop = wpkRect.top - wHeight - gapBottom;
  1107.                             v_isChanged = true;
  1108.                         }
  1109.                         if (!v_isChanged &&(abs(wpkRect.bottom - (wTop + wHeight + gapBottom)) <= 5)) {
  1110.                             wTop = wpkRect.bottom - wHeight - gapBottom;
  1111.                             v_isChanged = true;
  1112.                         }
  1113.                         wpk = wpk->nextWindow;
  1114.                         if(h_isChanged && v_isChanged)    wpk = (WindowPeek)0;
  1115.                     } else {
  1116.                         wpk = wpk->nextWindow;
  1117.                     }
  1118.                 }
  1119.             
  1120.                 MoveWindow(wp, wLeft + diff.h, wTop + diff.v, false);
  1121.                 oldPt = newPt;
  1122.             }
  1123.         }
  1124.     }
  1125.     SetPort(savedPortP);
  1126. }
  1127.  
  1128. pascal long customGrow(WindowPtr wp, Point mp, Rect *r)
  1129. {
  1130.     GrafPtr        savedPortP;
  1131.     GrafPort    myPort;
  1132.     Point        oldPt, newPt, pt;
  1133.     short        offset_h, offset_v;
  1134.     WindowPeek    wpk;
  1135.     Boolean        h_isChanged, v_isChanged;
  1136.     Rect        wpkRect, ristRect;
  1137.     short        wRight, wBottom;
  1138.     short        wWidth, wHeight;
  1139.     short        gapLeft, gapTop, gapRight, gapBottom;
  1140.     long        value = 0, size;
  1141.     
  1142.     GetPort(&savedPortP);
  1143.     OpenPort(&myPort);
  1144.     SetPort(&myPort);
  1145.     
  1146.     offset_h    = contRect.right    - mp.h;
  1147.     offset_v    = contRect.bottom    - mp.v;
  1148.     gapLeft        = contRect.left        - strucRect.left;
  1149.     gapTop        = contRect.top        - strucRect.top;
  1150.     gapRight    = strucRect.right    - contRect.right;
  1151.     gapBottom    = strucRect.bottom    - contRect.bottom;
  1152.     wWidth    = contRect.right    - contRect.left;
  1153.     wHeight    = contRect.bottom    - contRect.top;
  1154.     
  1155.     ristRect = *r;
  1156.     if(ristRect.right    > myPort.portRect.right)
  1157.                 ristRect.right    = myPort.portRect.right;
  1158.     if(ristRect.bottom    > myPort.portRect.bottom)
  1159.                 ristRect.bottom    = myPort.portRect.bottom;
  1160.     OffsetRect(&ristRect, contRect.left, contRect.top);
  1161.     
  1162.     PenSize(1, 1);
  1163.     PenPat(&myQDGlobals.gray);
  1164.     PenMode(patXor);
  1165.     oldPt = mp;
  1166.     wRight    = oldPt.h + offset_h;
  1167.     wBottom    = oldPt.v + offset_v;
  1168.     
  1169.     drawMarquee(((WindowPeek)wp)->strucRgn, wRight, wBottom, gapTop);
  1170.     while(StillDown()) {
  1171.         GetMouse(&newPt);
  1172.         LocalToGlobal(&newPt);
  1173.         pt = newPt;
  1174.         pt.h += offset_h;
  1175.         pt.v += offset_v;
  1176.         if(!PtInRect(pt, &ristRect)) {
  1177.             size = PinRect(&ristRect, pt);
  1178.             if(pt.v != HiWord(size))
  1179.                 newPt.v = HiWord(size) - offset_v;
  1180.             if(pt.h != LoWord(size))
  1181.                 newPt.h = LoWord(size) - offset_h;
  1182.         }
  1183.         if(!EqualPt(newPt, oldPt)) {
  1184.             drawMarquee(((WindowPeek)wp)->strucRgn, wRight, wBottom, gapTop);
  1185.             wRight    = newPt.h + offset_h;
  1186.             wBottom    = newPt.v + offset_v;
  1187.             h_isChanged = v_isChanged = false;
  1188.             wpk = (WindowPeek)FrontWindow();
  1189.             while(wpk)    {
  1190.                 if(wpk != (WindowPeek)wp) {
  1191.                     wpkRect = (**wpk->strucRgn).rgnBBox;
  1192.                     if (!h_isChanged &&(abs(wpkRect.left - (wRight + gapRight)) <= 5)) {
  1193.                         wRight = wpkRect.left - gapRight;
  1194.                         h_isChanged = true;
  1195.                     }
  1196.                     if (!h_isChanged &&(abs(wpkRect.right - (wRight + gapRight)) <= 5)) {
  1197.                         wRight = wpkRect.right - gapRight;
  1198.                         h_isChanged = true;
  1199.                     }
  1200.                     
  1201.                     if (!v_isChanged &&(abs(wpkRect.top - (wBottom + gapBottom)) <= 5)) {
  1202.                         wBottom = wpkRect.top - gapBottom;
  1203.                         v_isChanged = true;
  1204.                     }
  1205.                     if (!v_isChanged &&(abs(wpkRect.bottom - (wBottom + gapBottom)) <= 5)) {
  1206.                         wBottom = wpkRect.bottom - gapBottom;
  1207.                         v_isChanged = true;
  1208.                     }
  1209.                     
  1210.                     wpk = wpk->nextWindow;
  1211.                     if(h_isChanged && v_isChanged)    wpk = (WindowPeek)0;
  1212.                 } else {
  1213.                     wpk = wpk->nextWindow;
  1214.                 }
  1215.             }
  1216.         
  1217.             drawMarquee(((WindowPeek)wp)->strucRgn, wRight, wBottom, gapTop);
  1218.             oldPt = newPt;
  1219.         }
  1220.     }
  1221.     drawMarquee(((WindowPeek)wp)->strucRgn, wRight, wBottom, gapTop);
  1222.     SetPort(savedPortP);
  1223.     ClosePort(&myPort);
  1224.     if((mp.h != oldPt.h) || (mp.v != oldPt.v)) {
  1225.         value = wBottom - contRect.top;
  1226.         value <<= 16;
  1227.         value += wRight - contRect.left;
  1228.     }
  1229.     return(value);
  1230. }
  1231.  
  1232. void drawMarquee(RgnHandle rh, short globalRight, short globalBottom, short gapTop)
  1233. {
  1234.     RgnHandle    localRgnH;
  1235.     Point        globalPt, localPt;
  1236.     Rect        marqueeRect, localRect;
  1237.     
  1238.     localRgnH = NewRgn();
  1239.     CopyRgn(rh, localRgnH);
  1240.     globalPt.h = (**localRgnH).rgnBBox.right;
  1241.     globalPt.v = (**localRgnH).rgnBBox.bottom;
  1242.     localPt = globalPt;
  1243.     
  1244.     GlobalToLocal(&localPt);
  1245.     OffsetRgn(localRgnH, globalPt.h - localPt.h, globalPt.v - localPt.v);
  1246.     
  1247.     SetRect(&localRect, (**localRgnH).rgnBBox.left, (**localRgnH).rgnBBox.top,
  1248.                 (**localRgnH).rgnBBox.right, (**localRgnH).rgnBBox.bottom);
  1249.     
  1250.     SetRect(&marqueeRect, localRect.left, localRect.top,
  1251.                 localRect.right + (globalRight - globalPt.h) + 1,
  1252.                 localRect.bottom + (globalBottom - globalPt.v) + 1);
  1253.     FrameRect(&marqueeRect);
  1254.     MoveTo(marqueeRect.left,    marqueeRect.top + gapTop - 1);
  1255.     LineTo(marqueeRect.right,    marqueeRect.top + gapTop - 1);
  1256.     MoveTo(marqueeRect.left,    marqueeRect.bottom - 16);
  1257.     LineTo(marqueeRect.right,    marqueeRect.bottom - 16);
  1258.     MoveTo(marqueeRect.right - 16, marqueeRect.top + gapTop);
  1259.     LineTo(marqueeRect.right - 16, marqueeRect.bottom);
  1260.     
  1261.     DisposeRgn(localRgnH);
  1262. }
  1263.  
  1264. void frameRgn(RgnHandle rh, short globalLeft, short globalTop)
  1265. {
  1266.     RgnHandle    localRgnH;
  1267.     Point        localPt, globalPt;
  1268.     
  1269.     localRgnH = NewRgn();
  1270.     CopyRgn(rh, localRgnH);
  1271.     globalPt.h = (**localRgnH).rgnBBox.left;
  1272.     globalPt.v = (**localRgnH).rgnBBox.top;
  1273.     localPt = globalPt;
  1274.     
  1275.     GlobalToLocal(&localPt);
  1276.     OffsetRgn(localRgnH, (globalLeft - globalPt.h) + (localPt.h - globalPt.h),
  1277.                         (globalTop - globalPt.v) + (localPt.v- globalPt.v));
  1278.     
  1279.     FrameRgn(localRgnH);
  1280.     DisposeRgn(localRgnH);
  1281. }
  1282.  
  1283. void frameRect(Rect *rect)
  1284. {
  1285.     short    wk;
  1286.     Rect    r = *rect;
  1287.     Point    localPt, globalPt;
  1288.     
  1289.     globalPt.h = r.left;
  1290.     globalPt.v = r.top;
  1291.     localPt = globalPt;
  1292.     GlobalToLocal(&localPt);
  1293.     
  1294.     if(r.left > r.right) {
  1295.         wk = r.right;
  1296.         r.right = r.left;
  1297.         r.left = wk;
  1298.     }
  1299.     else {
  1300.         r.right++;
  1301.     }
  1302.     
  1303.     if(r.top > r.bottom) {
  1304.         wk = r.bottom;
  1305.         r.bottom = r.top;
  1306.         r.top = wk;
  1307.     }
  1308.     else {
  1309.         r.bottom++;
  1310.     }
  1311.     
  1312.     OffsetRect(&r, localPt.h - globalPt.h, localPt.v - globalPt.v);
  1313.     FrameRect(&r);
  1314. }
  1315.  
  1316. Boolean rectInRgn(Rect *rect, RgnHandle vRgn)
  1317. {
  1318.     short    wk;
  1319.     Rect    mRect = *rect;
  1320.  
  1321.     if(mRect.left > mRect.right) {
  1322.         wk = mRect.right;
  1323.         mRect.right = mRect.left;
  1324.         mRect.left = wk;
  1325.     }
  1326.     else    mRect.right++;
  1327.     
  1328.     if(mRect.top > mRect.bottom) {
  1329.         wk = mRect.bottom;
  1330.         mRect.bottom = mRect.top;
  1331.         mRect.top = wk;
  1332.     }
  1333.     else    mRect.bottom++;
  1334.     
  1335.     return(RectInRgn(&mRect, vRgn));
  1336. }
  1337.  
  1338. void paintRgn(RgnHandle strucVisRgnH)
  1339. {
  1340.     Point        localPt, globalPt;
  1341.     RgnHandle    localVisRgnH;
  1342.     
  1343.     globalPt.h = (**strucVisRgnH).rgnBBox.left;
  1344.     globalPt.v = (**strucVisRgnH).rgnBBox.top;
  1345.     localPt = globalPt;
  1346.     GlobalToLocal(&localPt);
  1347.     
  1348.     localVisRgnH = NewRgn();
  1349.     CopyRgn(strucVisRgnH, localVisRgnH);
  1350.     OffsetRgn(localVisRgnH, localPt.h - globalPt.h, localPt.v - globalPt.v);
  1351.     
  1352.     PaintRgn(localVisRgnH);
  1353.     
  1354.     DisposeRgn(localVisRgnH);
  1355. }
  1356.  
  1357. Boolean titleInRect(WindowPeek wPeek, short h, short v, Rect *r)
  1358. {
  1359.     WindowPtr    wp;
  1360.     Rect        titleRect, dummy;
  1361.  
  1362.     wp = (WindowPtr)wPeek;
  1363.     if(!EmptyRect(&wp->portRect)) {
  1364.         if(contRect.top - strucRect.top > contRect.left - strucRect.left) {
  1365.             SetRect(&titleRect, strucRect.left, strucRect.top,
  1366.                                         strucRect.right, contRect.top);
  1367.         }
  1368.         else {
  1369.             SetRect(&titleRect, strucRect.left, strucRect.top,
  1370.                                         contRect.left, strucRect.bottom);
  1371.         }
  1372.         if(titleRect.left > titleRect.right || titleRect.top > titleRect.bottom)
  1373.             titleRect = strucRect;
  1374.     }
  1375.     else {
  1376.         titleRect = strucRect;
  1377.     }
  1378.     OffsetRect(&titleRect, h, v);
  1379.     return(SectRect(&titleRect, r, &dummy));
  1380. }
  1381.  
  1382. void getGlobal(WindowPeek wPeek, Point *pt)
  1383. {
  1384.     GrafPtr        savedPortP;
  1385.     
  1386.     GetPort(&savedPortP);
  1387.     SetPort((WindowPtr)wPeek);
  1388.     
  1389.     LocalToGlobal(pt);
  1390.     
  1391.     SetPort(savedPortP);
  1392. }
  1393.