Subversion Repositories filter_foundry

Rev

Rev 193 | Rev 268 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.         This file is part of a common library
  3.     Copyright (C) 1990-2006 Toby Thain, toby@telegraphics.com.au
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by  
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License  
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18. */
  19.  
  20. #include <macwindows.h>
  21. #include <osutils.h>
  22.  
  23. #include "carbonstuff.h"
  24. #include "wind.h"
  25. #include "qd.h"
  26.  
  27. pascal void dominant_device_dldp(short depth, short deviceFlags,
  28.                                                                  GDHandle targetDevice, long userData);
  29.  
  30. Rect main_device_rect(void){
  31.         Rect r;
  32.         BitMap bm;
  33. // screenBits.bounds may be correct for both colour and B&W QuickDraw systems
  34. // another possibility: portRect of window manager's port
  35. //      r = has_colour_QD() /* && GetMainDevice() */ ? (*GetMainDevice())->gdRect : SAFE_QD(screenBits).bounds;
  36.         GetQDGlobalsScreenBits(&bm);
  37.         r = bm.bounds; //SAFE_QD(screenBits).bounds;
  38.         r.top += GetMBarHeight();
  39.         return r;
  40. }
  41.  
  42. /* "The dialog or alert window should appear with one-fifth of the vertical desktop area
  43.     (not including the menu bar) above it and the rest below the window." */
  44.  
  45. void centre_rect_in(Rect*r,Rect*s){
  46.         SetRect(r,0,0,r->right - r->left,r->bottom - r->top);
  47.         OffsetRect(r,(s->left + s->right - r->right)/2,(s->top + s->bottom - r->bottom)/5);
  48. }
  49.  
  50. void centre_rect(Rect*r){
  51.         Rect s = main_device_rect();
  52.         centre_rect_in(r,&s);
  53. }
  54.  
  55. void global_wind_rect(WindowPtr w,Rect*r){ GrafPtr gp;
  56.         GetPort(&gp);
  57.         SetPortWindowPort(w);
  58.         GetWindowPortBounds(w,r); //*r = w->portRect;
  59.         rect2g(r);
  60.         SetPort(gp);
  61. }
  62.  
  63. void get_struc_bbox(WindowPtr w,Rect*r){ enum{K=0x4000};
  64.         RgnHandle rgn = NewRgn();
  65.        
  66.         if(MacIsWindowVisible(w)){ //((WindowPeek)w)->visible)
  67.                 GetWindowRegion(w,kWindowStructureRgn,rgn);
  68.                 GetRegionBounds(rgn,r); //*r = (*((WindowPeek)w)->strucRgn)->rgnBBox;
  69.         }else{ Rect s;
  70.                 global_wind_rect(w,&s);
  71.                 MoveWindow(w,s.left,s.top+K,false);
  72.                 ShowHide(w,true);
  73.                 GetWindowRegion(w,kWindowStructureRgn,rgn);
  74.                 GetRegionBounds(rgn,r); //*r = (*((WindowPeek)w)->strucRgn)->rgnBBox;
  75.                 ShowHide(w,false);
  76.                 MoveWindow(w,s.left,s.top,false);
  77.                 OffsetRect(r,0,-K);
  78.         }
  79. }
  80.  
  81. void centre_window(WindowPtr w){ Rect r,s,t;
  82.         global_wind_rect(w,&r);
  83.         get_struc_bbox(w,&s);
  84.         t = s;
  85.         centre_rect(&t);
  86.         MoveWindow(w,t.left+(r.left-s.left),t.top+(r.top-s.top),false);
  87. }
  88.  
  89. void centre_window_in(WindowPtr w,Rect*rr){ Rect r,s,t;
  90.         global_wind_rect(w,&r);
  91.         get_struc_bbox(w,&s);
  92.         t = s;
  93.         centre_rect_in(&t,rr);
  94.         MoveWindow(w,t.left+(r.left-s.left),t.top+(r.top-s.top),false);
  95. }
  96.  
  97. void centre_window_on_parent(WindowPtr w,WindowPtr parent){
  98.         Rect q,r = dominant_device_rect(parent);
  99.         // if the screen is 13" or smaller, centre on the screen; otherwise on the "parent" window
  100.         if((long)(r.right-r.left)*(r.bottom-r.top) > 640*480L){
  101.                 get_struc_bbox(parent,&q);
  102. //              SectRect(&r,&q,&r); // centre on the part of the parent window that's on the screen
  103.                 // must still handle the case of a parent smaller than the window being centred...
  104.                 // perhaps the best way is to centre on the parent, then pin to the screen
  105.         }
  106.         centre_window_in(w,&r);
  107. }
  108.  
  109. // should use DeviceLoop to enumerate devices
  110.  
  111. typedef struct {
  112.         GDHandle dev;
  113.         Rect wr;
  114.         long g;
  115. } dominant_device_data;
  116.  
  117. pascal void dominant_device_dldp(short depth, short deviceFlags,
  118.                                                                  GDHandle targetDevice, long userData){
  119.         long g=0,a;
  120.         Rect r;
  121.  
  122.         SectRect(&((dominant_device_data*)userData)->wr,&(*targetDevice)->gdRect,&r);
  123.         if(     (a = (long)(r.right-r.left)*(r.bottom-r.top))
  124.                         > ((dominant_device_data*)userData)->g){
  125.                 ((dominant_device_data*)userData)->g = a;
  126.                 ((dominant_device_data*)userData)->dev = targetDevice;
  127.         }
  128. }
  129.  
  130. GDHandle dominant_device(WindowPtr w){
  131.         RgnHandle rgn;
  132.         DeviceLoopDrawingUPP proc = NewDeviceLoopDrawingUPP(dominant_device_dldp);
  133.         dominant_device_data dd;
  134.  
  135.         global_wind_rect(w,&dd.wr);
  136.         dd.dev = GetMainDevice();
  137.         dd.g = 0;
  138.         RectRgn(rgn = NewRgn(),&dd.wr);
  139.         DeviceLoop(rgn, proc, (long)&dd, 0);
  140.         DisposeRgn(rgn);
  141.  
  142.         DisposeDeviceLoopDrawingUPP(proc);
  143.         return dd.dev;
  144. }
  145.  
  146. #if 0
  147. GDHandle dominant_device_old(WindowPtr w){
  148.         long g=0,a;
  149.         GDHandle d,dev = GetMainDevice(); // default, in case it doesn't intersect any
  150.         Rect wr,r;
  151.        
  152.         global_wind_rect(w,&wr);
  153.         for(d=GetDeviceList();d;d=GetNextDevice(d))
  154.                 if(TestDeviceAttribute(d,screenDevice) && TestDeviceAttribute(d,screenActive)){
  155.                         SectRect(&wr,&(*d)->gdRect,&r);
  156.                         if((a = (long)(r.right-r.left)*(r.bottom-r.top)) > g){
  157.                                 g = a;
  158.                                 dev = d;
  159.                         }
  160.                 }
  161.         return dev;
  162. }
  163. #endif
  164.  
  165. Rect dominant_device_rect(WindowPtr w){
  166.         Rect r;
  167.         if(has_colour_QD()){  GDHandle d = dominant_device(w);
  168.                 r = (*d)->gdRect;
  169.                 if(d == GetMainDevice())
  170.                         r.top += GetMBarHeight();
  171.                 return r;
  172.         }else{
  173.                 GetRegionBounds(GetGrayRgn(),&r);
  174.                 return r;
  175.         }
  176. }
  177.  
  178. Rect largest_device_rect(void){
  179.         long g,a;
  180.         GDHandle d,dev;
  181.         Rect dr,*r;
  182.  
  183.         if(has_colour_QD()){           
  184.                 for(d=GetDeviceList(),dev=0,g=0;d;d=GetNextDevice(d))
  185.                         if(TestDeviceAttribute(d,screenDevice) && TestDeviceAttribute(d,screenActive)){
  186.                                 r = &(*d)->gdRect;
  187.                                 if((a = (long)(r->right-r->left)*(r->bottom-r->top)) > g){
  188.                                         g = a;
  189.                                         dev = d;
  190.                                 }
  191.                         }
  192.                 if(dev){
  193.                         dr = (*dev)->gdRect;
  194.                         if(dev == GetMainDevice())
  195.                                 dr.top += GetMBarHeight();
  196.                 }else{
  197.                         BitMap bm;
  198.                         GetQDGlobalsScreenBits(&bm);
  199.                         dr = bm.bounds; //SAFE_QD(screenBits).bounds; // there are no devices
  200.                 }
  201.         }else
  202.                 GetRegionBounds(GetGrayRgn(),&dr);
  203.         return dr;
  204. }
  205.  
  206. void grow_rect(WindowPtr w,Rect*r){
  207.         Rect bounds;
  208.         GetPortBounds((CGrafPtr)w,&bounds);
  209.         BOTRIGHT(*r) = BOTRIGHT(bounds);
  210.         r->left = r->right - (SCROLL_BAR_WIDTH-1);
  211.         r->top = r->bottom - (SCROLL_BAR_WIDTH-1);
  212. }
  213.  
  214. void inval_grow(WindowPtr w){
  215.         Rect r;
  216.         GrafPtr gp;
  217.  
  218.         grow_rect(w,&r);
  219. #if TARGET_CARBON
  220.         InvalWindowRect(w,&r);
  221. #else
  222.         GetPort(&gp);
  223.         SetPort((GrafPtr)GetWindowPort(w)); // should we preserve the current port??
  224.         InvalRect(&r);
  225.         SetPort(gp);
  226. #endif
  227. }
  228.