quickdraw.c

Go to the documentation of this file.
00001 
00002 /*  $Id: quickdraw.c 1254 2006-04-12 20:27:14Z sethdill $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028  
00029 /*
00030 quickdraw.c -- code which builds on top of basic quickdraw operations.
00031 */
00032 
00033 #include "frontier.h"
00034 #include "standard.h"
00035 
00036 #ifdef MACVERSION
00037     #include "mac.h"
00038 #endif
00039 
00040 #include "font.h"
00041 #include "memory.h"
00042 #include "ops.h"
00043 #include "strings.h"
00044 #include "quickdraw.h"
00045 #include "frontierwindows.h"
00046 #include "shell.h"
00047 #include "byteorder.h"  /* 2006-04-08 aradke: endianness conversion macros */
00048 
00049 
00050 #ifdef WIN95VERSION
00051     #include "FrontierWinMain.h"  // 2006-03-28 SMD, for getstatusbarheight()
00052     HWND getcurrentwindow();
00053     HBRUSH getcurrentbrush();
00054     extern HINSTANCE hInst;
00055     short gPenPositionX;
00056     short gPenPositionY;
00057 #endif
00058 
00059 #ifdef MACVERSION
00060     #define stockgray gray
00061     #define stockblack black
00062     #define getstockpattern(x) qd.x
00063 #endif
00064 
00065 #ifdef WIN95VERSION
00066     #define stockgray GRAY_BRUSH
00067     #define stockblack BLACK_BRUSH
00068     #define getstockpattern(x) GetStockObject(x)
00069     #define WINRGB(rgb) RGB((rgb).red >> 8,(rgb).green >> 8, (rgb).blue >> 8)
00070 #endif
00071 
00072 RGBColor whitecolor = {65535, 65535, 65535};
00073 
00074 RGBColor blackcolor = {0, 0, 0};
00075 
00076 RGBColor greencolor = {0, 32767, 0};
00077 
00078 RGBColor lightbluecolor = {52428, 52428, 65535};
00079 
00080 RGBColor darkbluecolor = {0, 0, 32767};
00081 
00082 RGBColor darkgraycolor = {10922, 10922, 10922};
00083 
00084 RGBColor graycolor = {32767, 32767, 32767};
00085 
00086 RGBColor mediumgraycolor = {52428, 52428, 52428};
00087 
00088 RGBColor lightgraycolor = {61166, 61166, 61166};
00089 
00090 RGBColor lightyellowcolor = {65535, 65535, 52428};
00091 
00092 RGBColor lightgreencolor = {52428, 65535, 52428};
00093 
00094 RGBColor lightpurplecolor = {65535, 52428, 65535};
00095 
00096 RGBColor darkpurplecolor = {16384, 0, 16384};
00097 
00098 RGBColor lightredcolor = {65535, 52428, 52428};
00099 
00100 RGBColor darkredcolor = {32767, 0, 0};
00101 
00102 RGBColor darkgreencolor = {0, 32767, 0};
00103 
00104 
00105 #define qdfillrect(r, p) FillRect (r, p)
00106 
00107 #ifdef fldebug
00108 
00109     #define checkdepth(top, maxtop) maxtop = (top > maxtop? top : maxtop)
00110     
00111     static short maxpen = 0, maxport = 0, maxclip = 0, maxstyle = 0;
00112 
00113 #else
00114 
00115     #define checkdepth(top, maxtop)
00116 
00117 #endif
00118 
00119 
00120 typedef struct tystylerecord  {
00121     
00122     short fnum, fsize, fstyle;
00123     } tystylerecord;
00124 
00125 
00126 #define ctports 20 /*we can remember ports up to 5 levels deep*/
00127 #define ctclip 20 /*we can remember clips up to 5 levels deep*/
00128 #define ctpens 4 /*we can remember pens up to 5 levels deep*/
00129 #define ctstyle 5 /*we can remember font/size/styles up to 5 levels deep*/
00130 #define ctforecolors 5
00131 #define ctbackcolors 5
00132 
00133 static short topport = 0;
00134 static short topclip = 0;
00135 static short toppen = 0;
00136 static short topstyle = 0;
00137 static short topforecolor = 0;
00138 static short topbackcolor = 0;
00139 
00140 static CGrafPtr portstack [ctports];
00141 static hdlregion clipstack [ctclip];
00142 static tystylerecord stylestack [ctstyle];
00143 
00144 #ifdef MACVERSION
00145     static PenState penstack [ctpens];
00146     static RGBColor forecolorstack [ctforecolors];
00147     static RGBColor backcolorstack [ctbackcolors];
00148 #endif
00149 
00150 #ifdef WIN95VERSION
00151     static HPEN penstack[ctpens];
00152     static COLORREF forecolor;
00153     static COLORREF backcolor = (COLORREF) (COLOR_BTNFACE + 1); //should agree with class back brush in FrontierWinMain
00154     static COLORREF forecolorstack [ctforecolors];
00155     static COLORREF backcolorstack [ctbackcolors];
00156 #endif
00157 
00158 
00159 static hdlregion scratchrgn;
00160 
00161 #ifdef MACVERSION
00162     static CGrafPtr scratchport;
00163     //Code change by Timothy Paustian Friday, May 5, 2000 9:50:05 PM
00164     //Changed to Opaque call for Carbon
00165     //I had to change this because carbon will not allow
00166     //GrafPorts (revealing the structure) you have to use a 
00167     //CGrafPtr. This may be deadly. I will test this.
00168     #define inscratchport() (getcurrentDC() == scratchport)
00169 
00170 #endif
00171 
00172 #ifdef WIN95VERSION
00173     static HDC scratchport;
00174     HWND currentport;
00175     HDC currentportDC;
00176     static short winportpushed = 0;
00177     HBRUSH currentwindowbrush;
00178     static BOOL winclipstack [ctclip]; // return values from GetClipRgn
00179     //Code change by Timothy Paustian Friday, May 5, 2000 9:50:05 PM
00180     //Changed to Opaque call for Carbon
00181     //I had to change this because carbon will not allow
00182     //GrafPorts (revealing the structure) you have to use a 
00183     //GrafPtr. I don't think I did anything here.
00184     #define inscratchport() (getcurrentDC() == scratchport) //07/06/2000 AR: getcurrentDC returns a HDC, so compare with scratchport instead of &scratchpart
00185 
00186 #endif
00187 
00188 
00189 /*Forward*/
00190 
00191 static short maxdepth (Rect *r);
00192 
00193 
00194 #ifdef WIN95VERSION
00195 
00196 HBRUSH getcurrentbrush() {
00197 
00198     return (currentwindowbrush);
00199     } /*getcurrentbrush*/
00200 
00201 
00202 HDC getcurrentDC (void) {
00203     
00204     return (currentportDC);
00205     } /*getcurrentDC*/
00206 
00207 
00208 boolean winpushport (WindowPtr w, HDC hdc) {
00209     
00210     if (topport >= ctports) {
00211         
00212         shellinternalerror (idportstackfull, BIGSTRING ("\x13" "port stack overflow"));
00213         
00214         return (false);
00215         }
00216     
00217     assert (winportpushed == 0);
00218 
00219     portstack [topport++] = currentport;
00220     
00221     if (currentport != NULL)
00222         ReleaseDC (currentport, currentportDC);
00223     
00224     currentport = w;
00225     
00226     currentportDC = hdc;
00227     
00228     ++winportpushed;
00229     
00230     checkdepth (topport, maxport);
00231     
00232     return (true);
00233     } /*winpushport*/
00234 
00235 
00236 boolean winpopport () {
00237     
00238     currentport = NULL;
00239     
00240     currentportDC = NULL;
00241     
00242     --winportpushed;
00243     
00244     return (popport ());
00245     } /*winpopport*/
00246 
00247 #endif
00248 
00249 
00250 short getmenubarheight (void) {
00251 #ifdef MACVERSION   
00252     return (GetMBarHeight ()); /*call Script Manager routine*/
00253 #endif
00254 
00255 #ifdef WIN95VERSION
00256     return (GetSystemMetrics (SM_CYMENUSIZE));
00257 #endif
00258     } /*getmenubarheight*/
00259 
00260 
00261 GrafPtr getport (void) {
00262 
00263 #ifdef MACVERSION   
00264     return GetQDGlobalsThePort();
00265 #endif
00266 
00267 #ifdef WIN95VERSION
00268     return (currentport);
00269 #endif
00270     } /*getport*/
00271 
00272 
00273 CGrafPtr
00274 getwindowport(WindowPtr w)
00275 {
00276     return (GetWindowPort(w));
00277 }
00278 
00279 
00280 void setport (GrafPtr port) {
00281 
00282     #ifdef MACVERSION   
00283         SetPort (port);
00284     #endif
00285 
00286     #ifdef WIN95VERSION
00287         if (winportpushed)
00288             return;
00289 
00290         if (port != currentport) {
00291             
00292             if (currentport != NULL) {
00293                 
00294                 ReleaseDC (currentport, currentportDC);
00295                 
00296                 currentport = NULL;
00297                 
00298                 currentportDC = NULL;
00299                 }
00300             
00301             if (port != NULL) {
00302                 
00303                 currentport = port;
00304                 
00305                 currentportDC = GetDC (port);
00306                 }
00307             }
00308     #endif
00309     } /*setport*/
00310         
00311 
00312 boolean pushport (CGrafPtr p) {
00313     /*
00314     5.0.2b4 dmb: must reset global fontinfo when port changes
00315     */
00316     
00317     if (topport >= ctports) {
00318         
00319         shellinternalerror (idportstackfull, BIGSTRING ("\x13" "port stack overflow"));
00320         
00321         return (false);
00322         }
00323     
00324 #ifdef MACVERSION
00325     {
00326         CGrafPtr    theGlobalPort = getport();
00327 
00328         portstack [topport++] = theGlobalPort;
00329 
00330         if ((p != nil) && (p != theGlobalPort)) {
00331             
00332             setport (p);
00333             GetFontInfo (&globalfontinfo);
00334         }
00335     }
00336 #endif
00337 
00338 #ifdef WIN95VERSION
00339     portstack [topport++] = currentport;
00340     setport (p);
00341 #endif
00342     
00343     checkdepth (topport, maxport);
00344 
00345     return (true);
00346     } /*pushport*/
00347         
00348 
00349 boolean popport (void) {
00350 
00351     /*
00352     5.0.2b4 dmb: must reset global fontinfo when port changes
00353     */
00354     
00355     register CGrafPtr p;
00356     
00357     if (topport <= 0) {
00358         
00359         shellinternalerror (idportstackempty, BIGSTRING ("\x11" "too many popports"));
00360         
00361         return (false);
00362         }
00363     
00364     p = portstack [--topport];
00365     
00366 #ifdef MACVERSION
00367     {
00368         CGrafPtr    theQDPort = getport();
00369 
00370         if ((p != nil) && (p != theQDPort)) {
00371 
00372             setport (p);
00373 
00374             GetFontInfo (&globalfontinfo);
00375         }
00376     }
00377 #endif
00378     
00379     #ifdef WIN95VERSION
00380         setport (p);
00381     #endif
00382     
00383     return (true);
00384     } /*popport*/
00385 
00386 
00387 boolean pushscratchport (void) {
00388     
00389     /*
00390     2.1b4 dmb: call this when a port is needed, but no window is available
00391     */
00392     #ifdef MACVERSION
00393     //Code change by Timothy Paustian Monday, August 21, 2000 4:31:49 PM
00394     //Must pass a CGrafPtr to pushport on OS X to avoid a crash
00395     CGrafPtr    thePort;
00396     #if TARGET_API_MAC_CARBON == 1
00397     thePort = scratchport; /* hra: scratchport is already a CGrafPtr, not a WindowPtr */
00398     #else
00399     thePort = (CGrafPtr)scratchport;
00400     #endif
00401         
00402     return pushport (thePort);
00403     #endif
00404     #ifdef WIN95VERSION
00405         return (pushport (currentport));
00406     #endif
00407     } /*pushscratchport*/
00408 
00409 
00410 #if !flruntime
00411 
00412 boolean pushcliprgn (hdlregion rgnclip, boolean flomit) {
00413 
00414     #ifdef MACVERSION   
00415     register hdlregion rgn;
00416     #endif
00417     
00418     if (topclip >= ctclip) {
00419         
00420         shellinternalerror (idregionstackfull, BIGSTRING ("\x15" "region stack overflow"));
00421         
00422         return (false);
00423         }
00424     
00425     #ifdef MACVERSION   
00426         rgn = clipstack [topclip++];
00427         
00428         GetClip (rgn);
00429 
00430         if (flomit)
00431             DiffRgn (rgn, rgnclip, scratchrgn);
00432         else
00433             SectRgn (rgn, rgnclip, scratchrgn);
00434         
00435         SetClip (scratchrgn);
00436     #endif
00437     #ifdef WIN95VERSION
00438         winclipstack [topclip] = GetClipRgn (getcurrentDC(), clipstack [topclip]);
00439         
00440         topclip++;
00441         
00442         ExtSelectClipRgn (getcurrentDC(), rgnclip, flomit?RGN_DIFF:RGN_AND); // 5.13.97 dmb: was OR
00443     #endif  
00444     
00445     checkdepth (topclip, maxclip);
00446 
00447     return (true);
00448     } /*pushcliprgn*/
00449 
00450 
00451 boolean pushclip (Rect r) {
00452 
00453 #ifdef MACVERSION   
00454     RectRgn (scratchrgn, &r);
00455     
00456     return (pushcliprgn (scratchrgn, false));
00457 #endif
00458 
00459 #ifdef WIN95VERSION
00460     hdlregion rgn;
00461     boolean res;
00462 
00463     rgn = CreateRectRgn (r.left, r.top, r.right, r.bottom);
00464     res = pushcliprgn (rgn, false);
00465     DeleteObject (rgn);
00466     return (res);
00467 #endif
00468     } /*pushclip*/
00469 
00470 
00471 boolean superpushclip (Rect r) {
00472     
00473     /*
00474     pushclip is scoped, that is if you do a pushclip
00475     while one is already outstanding, you can't draw outside of the
00476     earlier rectangle...  superpushclip is the escape valve, very
00477     rarely called. but it allows you to break this rule.
00478     
00479     we put it in early so that we could start calling it.
00480     
00481     2/27/91 dmb: pushclip now provides true clip nesting, so this procedure 
00482     may be needed for real
00483     */
00484 
00485     if (topclip >= ctclip) {
00486         
00487         shellinternalerror (idclipstackfull, BIGSTRING ("\x13" "clip stack overflow"));
00488         
00489         return (false);
00490         }
00491 
00492 #ifdef MACVERSION   
00493     GetClip (clipstack [topclip++]);
00494 
00495     ClipRect (&r);
00496 #endif  
00497 #ifdef WIN95VERSION
00498     {
00499     hdlregion rgn;
00500 
00501     winclipstack [topclip] = GetClipRgn (getcurrentDC(), clipstack [topclip]);
00502     
00503     topclip++;
00504     
00505     rgn = CreateRectRgn (r.left, r.top, r.right, r.bottom);
00506     
00507     SelectClipRgn (getcurrentDC(), rgn);
00508     
00509     DeleteObject (rgn);
00510     }
00511 #endif
00512 
00513     checkdepth (topclip, maxclip);
00514 
00515     return (true);
00516     } /*superpushclip*/
00517 
00518 
00519 boolean pushvalidrgnclip (void) {
00520     
00521     /*
00522     set up the clip region so that it excludes any part of the window 
00523     that has a pending update; i.e. clip to the valid part of the window.
00524     */
00525     
00526 #ifdef MACVERSION
00527     //Code change by Timothy Paustian Monday, May 1, 2000 9:47:33 PM
00528     //Changed to Opaque call for Carbon
00529     //we are assuming that scratchrgn has already been allocated.
00530     #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
00531     WindowRef   theWindow;
00532     CGrafPtr    thePort = GetQDGlobalsThePort();
00533     theWindow = GetWindowFromPort(thePort);
00534     //This probably needs to change after the bug in kWindowUpdateRgn is fixed
00535     //check the carbon release notes I seem to rememebr something about
00536     //this not working.
00537     GetWindowRegion(theWindow, kWindowContentRgn, scratchrgn);
00538     #else
00539     //old code
00540     CopyRgn ((*(WindowPeek) quickdrawglobal (thePort)).updateRgn, scratchrgn);
00541     #endif
00542     globaltolocalrgn (scratchrgn);
00543     
00544     return (pushcliprgn (scratchrgn, true));
00545 #endif
00546 
00547 #ifdef WIN95VERSION
00548     hdlregion rgn;
00549     boolean res;
00550 
00551     rgn = CreateRectRgn (0,0,1,1);
00552     GetUpdateRgn (getcurrentwindow(), rgn, false);
00553     res = pushcliprgn (rgn, true);
00554     DeleteObject (rgn);
00555     return (res);
00556 #endif
00557     } /*pushvalidrgnclip*/
00558 
00559 
00560 boolean pushemptyclip (void) {
00561     
00562     /*
00563     set up the clip region so that no display will occur
00564     */
00565 #ifdef MACVERSION   
00566     SetEmptyRgn (scratchrgn);
00567     
00568     return (pushcliprgn (scratchrgn, false));
00569 #endif
00570 
00571 #ifdef WIN95VERSION
00572     hdlregion rgn;
00573     boolean res;
00574 
00575     rgn = CreateRectRgn (0,0,1,1);
00576     CombineRgn (rgn, rgn, rgn, RGN_XOR);
00577     res = pushcliprgn (rgn, false);
00578     DeleteObject (rgn);
00579     return (res);
00580 #endif
00581     } /*pushemptyclip*/
00582 
00583 
00584 boolean popclip (void) {
00585 
00586     if (topclip <= 0) {
00587         
00588         shellinternalerror (idclipstackempty, BIGSTRING ("\x11" "too many popclips"));
00589         
00590         return (false);
00591         }
00592     
00593 #ifdef MACVERSION
00594     SetClip (clipstack [--topclip]);
00595 #endif  
00596 #ifdef WIN95VERSION
00597     if (winclipstack [--topclip])
00598         SelectClipRgn (getcurrentDC(), clipstack [topclip]);
00599     else
00600         SelectClipRgn (getcurrentDC(), NULL);
00601 #endif  
00602     return (true);
00603     } /*popclip*/
00604 
00605 
00606 boolean pushstyle (short fnum, short fsize, short fstyle) {
00607     
00608     register tystylerecord *pstyle;
00609     
00610     if (topstyle >= ctstyle) {
00611         
00612         shellinternalerror (idstylestackfull, BIGSTRING ("\x14" "style stack overflow"));
00613         
00614         return (false);
00615         }
00616     
00617     pstyle = &stylestack [topstyle];
00618     
00619     getfontsizestyle (&(*pstyle).fnum, &(*pstyle).fsize, &(*pstyle).fstyle);
00620     
00621     topstyle++;
00622     
00623     //if ((pstyle->fnum != fnum) || (pstyle->fsize != fsize) || (pstyle->fstyle != fstyle))
00624         setglobalfontsizestyle (fnum, fsize, fstyle);
00625     
00626     checkdepth (topstyle, maxstyle);
00627     
00628     return (true);
00629     } /*pushstyle*/
00630         
00631 
00632 boolean popstyle (void) {
00633     short fnum, fsize, fstyle;
00634 
00635     if (topstyle <= 0) {
00636         
00637         shellinternalerror (idstylestackempty, BIGSTRING ("\x12" "too many popstyles"));
00638         
00639         return (false);
00640         }
00641     
00642     topstyle--;
00643 
00644     getfontsizestyle (&fnum, &fsize, &fstyle);
00645     
00646     //if ((stylestack[topstyle].fnum != fnum) || (stylestack [topstyle].fsize != fsize) || (stylestack [topstyle].fstyle != fstyle))
00647         setglobalfontsizestyle (stylestack [topstyle].fnum, stylestack [topstyle].fsize, 
00648                                 stylestack [topstyle].fstyle);
00649         
00650     return (true);
00651     } /*popstyle*/
00652 
00653 
00654 #ifdef WIN95VERSION
00655 
00656 static boolean equalcolors (const RGBColor *rgb1, const RGBColor *rgb2) {
00657     
00658     return (memcmp (rgb1, rgb2, sizeof (RGBColor)) == 0);
00659     } /*equalcolors*/
00660 
00661 
00662 static COLORREF wincolorref (const RGBColor *rgb) {
00663     
00664     /*
00665     5.0b7 dmb: map the stock quickdraw.c color values to the system
00666     color values, if there's a match, or just a win rgb
00667     */
00668     
00669     if (equalcolors (rgb, &whitecolor))
00670         return GetSysColor (COLOR_WINDOW);
00671     
00672     if (equalcolors (rgb, &blackcolor))
00673         return GetSysColor (COLOR_WINDOWTEXT);
00674     
00675     if (equalcolors (rgb, &graycolor))
00676         return GetSysColor (COLOR_BTNFACE);
00677     
00678     if (equalcolors (rgb, &darkgraycolor))
00679         return GetSysColor (COLOR_3DDKSHADOW);
00680 
00681     /*
00682     if (equalcolors (rgb, &mediumgraycolor))
00683         return GetSysColor(COLOR_WINDOW);
00684     */
00685     
00686     if (equalcolors (rgb, &lightgraycolor))
00687         return GetSysColor (COLOR_BTNHIGHLIGHT);
00688 
00689     return (WINRGB (*rgb));
00690     } /*wincolorref*/
00691 
00692 #endif
00693 
00694 
00695 boolean pushforecolor (const RGBColor *rgb) {
00696         
00697     if (colorenabled ()) {
00698     
00699         if (topforecolor >= ctforecolors) {
00700             
00701             DebugStr (BIGSTRING ("\x1f" "pushforecolor: no room on stack"));
00702             
00703             return (false);
00704             }
00705     
00706         #ifdef MACVERSION           
00707             GetForeColor (&forecolorstack [topforecolor++]);
00708                     
00709             /*
00710             3/9/93 DW: copy the rgb record so the caller can pass us the 
00711             address of a field of a heap-allocated record.
00712             */
00713                 {
00714                 RGBColor rgbcopy = *rgb;
00715                 RGBForeColor (&rgbcopy);
00716                 }
00717         #endif
00718 
00719         #ifdef WIN95VERSION
00720             {
00721             HDC hdc = getcurrentDC ();
00722             HPEN colorpen = CreatePen (PS_SOLID, 1, wincolorref (rgb));
00723             
00724             penstack[toppen++] = SelectObject (hdc, colorpen);
00725             
00726             forecolorstack [topforecolor++] = SetTextColor (hdc, wincolorref (rgb));
00727             }
00728         #endif
00729         }
00730         
00731     return (true);
00732     } /*pushforecolor*/
00733         
00734 
00735 boolean popforecolor (void) {
00736     
00737     if (colorenabled ()) {
00738     
00739         if (topforecolor <= 0) {
00740             
00741             DebugStr ( BIGSTRING ("\x1e" "popforecolor: nothing on stack"));
00742             
00743             return (false);
00744             }
00745         
00746         #ifdef MACVERSION       
00747             RGBForeColor (&forecolorstack [--topforecolor]);
00748         #endif
00749         
00750         #ifdef WIN95VERSION
00751             SetTextColor (getcurrentDC(), forecolorstack [--topforecolor]);
00752             
00753             poppen ();
00754         #endif
00755         }
00756     
00757     return (true);
00758     } /*popforecolor*/
00759     
00760 
00761 boolean pushbackcolor (const RGBColor *rgb) {
00762     
00763     /*
00764     5.0b8 dmb: maintain our own backcolor value. fixed problems, with 
00765     the initial level of push/pop, at least.
00766     */
00767 
00768     if (colorenabled ()) {
00769         
00770         if (topbackcolor >= ctbackcolors) {
00771             
00772             DebugStr (BIGSTRING ("\x1f" "pushbackcolor: no room on stack"));
00773             
00774             return (false);
00775             }
00776         
00777         #ifdef MACVERSION
00778             GetBackColor (&backcolorstack [topbackcolor++]);
00779             
00780             /*
00781             3/9/93 DW: copy the rgb record so the caller can pass us the 
00782             address of a field of a heap-allocated record.
00783             */
00784                 {
00785                 RGBColor rgbcopy = *rgb;
00786                 
00787                 RGBBackColor (&rgbcopy);
00788                 }
00789         #endif
00790 
00791         #ifdef WIN95VERSION
00792             backcolor = wincolorref (rgb);
00793             
00794             backcolorstack [topbackcolor++] = SetBkColor (getcurrentDC (), backcolor);
00795         #endif
00796         }
00797         
00798     return (true);
00799     } /*pushbackcolor*/
00800         
00801 
00802 boolean popbackcolor (void) {
00803     
00804     if (colorenabled ()) {
00805     
00806         if (topbackcolor <= 0) {
00807             
00808             DebugStr (BIGSTRING ("\x1e" "popbackcolor: nothing on stack"));
00809             
00810             return (false);
00811             }
00812         #ifdef MACVERSION       
00813             RGBBackColor (&backcolorstack [--topbackcolor]);
00814         #endif
00815 
00816         #ifdef WIN95VERSION
00817             backcolor = backcolorstack [--topbackcolor];
00818             
00819             SetBkColor (getcurrentDC(), backcolor);
00820         #endif
00821         }
00822     
00823     return (true);
00824     } /*popbackcolor*/
00825 
00826 
00827 boolean pushcolors (const RGBColor *forecolor, const RGBColor *backcolor) {
00828     
00829     pushforecolor (forecolor);
00830     
00831     return (pushbackcolor (backcolor));
00832     } /*pushcolors*/
00833 
00834 
00835 boolean popcolors (void) {
00836 //  char    s[256];
00837     popforecolor ();
00838     return (popbackcolor ());
00839     } /*popcolors*/
00840 
00841 
00842 boolean pushpen (void) {
00843     
00844     if (toppen >= ctpens)
00845         return (false);
00846     
00847     #ifdef MACVERSION   
00848         GetPenState (&penstack [toppen++]);
00849     #endif
00850         
00851     #ifdef WIN95VERSION
00852         penstack[toppen++] = SelectObject (getcurrentDC(), GetStockObject (NULL_PEN));
00853     #endif
00854 
00855     checkdepth (toppen, maxpen);
00856     
00857     return (true);
00858     } /*pushpen*/
00859     
00860 
00861 boolean poppen (void) {
00862     
00863     /*
00864     5.0a24 dmb: delete the current pen after it's swapped out. 
00865     shouldn't hurt if it as the null pen that pushpen sets, but
00866     is necessary if pushforecolor pushed the pen
00867     */
00868 
00869     if (toppen <= 0) {
00870         
00871         shellinternalerror (idpenstackempty, BIGSTRING ("\x10" "too many poppens"));
00872         
00873         return (false);
00874         }
00875 
00876     #ifdef MACVERSION   
00877         SetPenState (&penstack [--toppen]);
00878     #endif
00879 
00880     #ifdef WIN95VERSION
00881         DeleteObject (SelectObject (getcurrentDC(), penstack [--toppen]));
00882     #endif
00883 
00884     return (true);
00885     } /*poppen*/
00886     
00887     
00888 void getpenpoint (Point *pt) {
00889     
00890 #ifdef MACVERSION   
00891     GetPen (pt);
00892 #endif
00893 
00894 #ifdef WIN95VERSION
00895     (*pt).h = gPenPositionX;
00896 
00897     (*pt).v = gPenPositionY;
00898 #endif
00899     } /*getpenpoint*/
00900     
00901     
00902 boolean equalpoints (Point pt1, Point pt2) {
00903 #ifdef MACVERSION   
00904     return (EqualPt (pt1, pt2));
00905 #endif
00906 
00907 #ifdef WIN95VERSION
00908     return ((pt1.v == pt2.v) && (pt1.h == pt2.h));
00909 #endif
00910     } /*equalpoints*/
00911 
00912 
00913 short pointdist (Point pt1, Point pt2) {
00914     
00915     return (absint (pt1.h - pt2.h) + absint (pt1.v - pt2.v));
00916     } /*pointdist*/
00917 
00918 
00919 void movepento (short h, short v) {
00920     
00921     /*
00922     move the pen to the indicated position.
00923     */
00924     
00925 #ifdef MACVERSION
00926     MoveTo (h, v);
00927 #endif
00928 
00929 #ifdef WIN95VERSION
00930     MoveToEx (getcurrentDC(), h, v, NULL);
00931     gPenPositionX = h;
00932     gPenPositionY = v;
00933 #endif
00934     } /*movepento*/
00935     
00936     
00937 void pendrawline (short h, short v) {
00938     
00939     /*
00940     draw a line from the current pen position to the indicated position.  side-
00941     effect, the pen moves to the endpoint of the line.
00942     */
00943     
00944 #ifdef MACVERSION
00945     LineTo (h, v);
00946 #endif
00947 
00948 #ifdef WIN95VERSION
00949     LineTo (getcurrentDC(), h, v);
00950     gPenPositionX = h;
00951     gPenPositionY = v;
00952 #endif
00953     } /*pendrawline*/
00954     
00955 //Code change by Timothy Paustian Saturday, April 29, 2000 9:32:15 PM
00956 //Changed for UH 3.3.1 conclicts with drawstring in QuickDrawText.h
00957 static void Drawstring (bigstring bs, boolean fldisabled) {
00958 
00959 #ifdef MACVERSION
00960     if (fldisabled)
00961         TextMode (grayishTextOr);
00962     
00963     DrawString (bs);
00964     
00965     if (fldisabled)
00966         TextMode (srcOr);
00967 #endif
00968 
00969 #ifdef WIN95VERSION
00970     RECT r;
00971     HDC hdc = getcurrentDC();
00972 
00973     r.top = gPenPositionY - globalfontinfo.ascent;
00974     r.left = gPenPositionX;
00975     r.bottom = gPenPositionY + globalfontinfo.descent + globalfontinfo.leading;
00976     r.right = r.left + 2048;
00977 
00978     setWindowsFont();
00979     
00980     if (stringlength (bs) > 0) {
00981         
00982         int savebkmode = GetBkMode (hdc);
00983         
00984         SetBkMode (hdc, TRANSPARENT);
00985 
00986         DrawText (hdc, stringbaseaddress (bs), stringlength (bs), &r, DT_CALCRECT | DT_SINGLELINE | DT_NOPREFIX);
00987         
00988         if (fldisabled)
00989             GrayString (hdc, GetStockObject(BLACK_BRUSH) /*NULL*/, NULL, (LPARAM) stringbaseaddress(bs), stringlength (bs), 
00990                 r.left, r.top, r.right - r.left, r.bottom - r.top);
00991         else
00992             DrawText (hdc, stringbaseaddress (bs), stringlength (bs), &r, DT_NOCLIP | DT_NOPREFIX);
00993         
00994         SetBkMode (hdc, savebkmode);
00995 
00996         gPenPositionX = r.right;
00997         }
00998     
00999     clearWindowsFont();
01000 #endif
01001     } /*drawstring*/
01002 
01003 
01004 void pendrawstring (bigstring bs) {
01005     
01006     /*
01007     draw a string at the current pen position.  side-effect, the pen moves
01008     to point just after the last character drawn.
01009     */
01010 #ifdef MACVERSION   
01011     DrawString (bs);
01012 #endif
01013 
01014 #ifdef WIN95VERSION
01015     Drawstring (bs, false);
01016 #endif
01017     } /*pendrawstring*/
01018 
01019 
01020 void graydrawstring (bigstring bs) {
01021     
01022     Drawstring (bs, true);
01023     } /*graydrawstring*/
01024 
01025 
01026 short stringpixels (bigstring bs) {
01027     
01028     /*
01029     return the number of pixels the string would occupy if it were drawn in
01030     the current font, size and style.
01031 
01032     5.0a17 dmb: use DrawText to more closely reflect the width of drawn text.
01033     */
01034 
01035 #ifdef MACVERSION
01036     return (StringWidth (bs));
01037 #endif
01038 
01039 #ifdef WIN95VERSION
01040     RECT r;
01041     
01042     r.top = 0;
01043     r.left = 0;
01044     r.bottom = globalfontinfo.ascent + globalfontinfo.descent + globalfontinfo.leading;
01045     r.right = 0;
01046     
01047     setWindowsFont();
01048     // GetTextExtentPoint32 (getcurrentDC(), stringbaseaddress(bs), stringlength(bs), &stringSize); 
01049     DrawText (getcurrentDC(), stringbaseaddress (bs), stringlength (bs), &r, DT_SINGLELINE | DT_CALCRECT | DT_NOPREFIX);
01050     clearWindowsFont();
01051     return ((short)r.right);
01052 #endif
01053     } /*stringpixels*/
01054 
01055 
01056 void centerrect (Rect *rcentered, Rect rcontains) {
01057     
01058     /*
01059     center the first rectangle within the second rectangle.
01060     */
01061     
01062     register short height, width;
01063     Rect r;
01064     
01065     r = *rcentered;
01066     
01067     width = r.right - r.left;
01068     
01069     r.left = rcontains.left + ((rcontains.right - rcontains.left - width) / 2);
01070     
01071     r.right = r.left + width;
01072     
01073     height = r.bottom - r.top;
01074     
01075     r.top = rcontains.top + ((rcontains.bottom - rcontains.top - height) / 2);
01076     
01077     r.bottom = r.top + height;
01078     
01079     *rcentered = r;
01080     } /*centerrect*/
01081 
01082 
01083 boolean havecolorquickdraw (void) {
01084 #ifdef MACVERSION   
01085     //Code change by Timothy Paustian Friday, June 9, 2000 2:36:02 PM
01086     //Changed because using SysEnvisons and SysEnvRec is like Really old style
01087     //This was changed to Gestalt calls with two new globals see mac.c initmacintosh
01088     return gHasColorQD;
01089 #endif
01090 
01091 #ifdef WIN95VERSION
01092     return (true);  
01093 #endif
01094     } /*havecolorquickdraw*/
01095 
01096 
01097 void getcurrentscreenbounds (Rect *r) {
01098 #ifdef MACVERSION   
01099     /*
01100     instead of using screenBits.bounds, call this routine to find out 
01101     the bounding global rectangle for the current monitor.
01102     
01103     we do this very heuristically -- we return the global rectangle that
01104     encloses the monitor that the mouse is in.
01105     */
01106     
01107     register WindowPtr w = FrontWindow ();
01108     register GDHandle hdevice;
01109     Point mousepoint;
01110     boolean flmenubar = true;
01111     //Code change by Timothy Paustian Friday, June 9, 2000 10:05:41 PM
01112     //Changed to Opaque call for Carbon
01113     BitMap  screenBits;
01114     #if TARGET_API_MAC_CARBON == 1
01115     GetQDGlobalsScreenBits(&screenBits);
01116     #else
01117     screenBits = qd.screenBits;
01118     #endif
01119     
01120     *r = screenBits.bounds; /*default: use the old standby...*/
01121     
01122     if (!havecolorquickdraw () || (w == nil))
01123         goto exit;
01124     //Code change by Timothy Paustian Monday, August 21, 2000 4:31:49 PM
01125     //Must pass a CGrafPtr to pushport on OS X to avoid a crash
01126     {
01127     CGrafPtr    thePort;
01128     #if TARGET_API_MAC_CARBON == 1
01129     thePort = GetWindowPort(w);
01130     #else
01131     thePort = (CGrafPtr)w;
01132     #endif
01133     
01134     pushport (thePort);
01135     }
01136     
01137     GetMouse (&mousepoint);
01138     
01139     LocalToGlobal (&mousepoint);
01140     
01141     popport ();
01142     
01143     hdevice = GetDeviceList (); /*start with the first graphics device*/
01144     
01145     while (true) { /*step through the graphics device list*/
01146         
01147         if (hdevice == nil) /*no more devices to look at, didn't find mouse loc*/
01148             goto exit;
01149         
01150         *r = (**hdevice).gdRect;
01151         
01152         if (pointinrect (mousepoint, *r)) {
01153             
01154             flmenubar = hdevice == GetMainDevice ();
01155             
01156             goto exit;
01157             }
01158         
01159         hdevice = GetNextDevice (hdevice); /*advance to next device in list*/
01160         } /*while*/
01161     
01162     exit:
01163     
01164     if (flmenubar)
01165         (*r).top += getmenubarheight ();
01166 #endif
01167 
01168 #ifdef WIN95VERSION
01169 /*
01170 //Use GetSystemMetrics
01171     r->top = 0;
01172     r->left = 0;
01173     r->right = GetSystemMetrics (SM_CXFULLSCREEN);
01174     r->bottom = GetSystemMetrics (SM_CYFULLSCREEN);
01175 */
01176     getdesktopbounds (r);
01177 #endif
01178     } /*getcurrentscreenbounds*/
01179 
01180 
01181 void getwindowscreenbounds (const Rect *rwindow, Rect *r) {
01182 #ifdef MACVERSION   
01183     /*
01184     instead of using screenBits.bounds, call this routine to find out 
01185     the bounding global rectangle for the monitor containing the 
01186     given window.
01187     
01188     if there is a window open, we determine which monitor it mostly
01189     resides on (windows can span two monitors) and return the global
01190     rectangle that encloses that window.
01191     
01192     if no window is given, or color quickdraw isn't around, we use 
01193     screenbits.bounds.
01194     
01195     12/15/91 dmb: don't look at inactive screens
01196     
01197     2.1b2 dmb: take desired rwindow directly instead of using a window's portrect
01198     */
01199     
01200     register GDHandle hdevice;
01201     register GDHandle hmost = nil;
01202     register long ctpixelsmost = 0;
01203     register long ctpixels;
01204     Rect rsect;
01205     //Code change by Timothy Paustian Friday, June 9, 2000 10:05:50 PM
01206     //Changed to Opaque call for Carbon
01207     BitMap  screenBits;
01208     #if TARGET_API_MAC_CARBON == 1
01209     GetQDGlobalsScreenBits(&screenBits);
01210     #else
01211     screenBits = qd.screenBits;
01212     #endif
01213     
01214     *r = screenBits.bounds; /*default return value, if no window open, or error*/
01215     
01216     /* commenting this out because we don't run on systems without color quickdraw anyway */
01217     /*
01218     if (!havecolorquickdraw ())
01219         goto exit;
01220     */
01221     
01222     hdevice = GetDeviceList (); /*start with the first graphics device*/
01223     
01224     while (true) { /*step through the graphics device list*/
01225         
01226         if (hdevice == nil) { /*no more devices to look at*/
01227             
01228             if (hmost != nil) {
01229                 
01230                 /*
01231                     2006-03-27 SMD - let the OS tell us about the available bounds
01232                     this handles the menubar, the dock, and anything else the system knows about
01233                 */
01234                 GetAvailableWindowPositioningBounds (hmost, r);
01235                 }
01236             
01237             break;  /* exit the while loop */
01238             }
01239         
01240         if (((**hdevice).gdFlags | (1 << screenActive)) != 0) { /*screen is active*/
01241                 
01242             if (SectRect (rwindow, &(**hdevice).gdRect, &rsect)) { /*they intersect*/
01243                 
01244                 ctpixels = abs ((long) (rsect.right - rsect.left) * (long) (rsect.bottom - rsect.top));
01245                 
01246                 if (ctpixels > ctpixelsmost) { /*more than last device that intersects*/
01247                     
01248                     ctpixelsmost = ctpixels;
01249                     
01250                     hmost = hdevice;
01251                     }
01252                 }
01253             }
01254         
01255         hdevice = GetNextDevice (hdevice); /*advance to next device in list*/
01256         } /*while*/
01257     
01258 #endif
01259 
01260 #ifdef WIN95VERSION
01261 /*
01262 //Use GetSystemMetrics
01263     r->top = 0;
01264     r->left = 0;
01265     r->right = GetSystemMetrics (SM_CXFULLSCREEN);
01266     r->bottom = GetSystemMetrics (SM_CYFULLSCREEN);
01267 */
01268     getdesktopbounds (r);
01269 #endif
01270     } /*getwindowscreenbounds*/
01271 
01272 
01273 void centerrectondesktop (Rect *r) {
01274     
01275     Rect rscreen;
01276     
01277     getcurrentscreenbounds (&rscreen);
01278     
01279     centerrect (r, rscreen);
01280     } /*centerrectondesktop*/
01281 
01282 
01283 void centerbuttonstring (const Rect *r, bigstring bs, boolean fldisabled) {
01284     
01285     /*
01286     draw the string in the current font, size and style, centered inside
01287     the indicated rectangle.
01288     
01289     11/10/89 DW: workaround wierdnesses in geneva 9 by subtracting 1 from v.
01290     
01291     9/10/91 dmb: geneva 9 workaround can mess up other fonts; added check to 
01292     ensure top of characters aren't cut off
01293 
01294     6.26.97 dmb: added fldisabled, renamed as centerbuttonstring
01295     */
01296     
01297     register short lh = globalfontinfo.ascent + globalfontinfo.descent; /*line height*/
01298     register short rh = (*r).bottom - (*r).top;
01299     register short rw = (*r).right - (*r).left;
01300     register short h, v;
01301     
01302     ellipsize (bs, rw); /*make sure it fits inside the rectangle, width-wise*/
01303     
01304     h = (*r).left + ((rw - stringpixels (bs)) / 2);
01305     
01306     v = (*r).top + ((rh - lh) / 2);
01307     
01308     if (v > (*r).top) /*9/10/91*/
01309         v--;
01310     
01311     #if TARGET_API_MAC_CARBON
01312     
01313         v--;
01314         
01315     #endif
01316     
01317     movepento (h, v + globalfontinfo.ascent);
01318     
01319     pushclip (*r);
01320     
01321     Drawstring (bs, fldisabled);
01322     
01323     popclip ();
01324     } /*centerbuttonstring*/
01325 
01326 
01327 void grayrect (Rect r) {
01328 #ifdef MACVERSION       
01329     pushpen ();
01330     
01331     PenMode (patBic);
01332     {
01333     #if TARGET_API_MAC_CARBON == 1
01334     
01335     Pattern gray;
01336     GetQDGlobalsGray(&gray);
01337     PenPat(&gray);
01338     #else
01339     PenPat (&qd.gray);
01340     
01341     #endif
01342     }
01343     PaintRect (&r);
01344     
01345     poppen ();
01346 #endif
01347 
01348 #ifdef WIN95VERSION
01349     /*
01350     HDC hdc = getcurrentDC ();
01351     int oldROP2;
01352     HPEN oldpen, graypen;
01353     
01354     oldROP2 = SetROP2 (hdc, R2_BLACK);
01355     
01356     graypen = CreatePen (PS_DOT, 0, 0);
01357     
01358     oldpen = SelectObject (hdc, graypen);
01359 
01360     fillrect (r, getstockpattern (stockgray));
01361     
01362     SelectObject (hdc, oldpen);
01363     
01364     SetROP2 (hdc, oldROP2);
01365     
01366     DeleteObject (graypen);
01367     */
01368 #endif
01369     } /*grayrect*/
01370     
01371     
01372 /*
01373 void evenrectangle (Rect *rsource) {
01374     
01375     register Rect *r = rsource;
01376     
01377     if ((*r).top % 2) {
01378         
01379         (*r).top++;
01380         
01381         (*r).bottom++;
01382         }
01383         
01384     if ((*r).left % 2) {
01385         
01386         (*r).left++;
01387         
01388         (*r).right++;
01389         }
01390     } %*evenrectangle*/
01391     
01392 
01393 /*
01394 void oddrectangle (Rect *rsource) {
01395     
01396     register Rect *r = rsource;
01397     
01398     if (((*r).top % 2) == 0) {
01399         
01400         (*r).top++;
01401         
01402         (*r).bottom++;
01403         }
01404         
01405     if (((*r).left % 2) == 0) {
01406         
01407         (*r).left++;
01408         
01409         (*r).right++;
01410         }
01411     } %*oddrectangle*/
01412     
01413 
01414 void zerorect (Rect *rzero) {
01415     
01416     register Rect *r = rzero;
01417     
01418     (*r).top = (*r).left = (*r).bottom = (*r).right = 0;
01419     } /*zerorect*/
01420     
01421 
01422 boolean equalrects (Rect r1, Rect r2) {
01423     
01424     return (
01425         (r1.top == r2.top) && (r1.left == r2.left) && 
01426         
01427         (r1.bottom == r2.bottom) && (r1.right == r2.right));
01428     } /*equalrects*/
01429     
01430 
01431 boolean issubrect (Rect r1, Rect r2) {
01432     
01433     /*
01434     return true if r1 is completely contained within r2.
01435     */
01436     
01437     Rect runion;
01438     
01439     unionrect (r1, r2, &runion);
01440     
01441     return (equalrects (r2, runion));
01442     } /*issubrect*/
01443 
01444 #endif
01445 
01446 
01447 void globaltolocalrgn (hdlregion rgn) {
01448 #ifdef MACVERSION   
01449     Point pt;
01450     
01451     SetPt (&pt, 0, 0);
01452     
01453     GlobalToLocal (&pt);
01454     
01455     OffsetRgn (rgn, pt.h, pt.v);
01456 #endif
01457     } /*globaltolocalrgn*/
01458     
01459     
01460 void localtoglobalrect (WindowPtr w, Rect *r) {
01461     
01462     /*
01463     convert the rectangle inside w to global coordinates on the desktop.
01464     */
01465 #ifdef MACVERSION   
01466     register Rect *x = r;
01467     Point p1, p2;
01468     //Code change by Timothy Paustian Monday, August 21, 2000 4:31:49 PM
01469     //Must pass a CGrafPtr to pushport on OS X to avoid a crash
01470     CGrafPtr    thePort;
01471     #if TARGET_API_MAC_CARBON == 1
01472     thePort = GetWindowPort(w);
01473     #else
01474     thePort = (CGrafPtr)w;
01475     #endif
01476         
01477     pushport (thePort);
01478     
01479     p1 = topLeft (*x);
01480     
01481     p2 = botRight (*x);
01482     
01483     LocalToGlobal (&p1);
01484     
01485     LocalToGlobal (&p2);
01486     
01487     Pt2Rect (p1, p2, x);
01488     
01489     popport ();
01490 #endif
01491 
01492 #ifdef WIN95VERSION
01493     /*
01494     for points, global means screen coordinates.
01495     for rects, global means frame-relative coordinates
01496     */
01497 
01498     POINT winpt;
01499     
01500     winpt.x = (*r).left;
01501     winpt.y = (*r).top;
01502     
01503 //  ClientToScreen (w, &winpt);
01504     MapWindowPoints (w, shellframewindow, &winpt, 1);
01505     
01506     offsetrect (r, winpt.x - (*r).left, winpt.y - (*r).top);
01507 #endif
01508     } /*localtoglobalrect*/
01509     
01510     
01511 void globaltolocalpoint (WindowPtr w, Point *pt) {
01512 #ifdef MACVERSION   
01513     //Code change by Timothy Paustian Monday, August 21, 2000 4:31:49 PM
01514     //Must pass a CGrafPtr to pushport on OS X to avoid a crash
01515     CGrafPtr    thePort;
01516     #if TARGET_API_MAC_CARBON == 1
01517     thePort = GetWindowPort(w);
01518     #else
01519     thePort = (CGrafPtr)w;
01520     #endif
01521         
01522     pushport (thePort);
01523     
01524     GlobalToLocal (pt);
01525     
01526     popport ();
01527 #endif
01528 #ifdef WIN95VERSION
01529     /*
01530     for points, global means screen coordinates.
01531     for rects, global means frame-relative coordinates
01532     */
01533 
01534     POINT winpt;
01535     
01536     winpt.x = (*pt).h;
01537     winpt.y = (*pt).v;
01538     
01539     ScreenToClient (w, &winpt);
01540 //  MapWindowPoints (shellframewindow, w, &winpt, 1);
01541     
01542     (*pt).h = (short)winpt.x;
01543     (*pt).v = (short)winpt.y;
01544 #endif
01545     } /*globaltolocalpoint*/
01546     
01547     
01548 void localtoglobalpoint (WindowPtr w, Point *pt) {
01549 #ifdef MACVERSION   
01550     //Code change by Timothy Paustian Monday, August 21, 2000 4:31:49 PM
01551     //Must pass a CGrafPtr to pushport on OS X to avoid a crash
01552     CGrafPtr    thePort;
01553     #if TARGET_API_MAC_CARBON == 1
01554     thePort = GetWindowPort(w);
01555     #else
01556     thePort = (CGrafPtr)w;
01557     #endif
01558         
01559     pushport (thePort);
01560     
01561     LocalToGlobal (pt);
01562     
01563     popport ();
01564 #endif
01565 
01566 #ifdef WIN95VERSION
01567     /*
01568     for points, global means screen coordinates. we're probably
01569     talking about the mouse position
01570 
01571     for rects, global means frame-relative coordinates. we're probably
01572     talking about a window position
01573     */
01574 
01575     POINT winpt;
01576     
01577     winpt.x = (*pt).h;
01578     winpt.y = (*pt).v;
01579     
01580     ClientToScreen (w, &winpt);
01581 //  MapWindowPoints (w, shellframewindow, &winpt, 1);
01582     
01583     (*pt).h = (short)winpt.x;
01584     (*pt).v = (short)winpt.y;
01585 #endif
01586     } /*localtoglobalpoint*/
01587     
01588 
01589 #if !flruntime
01590     
01591 void flashrect (Rect r, short ctflashes) {
01592     
01593     /*
01594     invert and uninvert the rectangle several times, with delays, to simulate
01595     a menu selection type animation.
01596     */
01597     
01598     register short ct = ctflashes;
01599     register short i;
01600     
01601     pushclip (r);
01602     
01603     for (i = 1; i <= ct; i++) {
01604         
01605         if (i > 1)
01606             delayticks (1);
01607         
01608         invertrect (r);
01609         
01610         delayticks (2);
01611         
01612         invertrect (r);
01613         } /*for*/
01614         
01615     popclip ();
01616     } /*flashrect*/
01617     
01618     
01619 void dropshadowrect (Rect r, short width, boolean flerase) {
01620     
01621     /*
01622     draw a drop-shadow to the right and below the indicated rectangle.  if flerase,
01623     then we fill the drop shadow area with gray.  it's designed to manage buttons
01624     displayed on a field of gray.
01625     */
01626     
01627     Rect rfill;
01628     
01629     rfill = r;
01630     
01631     rfill.top++;
01632     
01633     rfill.left = rfill.right;
01634     
01635     rfill.right = rfill.left + width;
01636     
01637     rfill.bottom += width;
01638     
01639     if (flerase) {
01640         //Code change by Timothy Paustian Friday, June 9, 2000 10:10:25 PM
01641         //Changed to Opaque call for Carbon
01642         #if TARGET_API_MAC_CARBON == 1
01643             Pattern gray;
01644             
01645             GetQDGlobalsGray(&gray);
01646             
01647             fillrect (rfill, gray);
01648         #else
01649             fillrect (rfill, getstockpattern (stockgray));
01650         #endif
01651         }
01652     else {
01653         #if TARGET_API_MAC_CARBON == 1
01654             Pattern black;
01655 
01656             GetQDGlobalsBlack(&black);
01657             
01658             fillrect (rfill, black);
01659         #else
01660             fillrect (rfill, getstockpattern (stockblack));
01661         #endif
01662         }
01663 
01664                             
01665     rfill = r;
01666     
01667     rfill.top = rfill.bottom;
01668     
01669     rfill.bottom = rfill.top + width;
01670     
01671     rfill.left++;
01672     
01673     rfill.right += width;
01674     
01675     if (flerase) {
01676         //Code change by Timothy Paustian Friday, June 9, 2000 10:10:25 PM
01677         //Changed to Opaque call for Carbon
01678         #if TARGET_API_MAC_CARBON == 1
01679             Pattern gray;
01680 
01681             GetQDGlobalsGray(&gray);
01682             
01683             fillrect (rfill, gray);
01684         #else
01685             fillrect (rfill, getstockpattern (stockgray));
01686         #endif
01687         }
01688     else {
01689         #if TARGET_API_MAC_CARBON == 1
01690             Pattern black;
01691 
01692             GetQDGlobalsBlack(&black);
01693             
01694             fillrect (rfill, black);
01695         #else
01696             fillrect (rfill, getstockpattern (stockblack));
01697         #endif
01698         }
01699     } /*dropshadowrect*/
01700 
01701 
01702 void smashrect (Rect r) {
01703 #ifdef MACVERSION       
01704     EraseRect (&r);
01705     //Code change by Timothy Paustian Friday, June 9, 2000 10:13:24 PM
01706     //Changed to Opaque call for Carbon
01707     #if TARGET_API_MAC_CARBON == 1
01708     //Will GetFrontWindowOfClass do what we want. I hope so.
01709     {
01710     WindowRef w;    
01711     CGrafPtr thePort = GetQDGlobalsThePort();
01712     
01713     w = GetWindowFromPort (thePort);
01714         
01715     InvalWindowRect(w, &r);
01716     }
01717     #else
01718     InvalRect (&r);
01719     #endif
01720 #endif
01721 #ifdef WIN95VERSION
01722     RECT winrect;
01723     recttowinrect (&r, &winrect);
01724     InvalidateRect (getcurrentwindow(), &winrect, true);
01725 
01726 #endif
01727     } /*smashrect*/
01728     
01729 
01730 void invalrect (Rect r) {
01731 #ifdef MACVERSION   
01732     //Code change by Timothy Paustian Friday, June 9, 2000 10:13:24 PM
01733     //Changed to Opaque call for Carbon
01734     #if TARGET_API_MAC_CARBON == 1
01735     //Will GetFrontWindowOfClass do what we want. I hope so.
01736     //InvalWindowRect(GetFrontWindowOfClass(kAllWindowClasses, false), &r);
01737     {
01738     WindowRef w;    
01739     CGrafPtr thePort = GetQDGlobalsThePort();
01740     
01741     w = GetWindowFromPort (thePort);
01742         
01743     InvalWindowRect(w, &r);
01744     }
01745     #else
01746     InvalRect (&r);
01747     #endif
01748 #endif
01749 #ifdef WIN95VERSION
01750     RECT winrect;
01751     recttowinrect (&r, &winrect);
01752     InvalidateRect (getcurrentwindow(), &winrect, false);
01753 
01754 #endif
01755     } /*invalrect*/
01756     
01757     
01758 void invalwindowrect (WindowPtr w, Rect r) {
01759 
01760     //Code change by Timothy Paustian Monday, August 21, 2000 4:31:49 PM
01761     //Must pass a CGrafPtr to pushport on OS X to avoid a crash
01762     CGrafPtr    thePort;
01763     #if TARGET_API_MAC_CARBON == 1
01764     thePort = GetWindowPort(w);
01765     #else
01766     thePort = (CGrafPtr)w;
01767     #endif
01768         
01769     pushport (thePort);
01770     
01771     invalrect (r);
01772     
01773     popport ();
01774     } /*invalwindowrect*/
01775 
01776 
01777 void validrect (Rect r) {
01778 #ifdef MACVERSION   
01779     #if TARGET_API_MAC_CARBON == 1
01780     //ValidWindowRect(GetFrontWindowOfClass(kAllWindowClasses, false), &r);
01781     ValidWindowRect (shellwindow, &r);
01782     #else
01783     ValidRect (&r);
01784     #endif
01785 #endif
01786 #ifdef WIN95VERSION
01787     RECT winrect;
01788     recttowinrect (&r, &winrect);
01789     ValidateRect (getcurrentwindow(), &winrect);
01790 #endif
01791     } /*validrect*/
01792 
01793 
01794 void eraserect (Rect r) {
01795 
01796 #ifdef MACVERSION   
01797     EraseRect (&r);
01798 #endif
01799 #ifdef WIN95VERSION
01800     RECT winrect;
01801     recttowinrect (&r, &winrect);
01802 
01803     if (!isemptyrect (r)) {
01804         
01805         if (topbackcolor > 0) {
01806 
01807             HBRUSH brush = CreateSolidBrush (GetBkColor (getcurrentDC()));
01808             FillRect (getcurrentDC(), &winrect, brush);
01809             DeleteObject (brush);
01810             }
01811         else
01812             FillRect (getcurrentDC(), &winrect, (HBRUSH) (COLOR_BTNFACE + 1));  // );GetStockObject(WHITE_BRUSH)
01813         
01814     //  FillRect (getcurrentDC(), &winrect, (HBRUSH) backcolor);
01815         }
01816 #endif
01817     } /*eraserect*/
01818     
01819 
01820 void framerect (Rect r) {
01821     
01822     #ifdef gray3Dlook
01823         boolean fllargeobject;
01824 
01825         if (isemptyrect (r))
01826             return;
01827 
01828         fllargeobject = r.bottom - r.top > 18;
01829 
01830         --r.right;
01831         --r.bottom;
01832         movepento (r.left, r.bottom);
01833         
01834         if (fllargeobject)
01835             pushforecolor (&darkgraycolor);
01836         else
01837             pushforecolor (&lightgraycolor);
01838 
01839         pendrawline (r.left, r.top);
01840         pendrawline (r.right, r.top);
01841         popforecolor ();
01842         
01843         if (fllargeobject)
01844             pushforecolor (&lightgraycolor);
01845         else
01846             pushforecolor (&darkgraycolor);
01847 
01848         pendrawline (r.right, r.bottom);
01849         pendrawline (r.left, r.bottom);
01850         popforecolor ();
01851     #else
01852         if (isemptyrect (r))
01853             return;
01854 
01855         #ifdef MACVERSION   
01856             FrameRect (&r);
01857         #endif
01858 
01859         #ifdef WIN95VERSION
01860         {
01861             RECT winrect;
01862             recttowinrect (&r, &winrect);
01863             FrameRect (getcurrentDC(), &winrect, getcurrentbrush());
01864         }
01865         #endif
01866     #endif
01867     } /*framerect*/
01868 
01869 
01870 void drawthemeborder (Rect r, Rect rcontent) {
01871     
01872     /*
01873     7.0b52 PBS: draw the "scan line" theme border on OS X.
01874     */
01875     
01876     #if TARGET_API_MAC_CARBON == 1
01877     
01878         //register hdlminirecord hm = minidata;
01879         //register hdlwindowinfo hw = miniwindowinfo;
01880         //WindowPtr w = (**hw).macwindow;
01881         Rect /*r, rcontent, */ rbackground;
01882 
01883         /*r = (**hm).textrects [0];
01884 
01885         rcontent = (**hw).contentrect;*/
01886         
01887         pushpen ();
01888         
01889         setthemepen (kThemeBrushDialogBackgroundActive, rcontent, true);
01890         
01891         rbackground.top = 0;
01892         rbackground.left = 0;
01893         rbackground.bottom = rcontent.bottom;
01894         rbackground.right = r.left;
01895         
01896         paintrect (rbackground);
01897         
01898         rbackground.right = rcontent.right;
01899         rbackground.bottom = r.top;
01900         
01901         paintrect (rbackground);
01902         
01903         rbackground.left = r.right;
01904         rbackground.right = rcontent.right;
01905         rbackground.bottom = rcontent.bottom;
01906         
01907         paintrect (rbackground);
01908         
01909         rbackground.left = 0;
01910         rbackground.top = r.bottom;
01911         
01912         paintrect (rbackground);
01913         
01914         poppen ();
01915 
01916     #endif
01917     
01918     }
01919 
01920 
01921 void setgraypen (void) {
01922 #ifdef MACVERSION   
01923     //Code change by Timothy Paustian Friday, June 9, 2000 10:22:55 PM
01924     //Changed to Opaque call for Carbon
01925     #if TARGET_API_MAC_CARBON == 1
01926     Pattern gray;
01927     PenPat(GetQDGlobalsGray(&gray));
01928     #else
01929     PenPat (&qd.gray);
01930     #endif
01931 #endif
01932 
01933 #ifdef WIN95VERSION
01934     HPEN graypen;
01935 
01936     currentwindowbrush = GetStockObject (GRAY_BRUSH);
01937     
01938     graypen = CreatePen (PS_SOLID, 0, RGB (0x7f, 0x7f, 0x7f));
01939 
01940     SelectObject (getcurrentDC(), graypen);
01941 
01942     assert (toppen > 0); // assume caller has pushed a pen
01943 #endif
01944     } /*setgraypen*/
01945 
01946 
01947 void setthemepen (const short brush, Rect r, boolean flupdate) {
01948 
01949     #if TARGET_API_MAC_CARBON == 1
01950     
01951         SetThemePen (brush, maxdepth (&r), flupdate);
01952                 
01953     #endif
01954     } /*setthemepen*/
01955 
01956 
01957 void graydrawline (short h, short v) {
01958 
01959 #ifdef MACVERSION       
01960     pushpen ();
01961     
01962     setgraypen (); 
01963     
01964     PenMode (patCopy);// (patXor);
01965     
01966     LineTo (h, v);
01967     
01968     poppen ();
01969 #endif
01970 
01971 #ifdef WIN95VERSION
01972     HDC hdc = getcurrentDC ();
01973     int oldROP2;
01974     HPEN oldpen, graypen;
01975     
01976     oldROP2 = SetROP2 (hdc, R2_XORPEN);
01977     
01978     graypen = CreatePen (PS_DOT, 0, 0);
01979     
01980     oldpen = SelectObject (hdc, graypen);
01981 
01982     LineTo (hdc, h, v);
01983     
01984     SelectObject (hdc, oldpen);
01985     
01986     SetROP2 (hdc, oldROP2);
01987     
01988     DeleteObject (graypen);
01989 
01990     gPenPositionX = h;
01991     gPenPositionY = v;
01992 #endif
01993     } /*graydrawline*/
01994 
01995 
01996 void grayframerect (Rect r) {
01997     #ifdef MACVERSION       
01998         pushpen ();
01999         
02000         setgraypen ();
02001         
02002         FrameRect (&r);
02003         
02004         poppen ();
02005     #endif
02006 
02007     #ifdef WIN95VERSION
02008         RECT winrect;
02009         HGDIOBJ brush;
02010 
02011         recttowinrect (&r, &winrect);
02012 
02013         brush = GetStockObject (GRAY_BRUSH);
02014 
02015         FrameRect (getcurrentDC(), &winrect, brush);
02016 
02017         DeleteObject (brush); //Not needed, but not harmful - keep code complete
02018     #endif
02019     } /*grayframerect*/
02020 
02021 
02022 void grayframerrgn (hdlregion rgn) {
02023     
02024     /*
02025     5.0b8 dmb: use xor rop2 so wp selrgn can be inverted
02026     */
02027     
02028     #ifdef MACVERSION   
02029         pushpen ();
02030         
02031         setgraypen ();
02032         
02033         PenMode (patCopy);// (patXor);
02034         
02035         FrameRgn (rgn);
02036         
02037         poppen ();
02038     #endif
02039 
02040     #ifdef WIN95VERSION
02041         HDC hdc = getcurrentDC();
02042         HGDIOBJ brush;
02043         int oldROP2;
02044 
02045         brush = GetStockObject (GRAY_BRUSH);
02046         
02047         oldROP2 = SetROP2 (hdc, R2_XORPEN);
02048 
02049         FrameRgn (hdc, rgn, brush, 1, 1);
02050 
02051         SetROP2 (hdc, oldROP2);
02052 
02053         DeleteObject (brush); //Not needed, but not harmful - keep code complete
02054     #endif
02055     } /*grayframerrgn*/
02056 
02057 
02058 void fillrect (Rect r, xppattern pat) {
02059     #ifdef MACVERSION
02060         qdfillrect (&r, &pat);
02061     #endif
02062 
02063     #ifdef WIN95VERSION
02064         RECT winrect;
02065         recttowinrect (&r, &winrect);
02066         FillRect (getcurrentDC(), &winrect, pat);
02067     #endif
02068     } /*fillrect*/
02069 
02070 
02071 #ifdef MACVERSION
02072 void paintrect (Rect r) {
02073     
02074     PaintRect (&r);
02075     } /*paintrect*/
02076 #endif  
02077 
02078 
02079 void frame3sides (Rect r) {
02080     
02081     /*
02082     draw a border, leaving out the right side of the rect.  makes it prettier
02083     if you're displaying a scrollbar to the right of the rect, for example.
02084 
02085     5.0a25 dmb: for Win vesion we now use this routine to frame the content
02086     areas
02087     */
02088     
02089     #ifdef MACVERSION
02090     --r.bottom;
02091     
02092     movepento (r.right, r.top); 
02093     
02094     pendrawline (r.left, r.top); /*draw top of box*/
02095     
02096     pendrawline (r.left, r.bottom); /*draw left side of box*/
02097     
02098     pendrawline (r.right, r.bottom); /*draw bottom of box*/
02099     
02100     #if TARGET_API_MAC_CARBON == 1
02101     
02102         {
02103         Rect rwindow;
02104         Rect rbackground;
02105         short depth;
02106         
02107         shellgetwindowrect (shellwindowinfo, &rwindow);
02108         
02109         depth = maxdepth (&rwindow);
02110                 
02111         pushpen ();
02112         
02113         setthemepen (kThemeBrushDialogBackgroundActive, rwindow, true);
02114         
02115         rbackground.top = 0;
02116         rbackground.left = 0;
02117         rbackground.bottom = r.top - 1;
02118         rbackground.right = rwindow.right;
02119         
02120         paintrect (rbackground);
02121         
02122         rbackground.right = r.left - 1;
02123         rbackground.bottom = rwindow.bottom;
02124         
02125         paintrect (rbackground);
02126         
02127         rbackground.left = r.right;
02128         rbackground.right = rwindow.right;
02129         
02130         paintrect (rbackground);
02131         
02132         rbackground.left = 0;
02133         rbackground.top = r.bottom + 1;
02134         rbackground.bottom = rwindow.bottom;
02135         
02136         paintrect (rbackground);
02137         
02138         poppen ();
02139         }
02140     
02141     
02142     #endif
02143     
02144     #endif
02145 
02146     #ifdef WIN95VERSION
02147     --r.right;
02148 
02149     --r.bottom;
02150 
02151     movepento (r.right, r.top); 
02152     
02153     pendrawline (r.left, r.top); /*draw top of box*/
02154     
02155     pendrawline (r.left, r.bottom); /*draw left side of box*/
02156     
02157     pendrawline (r.right, r.bottom); /*draw bottom of box*/
02158     
02159     pendrawline (r.right, r.top); /*draw right of box*/
02160     #endif
02161     } /*frame3sides*/
02162     
02163 
02164 void eraseandframerect (Rect r) {
02165 
02166     eraserect (r);
02167 
02168     framerect (r);
02169     } /*eraseandframerect*/
02170 
02171 
02172 void invertrect (Rect r) {
02173 #ifdef MACVERSION   
02174     InvertRect (&r);
02175 #endif
02176 
02177 #ifdef WIN95VERSION
02178     RECT winrect;
02179 
02180     recttowinrect (&r, &winrect);
02181 
02182     InvertRect (getcurrentDC(), &winrect);
02183 #endif
02184     } /*invertrect*/    
02185     
02186 #endif
02187 
02188 
02189 void setrect (Rect *rset, short top, short pleft, short bottom, short pright) {
02190     
02191     register Rect *r = rset;
02192     
02193     (*r).top = top;
02194     
02195     (*r).left = pleft;
02196     
02197     (*r).bottom = bottom;
02198     
02199     (*r).right = pright;
02200     } /*setrect*/
02201     
02202 
02203 void insetrect (Rect *r, short dh, short dv) {
02204 #ifdef MACVERSION   
02205     InsetRect (r, dh, dv);
02206 #endif
02207 #ifdef WIN95VERSION
02208     RECT winrect;
02209 
02210     recttowinrect (r, &winrect);
02211 
02212     InflateRect (&winrect, dh*-1, dv*-1);
02213 
02214     winrecttorect (&winrect, r);
02215 #endif
02216     } /*insetrect*/
02217     
02218 
02219 void offsetrect (Rect *r, short dh, short dv) {
02220 #ifdef MACVERSION   
02221     OffsetRect (r, dh, dv);
02222 #endif
02223 #ifdef WIN95VERSION
02224     RECT winrect;
02225 
02226     recttowinrect (r, &winrect);
02227 
02228     OffsetRect (&winrect, dh, dv);
02229 
02230     winrecttorect (&winrect, r);
02231 #endif
02232     } /*offsetrect*/
02233     
02234 
02235 boolean pointinrect (Point pt, Rect r) {
02236 
02237     #ifdef MACVERSION   
02238         return (PtInRect (pt, &r));
02239     #endif
02240     #ifdef WIN95VERSION
02241         RECT winrect;
02242         POINT winpoint;
02243 
02244         recttowinrect (&r, &winrect);
02245         winpoint.x = pt.h;
02246         winpoint.y = pt.v;
02247         return (PtInRect (&winrect, winpoint));
02248     #endif
02249     } /*pointinrect*/
02250 
02251 #if !flruntime
02252 
02253 void scrollrect (Rect r, short dh, short dv) {
02254     
02255     /*
02256     a front end for the Macintosh routine that scrolls a rectangle of pixels.
02257 
02258     5.0b9 dmb: use ScrollDC's region to handle window's true vis rgn
02259     */
02260     
02261     register hdlregion rgn;
02262     
02263 #ifdef MACVERSION
02264     rgn = NewRgn ();
02265     
02266     /*7.1b19 PBS: Call QDerror: you're supposed to check. Plus Eric Soroos is getting crashes in ScrollRect I can't explain.*/
02267 
02268     if (QDError () != noErr) 
02269         return;
02270         
02271     ScrollRect (&r, dh, dv, rgn);
02272     
02273     #if TARGET_API_MAC_CARBON == 1
02274     //InvalWindowRgn(GetFrontWindowOfClass(kAllWindowClasses, false), rgn);
02275     {
02276     WindowRef w;    
02277     CGrafPtr thePort = GetQDGlobalsThePort();
02278     
02279     w = GetWindowFromPort (thePort);
02280         
02281     InvalWindowRgn (w, rgn);
02282     }
02283     
02284     #else
02285     InvalRgn (rgn);
02286     #endif
02287     DisposeRgn (rgn);
02288 #endif
02289     
02290 #ifdef WIN95VERSION
02291     RECT winrect, updaterect, cliprect, smashedrect;
02292     
02293     recttowinrect (&r, &winrect);
02294     smashedrect = winrect;
02295     
02296     if (dv > 0) {
02297         winrect.bottom -= dv;
02298         
02299         smashedrect.bottom = r.top + dv;
02300         }
02301     else {
02302         winrect.top -= dv;
02303         
02304         if (dv)
02305             smashedrect.top = r.bottom + dv;
02306         }
02307 
02308     if (dh > 0) {
02309         winrect.right -= dh;
02310 
02311         smashedrect.right = r.left + dh;
02312         }
02313     else {
02314         winrect.left -= dh;
02315 
02316         if (dh)
02317             smashedrect.left = r.right + dh;
02318         }
02319     
02320     rgn = CreateRectRgn (r.left, r.top, r.right, r.bottom); // default update region
02321     
02322     if (winrect.bottom > winrect.top && winrect.right > winrect.left) {
02323         
02324         GetClipBox (currentportDC, &cliprect);
02325         
02326         ScrollDC (currentportDC, dh, dv, &winrect, &cliprect, rgn, &updaterect);
02327         }
02328     
02329     InvalidateRgn (currentport, rgn, false); // region calc'ed by ScrollDC
02330     
02331     DeleteObject (rgn);
02332 
02333     InvalidateRect (currentport, &smashedrect, false); // region we know to need painting
02334 #endif
02335 
02336     } /*scrollrect*/
02337 
02338 
02339 void scrollrectvert (Rect r, short dv) {
02340     
02341     scrollrect (r, 0, dv);
02342     } /*scrollrectvert*/
02343     
02344 
02345 void scrollrecthoriz (Rect r, short dh) {
02346     
02347     scrollrect (r, dh, 0);
02348     } /*scrollrecthoriz*/
02349 
02350 
02351 void unionrect (Rect r1, Rect r2, Rect *runion) {
02352 
02353     /*
02354     calculates the smallest rectangle which encloses both input rectangles. 
02355     It works correctly even if one of the source rectangles is also the 
02356     destination.
02357     */
02358 
02359     #ifdef MACVERSION   
02360         UnionRect (&r1, &r2, runion);
02361     #endif
02362     
02363     #ifdef WIN95VERSION
02364         RECT winrect1, winrect2, windestrect;
02365 
02366         recttowinrect (&r1, &winrect1);
02367         recttowinrect (&r2, &winrect2);
02368 
02369         UnionRect (&windestrect, &winrect1, &winrect2);
02370 
02371         winrecttorect (&windestrect, runion);
02372     #endif
02373     } /*unionrect*/
02374     
02375     
02376 boolean intersectrect (Rect r1, Rect r2, Rect *rintersection) {
02377 
02378     /*
02379     calculates the rectangle that is the intersection of the two input 
02380     rectangles, and returns true if they indeed intersect or false if they do not. 
02381     rectangles that touch at a line or a point are not considered intersecting, 
02382     because their intersection rectangle (really, in this case, an intersection 
02383     line or point) does not enclose any bits on the bitMap. 
02384     */
02385 #ifdef MACVERSION   
02386     return (SectRect (&r1, &r2, rintersection));
02387 #endif
02388 #ifdef WIN95VERSION
02389     RECT winrect1, winrect2, windestrect;
02390     boolean res;
02391 
02392     recttowinrect (&r1, &winrect1);
02393     recttowinrect (&r2, &winrect2);
02394 
02395     res = IntersectRect (&windestrect, &winrect1, &winrect2);
02396 
02397     winrecttorect (&windestrect, rintersection);
02398 
02399     return (res);
02400 #endif
02401     } /*intersectrect*/
02402 
02403 
02404 void getdesktopbounds (Rect *r) {
02405     
02406     /*
02407     the QuickDraw global GrayRgn encloses the entire desktop, the
02408     concatenation of all monitors attached to the system.
02409     
02410     call this routine when you want to limit a rectangle not to the
02411     current monitor, but to the entire desktop.
02412     */
02413 #ifdef MACVERSION
02414     //Code change by Timothy Paustian Monday, May 1, 2000 9:57:24 PM
02415     //Changed to Opaque call for Carbon
02416     //This is probably not the best way to do this, but it works.
02417     //I could probably remove the #if #else stuff this is an old call.
02418     #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
02419     RgnHandle   grayRgn;
02420     grayRgn = GetGrayRgn();
02421     GetRegionBounds(grayRgn, r);
02422     #else
02423     //old code
02424     *r = (**LMGetGrayRgn ()).rgnBBox;
02425     #endif
02426 #endif
02427 
02428 #ifdef WIN95VERSION
02429 /*
02430 //Use GetSystemMetrics
02431     r->top = 0;
02432     r->left = 0;
02433     r->right = GetSystemMetrics (SM_CXFULLSCREEN);
02434     r->bottom = GetSystemMetrics (SM_CYFULLSCREEN);
02435 */
02436     getlocalwindowrect (shellframewindow, r);
02437 
02438     localtoglobalrect (shellframewindow, r);
02439     
02440     (*r).bottom -= getstatusbarheight();  // 2006-03-28 SMD
02441 #endif
02442     } /*getdesktopbounds*/
02443 
02444 
02445 static boolean constraintorect (Rect *rconstrained, Rect rcontains, boolean flcenter) {
02446     
02447     /*
02448     9/15/91 dmb: make sure that rconstrained fits within rcontains.
02449     
02450     if flcenter is true, center the window along any axis that needs 
02451     constraint. otherwise, just move the rect enough to get it inside.
02452     */
02453     
02454     Rect r;
02455     Rect rcentered;
02456     short dh = 0;
02457     short dv = 0;
02458     
02459     r = *rconstrained; /*copy into local*/
02460     
02461     /*first, limit size to size of screen*/
02462     
02463     r.right = min (r.right, r.left + (rcontains.right - rcontains.left));
02464     
02465     r.bottom = min (r.bottom, r.top + (rcontains.bottom - rcontains.top));
02466     
02467     /*now, if repositioning is necessary, center in that dimension*/
02468     
02469     rcentered = r;
02470     
02471     centerrect (&rcentered, rcontains);
02472     
02473     if (r.left < rcontains.left) {
02474         
02475         if (flcenter)
02476             dh = rcentered.left - r.left;
02477         else
02478             dh = rcontains.left - r.left;
02479         }
02480     else if (r.right > rcontains.right) {
02481         
02482         if (flcenter)
02483             dh = rcentered.right - r.right;
02484         else
02485             dh = rcontains.right - r.right;
02486         }
02487     
02488     if (r.top < rcontains.top) {
02489         
02490         if (flcenter)
02491             dv = rcentered.top - r.top;
02492         else
02493             dv = rcontains.top - r.top;
02494         }
02495     else if (r.bottom > rcontains.bottom) {
02496         
02497         if (flcenter)
02498             dv = rcentered.bottom - r.bottom;
02499         else
02500             dv = rcontains.bottom - r.bottom;
02501         }
02502     
02503     offsetrect (&r, dh, dv);
02504     
02505     /*
02506     r.left = max (r.left, rcontains.left);
02507     
02508     r.right = min (r.right, rcontains.right);
02509     
02510     r.top = max (r.top, rcontains.top);
02511     
02512     r.bottom = min (r.bottom, rcontains.bottom);
02513     
02514     r.bottom = max (r.bottom, r.top);
02515     */
02516     
02517     if (equalrects (*rconstrained, r))
02518         return (false);
02519     
02520     *rconstrained = r; /*copy back to parameter*/
02521     
02522     return (true);
02523     } /*constraintorect*/
02524 
02525 
02526 static void accountfortitlebar (WindowPtr w, Rect *rconstrain) {
02527 
02528     /*
02529     if w is a window with a titlebar, tighten the contraining rect to 
02530     account for the titlebar's height
02531     */
02532     #ifdef MACVERSION   
02533         //Code change by Timothy Paustian Monday, May 1, 2000 10:10:10 PM
02534         //Changed to Opaque call for Carbon
02535         short variant = 0;
02536         //Code change by Timothy Paustian Wednesday, May 3, 2000 10:08:46 PM
02537         //This is sometimes called with nil, we have to check, for this.
02538         if(w != nil)
02539             variant = GetWVariant (w);
02540             
02541         if ((variant == documentProc) || (variant > altDBoxProc))
02542             (*rconstrain).top += doctitlebarheight;
02543         /*
02544         old code
02545         register WindowPeek wpeek = (WindowPeek) w;
02546         
02547         if (wpeek != nil) {
02548             
02549             short variant = GetWVariant (w);
02550             
02551             if ((variant == documentProc) || (variant > altDBoxProc))
02552                 (*rconstrain).top += doctitlebarheight;
02553             
02554             %*
02555             titleheight = (**(*wpeek).contRgn).rgnBBox.top - (**(*wpeek).strucRgn).rgnBBox.top;
02556             
02557             (*rconstrain).top += titleheight;
02558             */
02559             //}*/
02560     #endif
02561 
02562     #ifdef WIN95VERSION
02563         #define titlebarheight 20
02564 
02565         (*rconstrain).top += titlebarheight;
02566     #endif
02567     } /*accountfortitlebar*/
02568 
02569 
02570 boolean constraintodesktop (WindowPtr w, Rect *rparam) {
02571     
02572     /*
02573     make sure the rect fits within the desktop of the machine we're running on.
02574     
02575     12/28/90 dmb: don't add titlebarheight to top.  make sure bottom doesn't 
02576     end up above top
02577     
02578     9/27/91 dmb: title bar height is now accounted for by taking windowptr 
02579     parameter and calling accountfortitlebar.
02580     */
02581     
02582     Rect rdesktop;
02583     
02584     getdesktopbounds (&rdesktop);
02585     
02586     accountfortitlebar (w, &rdesktop);
02587     
02588     return (constraintorect (rparam, rdesktop, false));
02589     } /*constraintodesktop*/
02590 
02591 
02592 boolean constraintoscreenbounds (WindowPtr w, boolean flcurrentscreen, Rect *rparam) {
02593     
02594     /*
02595     9/15/91 dmb: make sure the rect fits within the screen that is occupies
02596     
02597     2.1b6 dmb: added flcurrentscreen parameter. if true, constrain to bounds 
02598     of the screen the window is actually on, like we originally did. if false, 
02599     contstrain to the screen containing rparam, as we've been doing 
02600     more recently.
02601     */
02602     
02603     Rect r;
02604     Rect rscreen;
02605     
02606     if (flcurrentscreen) { /*use its portrect*/
02607         
02608         getglobalwindowrect (w, &r);
02609         
02610         getwindowscreenbounds (&r, &rscreen);
02611         }
02612     else
02613         getwindowscreenbounds (rparam, &rscreen);
02614     
02615     accountfortitlebar (w, &rscreen);
02616     
02617     /***insetrect (&rscreen, 3, 3); %*an aesthetic border of desktop*/
02618     
02619     return (constraintorect (rparam, rscreen, false)); /*4.1b7 dmb: flcenter parm was true*/
02620     } /*constraintoscreenbounds*/
02621 
02622 #ifdef MACVERSION
02623 boolean pushdesktopport (CGrafPtr port) {
02624     
02625     /*
02626     call this when you want to draw directly to the whole desktop, regardless
02627     of how many monitors there are.
02628     
02629     it must be balanced with a call to popdesktopport.
02630     
02631     it returns false if it was unable to set up the port, in which case the
02632     caller should **not** call popdesktopport, and should assume that he cannot
02633     draw on the desktop.
02634     
02635     12/28/90 dmb: original version copied the GrayRgn to a local, and then
02636     assigned to the visRgn, without disposing the original (stranding a heap 
02637     block).  since OpenPort isn't preflighted, there's no point in creating an 
02638     intermediate copy of the GrayRgn anyway, so we copy directly to the visRgn
02639     */
02640     
02641     //Code change by Timothy Paustian Monday, May 1, 2000 10:12:02 PM
02642     //Changed to Opaque call for Carbon
02643     //Using this whole routine may be a problem. Check to see if it is even used.
02644     register CGrafPtr p = port;
02645     hdlregion grayrgn;
02646     Rect        grayRect;
02647         
02648     pushport (nil); /*save current port, don't SetPort*/
02649     
02650     #if TARGET_API_MAC_CARBON == 1
02651      p = CreateNewPort();
02652     #else
02653     OpenPort (p); /*also makes it the current port*/
02654     #endif
02655     grayrgn = GetGrayRgn ();
02656     
02657     #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
02658     SetPortVisibleRegion(p, grayrgn);
02659     GetRegionBounds(grayrgn, &grayRect);
02660     SetPortBounds(p, &grayRect);
02661     #else
02662     #pragma unused(grayRect)
02663     //old code
02664     CopyRgn (grayrgn, (*p).visRgn); /*make visRgn cover entire desktop*/
02665     
02666     (*p).portRect = (**LMGetGrayRgn ()).rgnBBox;
02667     #endif
02668     
02669     return (true);
02670     } /*pushdesktopport*/
02671 
02672 
02673 void popdesktopport (CGrafPtr port) {
02674     
02675     //Code change by Timothy Paustian Thursday, July 20, 2000 4:27:05 PM
02676     //pop this port off the stack, then dispose of it.
02677     popport ();
02678     //Code change by Timothy Paustian Friday, June 16, 2000 2:51:11 PM
02679     //Changed to Opaque call for Carbon
02680     #if TARGET_API_MAC_CARBON == 1
02681     DisposePort(port);
02682     #else   
02683     ClosePort (port);
02684     #endif
02685         
02686     
02687     } /*popdesktopport*/
02688 #endif
02689 
02690 
02691 void getmainscreenrect (Rect *r) {
02692     
02693     /*
02694     returns the rectangle on the user's main screen rect, minus the height
02695     of the menubar.
02696     */
02697     
02698     getcurrentscreenbounds (r);
02699     
02700     /*
02701     (*r).top += getmenubarheight ();
02702     */
02703     } /*getmainscreenrect*/
02704     
02705 
02706 void getsystemoriginrect (Rect *r) {
02707 
02708     /*
02709     when you want to zoom something from the system menu, get the source
02710     rectangle from us.
02711     */
02712     
02713     register short h, v;
02714     Rect rbounds;
02715     #ifdef WIN95VERSION
02716         RECT winrect;
02717     #endif
02718     
02719     getcurrentscreenbounds (&rbounds);
02720     
02721     h = rbounds.left;
02722     
02723     v = rbounds.top;
02724     
02725     /*
02726     v = getmenubarheight ();
02727     */
02728     
02729     #ifdef MACVERSION
02730         SetRect (r, h, v, h, v); /*approximate location of Apple menu*/
02731     #endif
02732     #ifdef WIN95VERSION
02733         SetRect (&winrect, h, v, h, v);
02734         winrecttorect (&winrect, r);
02735     #endif
02736     } /*getsystemoriginrect*/
02737 
02738 
02739 static short maxdepth (Rect *r) {
02740     
02741     /*
02742     5.0b8 dmb: fixed Windows vesion
02743     */
02744 
02745     #ifdef MACVERSION   
02746         GDHandle hdldevice;
02747         
02748         if (!systemhascolor ())
02749             return (1);
02750         
02751         hdldevice = GetMaxDevice (r);
02752         
02753         if (hdldevice == nil)
02754             return (1);
02755         
02756         return ((**(**hdldevice).gdPMap).pixelSize);
02757     #endif
02758 
02759     #ifdef WIN95VERSION
02760         HDC hdc;
02761         short depth;
02762         
02763         hdc = GetDC(GetTopWindow(NULL));
02764         
02765         if ((GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE) != 0)
02766             depth = GetDeviceCaps (hdc, COLORRES);
02767         else
02768             depth = 4;
02769 
02770         ReleaseDC (GetTopWindow(NULL), hdc);
02771         
02772         return (depth);
02773     #endif
02774     } /*maxdepth*/
02775 
02776 
02777 boolean colorenabled (void) {
02778     
02779     /*
02780     2.1b6 dmb: take rect in which to test maxdepth
02781     */
02782     
02783     if (!systemhascolor ())
02784         return (false);
02785     
02786     #ifdef MACVERSION
02787         //Code change by Timothy Paustian Friday, June 9, 2000 10:28:39 PM
02788         //Changed to Opaque call for Carbon
02789         #if TARGET_API_MAC_CARBON == 1
02790         {
02791         BitMap  screenBits;
02792         GetQDGlobalsScreenBits(&screenBits);
02793         return (maxdepth(&(screenBits).bounds) > 1);
02794         }
02795         #else
02796         return (maxdepth (&quickdrawglobal (screenBits).bounds) > 1);
02797         #endif
02798     #endif
02799     #ifdef WIN95VERSION
02800         return (maxdepth (NULL) > 1);
02801     #endif
02802     } /*colorenabled*/
02803 
02804 
02805 short iscolorport (CGrafPtr pport) {
02806 
02807     #ifdef MACVERSION
02808         //Code change by Timothy Paustian Monday, May 1, 2000 10:17:59 PM
02809         //Changed to Opaque call for Carbon
02810         #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
02811         return IsPortColor(pport);
02812         #else
02813         //old code
02814         return ((*(CGrafPtr) pport).portVersion < 0);
02815         #endif
02816     #endif
02817     #ifdef WIN95VERSION
02818         return (true);
02819     #endif
02820     } /*iscolorport*/
02821 
02822 
02823 void fillcolorrect (Rect r, short idppat) {
02824 
02825     #ifdef MACVERSION   
02826         PixPatHandle hppat = GetPixPat (idppat);
02827         
02828         FillCRect (&r, hppat);
02829         
02830         DisposePixPat (hppat);
02831     #endif
02832 
02833     #ifdef WIN95VERSION
02834         RECT winrect;
02835         HBRUSH hBrush;
02836         HBITMAP hBitmap;
02837 
02838         hBitmap = LoadBitmap (hInst, MAKEINTRESOURCE(idppat));
02839         hBrush = CreatePatternBrush (hBitmap);
02840         recttowinrect (&r, &winrect);
02841 
02842         FillRect (getcurrentDC(), &winrect, hBrush);
02843 
02844         DeleteObject (hBrush);
02845         DeleteObject (hBitmap);
02846     #endif
02847     } /*fillcolorrect*/
02848 
02849 
02850 /*
02851 static boolean getclut (short resid, CTabHandle *hdlctab) {
02852     
02853     Handle hdata;
02854     
02855     *hdlctab = nil;
02856     
02857     hdata = GetResource ('clut', resid);
02858     
02859     if (hdata == nil)
02860         return (false);
02861     
02862     *hdlctab = (CTabHandle) hdata;
02863     
02864     return (true);
02865     } %*getclut*/
02866 
02867 /*
02868 static boolean getcolorfromindex (short index, RGBColor *rgb) {
02869 
02870     CTabHandle hctab;
02871     
02872     hctabl = GetCTable (128);
02873     
02874     if (hctab == nil)
02875         return (false);
02876         
02877     %*
02878     if (!getclut (128, &hctab))
02879         return (false);
02880     %/
02881     
02882     *rgb = (**hctab).ctTable [index].rgb;
02883     
02884     return (true);
02885     } %*getcolorfromindex*/
02886 
02887 #endif /*flruntime*/
02888 
02889 
02890 boolean systemhascolor (void) {
02891 
02892     #ifdef MACVERSION
02893         long templong;
02894         if (!gestalt (gestaltQuickdrawVersion, &templong))
02895             return (false);
02896         
02897         return (templong >= gestalt8BitQD);
02898     #endif
02899     #ifdef WIN95VERSION
02900         return (true);  //8 bit color required for windows...
02901     #endif
02902     } /*systemhascolor*/
02903 
02904 
02905 boolean rectinregion (Rect r, hdlregion rgn) {
02906 
02907     #ifdef MACVERSION
02908         return (RectInRgn (&r, rgn));
02909     #endif
02910 
02911     #ifdef WIN95VERSION
02912         RECT winrect;
02913 
02914         recttowinrect (&r, &winrect);
02915 
02916         return (RectInRegion (rgn, &winrect));
02917     #endif
02918     } /*rectinregion*/
02919 
02920 
02921 void initquickdraw (void) {
02922     
02923     /*
02924     by pre-allocating regions for the clip stack, and a scratch region, 
02925     we reduce heap management overhead for push/popclip operations
02926     
02927     2.1b4 dmb: added opening of a scratchport. since we always push & pop 
02928     ports, this ensures that when nothing is pushed, a valid port is still 
02929     established. avoids crashes. even better is to call "pushscratchport" 
02930     in places where a port is needed, and no window is appropriate.
02931 
02932     2002-11-11 AR: Added asserts to make sure the C compiler chose the
02933     proper byte alignment for the diskrect and diskrgb structs.
02934     If it did not, we would end up corrupting any database files we saved.
02935     */
02936     
02937     register short ix;
02938 
02939     assert (sizeof(diskrect) == 8);
02940     
02941     assert (sizeof(diskrgb) == 6);
02942     
02943     #ifdef MACVERSION
02944         for (ix = 0; ix < ctclip; ix++)
02945             clipstack [ix] = NewRgn ();
02946         
02947         scratchrgn = NewRgn ();
02948         //Code change by Timothy Paustian Friday, May 5, 2000 9:55:41 PM
02949         //I need to allocate the memory for the scratch port since it is
02950         //now a pointer. Make sure this is cool with Andre
02951         //This is creating a memory leak but it only gets called once.
02952         #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
02953         scratchport = CreateNewPort();
02954         #else
02955         scratchport = NewPtr(sizeof(CGrafPort));
02956         OpenPort (scratchport);
02957         #endif
02958     #endif
02959 
02960     #ifdef WIN95VERSION
02961         for (ix = 0; ix < ctclip; ix++)
02962             clipstack [ix] = CreateRectRgn (0,0,1,1);
02963         
02964         scratchrgn = CreateRectRgn (0,0,1,1);
02965         currentwindowbrush = GetStockObject (BLACK_BRUSH);
02966         gPenPositionX = 0;
02967         gPenPositionY = 0;
02968     #endif
02969     } /*initquickdraw*/
02970 
02971 
02972 void diskrecttorect (diskrect *rdisk, Rect *r) {
02973 
02974     diskrect rcopy = *rdisk;
02975 
02976     disktomemshort (rcopy.left);
02977     disktomemshort(rcopy.top);
02978     disktomemshort(rcopy.right);
02979     disktomemshort(rcopy.bottom);
02980 
02981     (*r).left = rcopy.left;
02982     
02983     (*r).top = rcopy.top;
02984     
02985     (*r).right = rcopy.right;
02986     
02987     (*r).bottom = rcopy.bottom;
02988     } /*diskrecttorect*/
02989 
02990 
02991 void recttodiskrect (Rect *r, diskrect *rdisk) {
02992 
02993     (*rdisk).left = (short) (*r).left;
02994     
02995     (*rdisk).top = (short) (*r).top;
02996     
02997     (*rdisk).right = (short) (*r).right;
02998     
02999     (*rdisk).bottom = (short) (*r).bottom;
03000 
03001     memtodiskshort (rdisk->left);
03002     memtodiskshort(rdisk->top);
03003     memtodiskshort(rdisk->right);
03004     memtodiskshort(rdisk->bottom);
03005     } /*recttodiskrect*/
03006 
03007 
03008 void diskrgbtorgb (diskrgb *rgbdisk, RGBColor *r) {
03009 
03010     (*r).red = (*rgbdisk).red;
03011     
03012     (*r).green = (*rgbdisk).green;
03013     
03014     (*r).blue = (*rgbdisk).blue;
03015 
03016     disktomemshort(r->red);
03017     disktomemshort(r->green);
03018     disktomemshort(r->blue);
03019     } /*diskrgbtorgb*/
03020 
03021 
03022 void rgbtodiskrgb (RGBColor *r, diskrgb *rgbdisk) {
03023 
03024     (*rgbdisk).red = (short) (*r).red;
03025     
03026     (*rgbdisk).green = (short) (*r).green;
03027     
03028     (*rgbdisk).blue = (short) (*r).blue;
03029 
03030     memtodiskshort(rgbdisk->red);
03031     memtodiskshort(rgbdisk->green);
03032     memtodiskshort(rgbdisk->blue);
03033     } /*rgbtodiskrgb*/
03034 
03035 

Generated on Wed May 31 18:20:00 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6