3 * FvwmButtons, copyright 1996, Jarl Totland
5 * This module, and the entire GoodStuff program, and the concept for
6 * interfacing this module to the Window Manager, are all original work
9 * Copyright 1993, Robert Nation. No guarantees or warantees or anything
10 * are provided or implied in any way whatsoever. Use this program at your
11 * own risk. Permission to use this program for any purpose is given,
12 * as long as the copyright is kept intact.
16 /* This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38 *** Adjust a given width and height to account for the constraints imposed by
40 *** The general algorithm, especially the aspect ratio stuff, is borrowed from
41 *** uwm's CheckConsistency routine.
43 void ConstrainSize (XSizeHints
*hints
, int *widthp
, int *heightp
)
45 #define makemult(a,b) ((b == 1) ? (a) : (((int)((a) / (b))) * (b)))
47 int minWidth
, minHeight
, maxWidth
, maxHeight
, xinc
, yinc
, delta
;
48 int baseWidth
, baseHeight
;
49 int dwidth
= *widthp
, dheight
= *heightp
;
51 if (hints
->flags
& PMinSize
)
53 minWidth
= hints
->min_width
;
54 minHeight
= hints
->min_height
;
55 if (hints
->flags
& PBaseSize
)
57 baseWidth
= hints
->base_width
;
58 baseHeight
= hints
->base_height
;
62 baseWidth
= hints
->min_width
;
63 baseHeight
= hints
->min_height
;
66 else if (hints
->flags
& PBaseSize
)
68 minWidth
= hints
->base_width
;
69 minHeight
= hints
->base_height
;
70 baseWidth
= hints
->base_width
;
71 baseHeight
= hints
->base_height
;
81 if (hints
->flags
& PMaxSize
)
83 maxWidth
= hints
->max_width
;
84 maxHeight
= hints
->max_height
;
91 if (hints
->flags
& PResizeInc
)
93 xinc
= hints
->width_inc
;
94 yinc
= hints
->height_inc
;
103 * First, clamp to min and max values
105 if (dwidth
< minWidth
)
109 if (dheight
< minHeight
)
114 if (dwidth
> maxWidth
)
118 if (dheight
> maxHeight
)
125 * Second, fit to base + N * inc
127 dwidth
= ((dwidth
- baseWidth
) / xinc
* xinc
) + baseWidth
;
128 dheight
= ((dheight
- baseHeight
) / yinc
* yinc
) + baseHeight
;
132 * Third, adjust for aspect ratio
134 #define maxAspectX hints->max_aspect.x
135 #define maxAspectY hints->max_aspect.y
136 #define minAspectX hints->min_aspect.x
137 #define minAspectY hints->min_aspect.y
139 * The math looks like this:
141 * minAspectX dwidth maxAspectX
142 * ---------- <= ------- <= ----------
143 * minAspectY dheight maxAspectY
145 * If that is multiplied out, then the width and height are
146 * invalid in the following situations:
148 * minAspectX * dheight > minAspectY * dwidth
149 * maxAspectX * dheight < maxAspectY * dwidth
153 if (hints
->flags
& PAspect
)
155 if (minAspectX
* dheight
> minAspectY
* dwidth
)
158 minAspectX
* dheight
/ minAspectY
- dwidth
,
160 if (dwidth
+ delta
<= maxWidth
)
167 dheight
- minAspectY
*dwidth
/minAspectX
,
169 if (dheight
- delta
>= minHeight
)
176 if (maxAspectX
* dheight
< maxAspectY
* dwidth
)
179 dwidth
* maxAspectY
/ maxAspectX
- dheight
,
181 if (dheight
+ delta
<= maxHeight
)
188 dwidth
- maxAspectX
*dheight
/maxAspectY
,
190 if (dwidth
- delta
>= minWidth
)