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);
74 if(min
&& hints
->min_set
){
75 w
=maxof(w
, hints
->min_width
);
76 h
=maxof(h
, hints
->min_height
);
79 if(hints
->no_constrain
&& !override_no_constrain
){
89 correct_aspect(tw
, th
, hints
, &tw
, &th
);
93 tw
=(tw
/hints
->width_inc
)*hints
->width_inc
;
95 th
=(th
/hints
->height_inc
)*hints
->height_inc
;
102 w
=minof(w
, hints
->max_width
);
103 h
=minof(h
, hints
->max_height
);
114 /*{{{ X size hints sanity adjustment */
117 void xsizehints_sanity_adjust(XSizeHints
*hints
)
119 if(!(hints
->flags
&PMinSize
)){
120 if(hints
->flags
&PBaseSize
){
121 hints
->min_width
=hints
->base_width
;
122 hints
->min_height
=hints
->base_height
;
129 hints
->min_width
=maxof(hints
->min_width
, 0);
130 hints
->min_height
=maxof(hints
->min_height
, 0);
132 if(!(hints
->flags
&PBaseSize
) || hints
->base_width
<0)
133 hints
->base_width
=hints
->min_width
;
134 if(!(hints
->flags
&PBaseSize
) || hints
->base_height
<0)
135 hints
->base_height
=hints
->min_height
;
137 if(hints
->flags
&PMaxSize
){
138 hints
->max_width
=maxof(hints
->max_width
, hints
->min_width
);
139 hints
->max_height
=maxof(hints
->max_height
, hints
->min_height
);
142 hints
->flags
|=(PBaseSize
|PMinSize
);
144 if(hints
->flags
&PResizeInc
){
145 if(hints
->width_inc
<=0 || hints
->height_inc
<=0){
146 warn(TR("Invalid client-supplied width/height increment."));
147 hints
->flags
&=~PResizeInc
;
151 if(hints
->flags
&PAspect
){
152 if(hints
->min_aspect
.x
<=0 || hints
->min_aspect
.y
<=0 ||
153 hints
->min_aspect
.x
<=0 || hints
->min_aspect
.y
<=0){
154 warn(TR("Invalid client-supplied aspect-ratio."));
155 hints
->flags
&=~PAspect
;
159 if(!(hints
->flags
&PWinGravity
))
160 hints
->win_gravity
=ForgetGravity
;
167 /*{{{ xsizehints_adjust_for */
170 void sizehints_adjust_for(WSizeHints
*hints
, WRegion
*reg
)
172 WSizeHints tmp_hints
;
174 region_size_hints(reg
, &tmp_hints
);
176 if(tmp_hints
.min_set
){
179 hints
->min_width
=tmp_hints
.min_width
;
180 hints
->min_height
=tmp_hints
.min_height
;
182 hints
->min_width
=maxof(hints
->min_width
,
183 tmp_hints
.min_width
);
184 hints
->min_height
=maxof(hints
->min_height
,
185 tmp_hints
.min_height
);
189 if(tmp_hints
.max_set
&& hints
->max_set
){
190 hints
->max_width
=maxof(hints
->max_width
,
191 tmp_hints
.max_width
);
192 hints
->max_height
=maxof(hints
->max_height
,
193 tmp_hints
.max_height
);
195 hints
->max_set
=FALSE
;
203 /*{{{ account_gravity */
206 int xgravity_deltax(int gravity
, int left
, int right
)
210 if(gravity
==StaticGravity
|| gravity
==ForgetGravity
){
212 }else if(gravity
==NorthWestGravity
|| gravity
==WestGravity
||
213 gravity
==SouthWestGravity
){
215 }else if(gravity
==NorthEastGravity
|| gravity
==EastGravity
||
216 gravity
==SouthEastGravity
){
217 /* geom->x=geom->w+geom->x-(geom->w+woff) */
219 }else if(gravity
==CenterGravity
|| gravity
==NorthGravity
||
220 gravity
==SouthGravity
){
221 /* geom->x=geom->x+geom->w/2-(geom->w+woff)/2 */
228 int xgravity_deltay(int gravity
, int top
, int bottom
)
232 if(gravity
==StaticGravity
|| gravity
==ForgetGravity
){
234 }else if(gravity
==NorthWestGravity
|| gravity
==NorthGravity
||
235 gravity
==NorthEastGravity
){
237 }else if(gravity
==SouthWestGravity
|| gravity
==SouthGravity
||
238 gravity
==SouthEastGravity
){
239 /* geom->y=geom->y+geom->h-(geom->h+hoff) */
241 }else if(gravity
==CenterGravity
|| gravity
==WestGravity
||
242 gravity
==EastGravity
){
243 /* geom->y=geom->y+geom->h/2-(geom->h+hoff)/2 */
250 void xgravity_translate(int gravity
, WRegion
*reg
, WRectangle
*geom
)
252 int top
=0, left
=0, bottom
=0, right
=0;
255 root
=region_rootwin_of(reg
);
256 region_rootpos(reg
, &left
, &top
);
257 right
=REGION_GEOM(root
).w
-left
-REGION_GEOM(reg
).w
;
258 bottom
=REGION_GEOM(root
).h
-top
-REGION_GEOM(reg
).h
;
260 geom
->x
+=xgravity_deltax(gravity
, left
, right
);
261 geom
->y
+=xgravity_deltay(gravity
, top
, bottom
);
271 void xsizehints_to_sizehints(const XSizeHints
*xh
, WSizeHints
*hints
)
273 hints
->max_width
=xh
->max_width
;
274 hints
->max_height
=xh
->max_height
;
275 hints
->min_width
=xh
->min_width
;
276 hints
->min_height
=xh
->min_height
;
277 hints
->base_width
=xh
->base_width
;
278 hints
->base_height
=xh
->base_height
;
279 hints
->width_inc
=xh
->width_inc
;
280 hints
->height_inc
=xh
->height_inc
;
281 hints
->min_aspect
.x
=xh
->min_aspect
.x
;
282 hints
->min_aspect
.y
=xh
->min_aspect
.y
;
283 hints
->max_aspect
.x
=xh
->max_aspect
.x
;
284 hints
->max_aspect
.y
=xh
->max_aspect
.y
;
286 hints
->max_set
=((xh
->flags
&PMaxSize
)!=0);
287 hints
->min_set
=((xh
->flags
&PMinSize
)!=0);
288 hints
->base_set
=((xh
->flags
&PBaseSize
)!=0);
289 hints
->inc_set
=((xh
->flags
&PResizeInc
)!=0);
290 hints
->aspect_set
=((xh
->flags
&PAspect
)!=0);
291 hints
->no_constrain
=0;
295 void sizehints_clear(WSizeHints
*hints
)
302 hints
->no_constrain
=0;