Spell 'serialize' with a 'z'
[notion.git] / ioncore / sizehint.c
blob784bf5e8483220f412f077bccd451ebb7e2e05d0
1 /*
2 * ion/ioncore/sizehint.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
7 */
9 #include <string.h>
10 #include <libtu/minmax.h>
12 #include "common.h"
13 #include "global.h"
14 #include "region.h"
15 #include "resize.h"
16 #include "sizehint.h"
17 #include "rootwin.h"
20 /*{{{ xsizehints_correct */
23 static void do_correct_aspect(int max_w, int max_h, int ax, int ay,
24 int *wret, int *hret)
26 int w=*wret, h=*hret;
28 if(ax>ay){
29 h=(w*ay)/ax;
30 if(max_h>0 && h>max_h){
31 h=max_h;
32 w=(h*ax)/ay;
34 }else{
35 w=(h*ax)/ay;
36 if(max_w>0 && w>max_w){
37 w=max_w;
38 h=(w*ay)/ax;
42 *wret=w;
43 *hret=h;
47 static void correct_aspect(int max_w, int max_h, const WSizeHints *hints,
48 int *wret, int *hret)
50 if(!hints->aspect_set)
51 return;
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,
56 wret, hret);
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,
62 wret, hret);
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){
79 *wp=w;
80 *hp=h;
81 return;
84 tw=w-bw;
85 th=h-bh;
87 if(tw>=0 && th>=0)
88 correct_aspect(tw, th, hints, &tw, &th);
90 if(hints->inc_set){
91 if(tw>0)
92 tw=(tw/hints->width_inc)*hints->width_inc;
93 if(th>0)
94 th=(th/hints->height_inc)*hints->height_inc;
97 w=tw+bw;
98 h=th+bh;
100 if(hints->max_set){
101 w=minof(w, hints->max_width);
102 h=minof(h, hints->max_height);
105 *wp=w;
106 *hp=h;
110 /*}}}*/
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;
122 }else{
123 hints->min_width=0;
124 hints->min_height=0;
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;
163 /*}}}*/
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){
176 if(!hints->min_set){
177 hints->min_set=TRUE;
178 hints->min_width=tmp_hints.min_width;
179 hints->min_height=tmp_hints.min_height;
180 }else{
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);
193 }else{
194 hints->max_set=FALSE;
199 /*}}}*/
202 /*{{{ account_gravity */
205 int xgravity_deltax(int gravity, int left, int right)
207 int woff=left+right;
209 if(gravity==StaticGravity || gravity==ForgetGravity){
210 return -left;
211 }else if(gravity==NorthWestGravity || gravity==WestGravity ||
212 gravity==SouthWestGravity){
213 /* */
214 }else if(gravity==NorthEastGravity || gravity==EastGravity ||
215 gravity==SouthEastGravity){
216 /* geom->x=geom->w+geom->x-(geom->w+woff) */
217 return -woff;
218 }else if(gravity==CenterGravity || gravity==NorthGravity ||
219 gravity==SouthGravity){
220 /* geom->x=geom->x+geom->w/2-(geom->w+woff)/2 */
221 return -woff/2;
223 return 0;
227 int xgravity_deltay(int gravity, int top, int bottom)
229 int hoff=top+bottom;
231 if(gravity==StaticGravity || gravity==ForgetGravity){
232 return -top;
233 }else if(gravity==NorthWestGravity || gravity==NorthGravity ||
234 gravity==NorthEastGravity){
235 /* */
236 }else if(gravity==SouthWestGravity || gravity==SouthGravity ||
237 gravity==SouthEastGravity){
238 /* geom->y=geom->y+geom->h-(geom->h+hoff) */
239 return -hoff;
240 }else if(gravity==CenterGravity || gravity==WestGravity ||
241 gravity==EastGravity){
242 /* geom->y=geom->y+geom->h/2-(geom->h+hoff)/2 */
243 return -hoff/2;
245 return 0;
249 void xgravity_translate(int gravity, WRegion *reg, WRectangle *geom)
251 int top=0, left=0, bottom=0, right=0;
252 WRootWin *root;
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);
264 /*}}}*/
267 /*{{{ Init */
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)
296 hints->max_set=0;
297 hints->min_set=0;
298 hints->inc_set=0;
299 hints->base_set=0;
300 hints->aspect_set=0;
301 hints->no_constrain=0;
305 /*}}}*/