2 * ion/ioncore/sizehint.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
10 #include <libtu/minmax.h>
20 /*{{{ xsizehints_correct */
23 static void do_correct_aspect(int max_w
, int max_h
, int ax
, int ay
,
30 if(max_h
>0 && h
>max_h
){
36 if(max_w
>0 && w
>max_w
){
47 static void correct_aspect(int max_w
, int max_h
, const WSizeHints
*hints
,
50 if(!hints
->aspect_set
)
53 if(*wret
*hints
->max_aspect
.y
>*hret
*hints
->max_aspect
.x
){
54 do_correct_aspect(max_w
, max_h
,
55 hints
->min_aspect
.x
, hints
->min_aspect
.y
,
59 if(*wret
*hints
->min_aspect
.y
<*hret
*hints
->min_aspect
.x
){
60 do_correct_aspect(max_w
, max_h
,
61 hints
->max_aspect
.x
, hints
->max_aspect
.y
,
67 void sizehints_correct(const WSizeHints
*hints
, int *wp
, int *hp
,
68 bool min
, bool override_no_constrain
)
70 int w
=*wp
, tw
, bw
=(hints
->base_set
? hints
->base_width
: 0);
71 int h
=*hp
, th
, bh
=(hints
->base_set
? hints
->base_height
: 0);
73 if(min
&& hints
->min_set
){
74 w
=maxof(w
, hints
->min_width
);
75 h
=maxof(h
, hints
->min_height
);
78 if(hints
->no_constrain
&& !override_no_constrain
){
88 correct_aspect(tw
, th
, hints
, &tw
, &th
);
92 tw
=(tw
/hints
->width_inc
)*hints
->width_inc
;
94 th
=(th
/hints
->height_inc
)*hints
->height_inc
;
101 w
=minof(w
, hints
->max_width
);
102 h
=minof(h
, hints
->max_height
);
113 /*{{{ X size hints sanity adjustment */
116 void xsizehints_sanity_adjust(XSizeHints
*hints
)
118 if(!(hints
->flags
&PMinSize
)){
119 if(hints
->flags
&PBaseSize
){
120 hints
->min_width
=hints
->base_width
;
121 hints
->min_height
=hints
->base_height
;
128 hints
->min_width
=maxof(hints
->min_width
, 0);
129 hints
->min_height
=maxof(hints
->min_height
, 0);
131 if(!(hints
->flags
&PBaseSize
) || hints
->base_width
<0)
132 hints
->base_width
=hints
->min_width
;
133 if(!(hints
->flags
&PBaseSize
) || hints
->base_height
<0)
134 hints
->base_height
=hints
->min_height
;
136 if(hints
->flags
&PMaxSize
){
137 hints
->max_width
=maxof(hints
->max_width
, hints
->min_width
);
138 hints
->max_height
=maxof(hints
->max_height
, hints
->min_height
);
141 hints
->flags
|=(PBaseSize
|PMinSize
);
143 if(hints
->flags
&PResizeInc
){
144 if(hints
->width_inc
<=0 || hints
->height_inc
<=0){
145 warn(TR("Invalid client-supplied width/height increment."));
146 hints
->flags
&=~PResizeInc
;
150 if(hints
->flags
&PAspect
){
151 if(hints
->min_aspect
.x
<=0 || hints
->min_aspect
.y
<=0 ||
152 hints
->min_aspect
.x
<=0 || hints
->min_aspect
.y
<=0){
153 warn(TR("Invalid client-supplied aspect-ratio."));
154 hints
->flags
&=~PAspect
;
158 if(!(hints
->flags
&PWinGravity
))
159 hints
->win_gravity
=ForgetGravity
;
166 /*{{{ xsizehints_adjust_for */
169 void sizehints_adjust_for(WSizeHints
*hints
, WRegion
*reg
)
171 WSizeHints tmp_hints
;
173 region_size_hints(reg
, &tmp_hints
);
175 if(tmp_hints
.min_set
){
178 hints
->min_width
=tmp_hints
.min_width
;
179 hints
->min_height
=tmp_hints
.min_height
;
181 hints
->min_width
=maxof(hints
->min_width
,
182 tmp_hints
.min_width
);
183 hints
->min_height
=maxof(hints
->min_height
,
184 tmp_hints
.min_height
);
188 if(tmp_hints
.max_set
&& hints
->max_set
){
189 hints
->max_width
=maxof(hints
->max_width
,
190 tmp_hints
.max_width
);
191 hints
->max_height
=maxof(hints
->max_height
,
192 tmp_hints
.max_height
);
194 hints
->max_set
=FALSE
;
202 /*{{{ account_gravity */
205 int xgravity_deltax(int gravity
, int left
, int right
)
209 if(gravity
==StaticGravity
|| gravity
==ForgetGravity
){
211 }else if(gravity
==NorthWestGravity
|| gravity
==WestGravity
||
212 gravity
==SouthWestGravity
){
214 }else if(gravity
==NorthEastGravity
|| gravity
==EastGravity
||
215 gravity
==SouthEastGravity
){
216 /* geom->x=geom->w+geom->x-(geom->w+woff) */
218 }else if(gravity
==CenterGravity
|| gravity
==NorthGravity
||
219 gravity
==SouthGravity
){
220 /* geom->x=geom->x+geom->w/2-(geom->w+woff)/2 */
227 int xgravity_deltay(int gravity
, int top
, int bottom
)
231 if(gravity
==StaticGravity
|| gravity
==ForgetGravity
){
233 }else if(gravity
==NorthWestGravity
|| gravity
==NorthGravity
||
234 gravity
==NorthEastGravity
){
236 }else if(gravity
==SouthWestGravity
|| gravity
==SouthGravity
||
237 gravity
==SouthEastGravity
){
238 /* geom->y=geom->y+geom->h-(geom->h+hoff) */
240 }else if(gravity
==CenterGravity
|| gravity
==WestGravity
||
241 gravity
==EastGravity
){
242 /* geom->y=geom->y+geom->h/2-(geom->h+hoff)/2 */
249 void xgravity_translate(int gravity
, WRegion
*reg
, WRectangle
*geom
)
251 int top
=0, left
=0, bottom
=0, right
=0;
254 root
=region_rootwin_of(reg
);
255 region_rootpos(reg
, &left
, &top
);
256 right
=REGION_GEOM(root
).w
-left
-REGION_GEOM(reg
).w
;
257 bottom
=REGION_GEOM(root
).h
-top
-REGION_GEOM(reg
).h
;
259 geom
->x
+=xgravity_deltax(gravity
, left
, right
);
260 geom
->y
+=xgravity_deltay(gravity
, top
, bottom
);
270 void xsizehints_to_sizehints(const XSizeHints
*xh
, WSizeHints
*hints
)
272 hints
->max_width
=xh
->max_width
;
273 hints
->max_height
=xh
->max_height
;
274 hints
->min_width
=xh
->min_width
;
275 hints
->min_height
=xh
->min_height
;
276 hints
->base_width
=xh
->base_width
;
277 hints
->base_height
=xh
->base_height
;
278 hints
->width_inc
=xh
->width_inc
;
279 hints
->height_inc
=xh
->height_inc
;
280 hints
->min_aspect
.x
=xh
->min_aspect
.x
;
281 hints
->min_aspect
.y
=xh
->min_aspect
.y
;
282 hints
->max_aspect
.x
=xh
->max_aspect
.x
;
283 hints
->max_aspect
.y
=xh
->max_aspect
.y
;
285 hints
->max_set
=((xh
->flags
&PMaxSize
)!=0);
286 hints
->min_set
=((xh
->flags
&PMinSize
)!=0);
287 hints
->base_set
=((xh
->flags
&PBaseSize
)!=0);
288 hints
->inc_set
=((xh
->flags
&PResizeInc
)!=0);
289 hints
->aspect_set
=((xh
->flags
&PAspect
)!=0);
290 hints
->no_constrain
=0;
294 void sizehints_clear(WSizeHints
*hints
)
301 hints
->no_constrain
=0;