2 * ion/ioncore/sizehint.c
4 * Copyright (c) Tuomo Valkonen 1999-2007.
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;