Rev 193 | Rev 268 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
259 | daniel-mar | 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 | } |