2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 /* ---------------------------- included header files ---------------------- */
29 /* ---------------------------- local definitions -------------------------- */
31 /* ---------------------------- local macros ------------------------------- */
33 /* ---------------------------- imports ------------------------------------ */
35 /* ---------------------------- included code files ------------------------ */
37 /* ---------------------------- local types -------------------------------- */
39 struct _gravity_offset
44 /* ---------------------------- forward declarations ----------------------- */
46 /* ---------------------------- local variables ---------------------------- */
48 #define STRINGS_PER_DIR 7
49 static char *gravity_dir_optlist
[] = {
50 "-", "N", "North", "Top", "t", "Up", "u",
51 "]", "E", "East", "Right", "r", "Right", "r",
52 "_", "S", "South", "Bottom", "b", "Down", "d",
53 "[", "W", "West", "Left", "l", "Left", "l",
54 "^", "NE", "NorthEast", "TopRight", "tr", "UpRight", "ur",
55 ">", "SE", "SouthEast", "BottomRight", "br", "DownRight", "dr",
56 "v", "SW", "SouthWest", "BottomLeft", "bl", "DownLeft", "dl",
57 "<", "NW", "NorthWest", "TopLeft", "tl", "UpLeft", "ul",
58 ".", "C", "Center", "Centre", NULL
, NULL
, NULL
,
62 /* ---------------------------- exported variables (globals) --------------- */
64 /* ---------------------------- local functions ---------------------------- */
66 /* ---------------------------- interface functions ------------------------ */
68 /* map gravity to (x,y) offset signs for adding to x and y when window is
69 * mapped to get proper placement. */
70 void gravity_get_offsets(int grav
, int *xp
,int *yp
)
72 static struct _gravity_offset gravity_offsets
[11] = {
73 { 0, 0 }, /* ForgetGravity */
74 { -1, -1 }, /* NorthWestGravity */
75 { 0, -1 }, /* NorthGravity */
76 { 1, -1 }, /* NorthEastGravity */
77 { -1, 0 }, /* WestGravity */
78 { 0, 0 }, /* CenterGravity */
79 { 1, 0 }, /* EastGravity */
80 { -1, 1 }, /* SouthWestGravity */
81 { 0, 1 }, /* SouthGravity */
82 { 1, 1 }, /* SouthEastGravity */
83 { 0, 0 }, /* StaticGravity */
86 if (grav
< ForgetGravity
|| grav
> StaticGravity
)
92 *xp
= (int)gravity_offsets
[grav
].x
;
93 *yp
= (int)gravity_offsets
[grav
].y
;
99 /* Move a rectangle while taking gravity into account. */
100 void gravity_move(int gravity
, rectangle
*rect
, int xdiff
, int ydiff
)
105 gravity_get_offsets(gravity
, &xoff
, &yoff
);
106 rect
->x
-= xoff
* xdiff
;
107 rect
->y
-= yoff
* ydiff
;
112 /* Resize rectangle while taking gravity into account. */
113 void gravity_resize(int gravity
, rectangle
*rect
, int wdiff
, int hdiff
)
118 gravity_get_offsets(gravity
, &xoff
, &yoff
);
119 rect
->x
-= (wdiff
* (xoff
+ 1)) / 2;
120 rect
->width
+= wdiff
;
121 rect
->y
-= (hdiff
* (yoff
+ 1)) / 2;
122 rect
->height
+= hdiff
;
127 /* Moves a child rectangle taking its gravity into accout as if the parent
128 * rectangle was moved and resized. */
129 void gravity_move_resize_parent_child(
130 int child_gravity
, rectangle
*parent_diff_r
, rectangle
*child_r
)
135 gravity_get_offsets(child_gravity
, &xoff
, &yoff
);
136 child_r
->x
-= xoff
* parent_diff_r
->x
;
137 child_r
->y
-= yoff
* parent_diff_r
->y
;
138 child_r
->x
+= ((xoff
+ 1) * parent_diff_r
->width
) / 2;
139 child_r
->y
+= ((yoff
+ 1) * parent_diff_r
->height
) / 2;
144 direction_t
gravity_grav_to_dir(
149 case NorthWestGravity
:
153 case NorthEastGravity
:
161 case SouthWestGravity
:
165 case SouthEastGravity
:
174 int gravity_dir_to_grav(
188 return NorthEastGravity
;
190 return SouthEastGravity
;
192 return SouthWestGravity
;
194 return NorthWestGravity
;
197 return ForgetGravity
;
201 int gravity_combine_xy_grav(
202 int grav_x
, int grav_y
)
206 case NorthWestGravity
:
208 case SouthWestGravity
:
209 grav_x
= WestGravity
;
211 case NorthEastGravity
:
213 case SouthEastGravity
:
214 grav_x
= EastGravity
;
217 grav_x
= CenterGravity
;
222 case NorthWestGravity
:
224 case NorthEastGravity
:
225 grav_y
= NorthGravity
;
227 case SouthWestGravity
:
229 case SouthEastGravity
:
230 grav_y
= SouthGravity
;
233 grav_y
= CenterGravity
;
236 if (grav_x
== CenterGravity
)
243 return (grav_x
== WestGravity
) ?
244 NorthWestGravity
: NorthEastGravity
;
246 return (grav_x
== WestGravity
) ?
247 SouthWestGravity
: SouthEastGravity
;
256 void gravity_split_xy_grav(
257 int *ret_grav_x
, int *ret_grav_y
, int in_grav
)
261 case NorthWestGravity
:
263 case SouthWestGravity
:
264 *ret_grav_x
= WestGravity
;
266 case NorthEastGravity
:
268 case SouthEastGravity
:
269 *ret_grav_x
= EastGravity
;
277 *ret_grav_x
= CenterGravity
;
282 case NorthWestGravity
:
284 case NorthEastGravity
:
285 *ret_grav_y
= NorthGravity
;
287 case SouthWestGravity
:
289 case SouthEastGravity
:
290 *ret_grav_y
= SouthGravity
;
298 *ret_grav_y
= CenterGravity
;
303 int gravity_combine_xy_dir(
304 int dir_x
, int dir_y
)
338 if (dir_x
== DIR_NONE
)
345 return (dir_x
== DIR_W
) ? DIR_NW
: DIR_NE
;
347 return (dir_x
== DIR_W
) ? DIR_SW
: DIR_SE
;
354 void gravity_split_xy_dir(
355 int *ret_dir_x
, int *ret_dir_y
, int in_dir
)
373 *ret_dir_x
= DIR_NONE
;
392 *ret_dir_y
= DIR_NONE
;
397 static inline int __gravity_override_one_axis(int dir_orig
, int dir_mod
)
401 if (dir_mod
== DIR_NONE
)
413 int gravity_override_dir(
414 int dir_orig
, int dir_mod
)
424 gravity_split_xy_dir(&orig_x
, &orig_y
, dir_orig
);
425 gravity_split_xy_dir(&mod_x
, &mod_y
, dir_mod
);
426 ret_x
= __gravity_override_one_axis(orig_x
, mod_x
);
427 ret_y
= __gravity_override_one_axis(orig_y
, mod_y
);
428 ret_dir
= gravity_combine_xy_dir(ret_x
, ret_y
);
433 int gravity_dir_to_sign_one_axis(
449 /* Parses the next token in action and returns
451 * 0 if it is N, North, Top or Up
452 * 1 if it is E, East, Right or Right
453 * 2 if it is S, South, Bottom or Down
454 * 3 if it is E, West, Left or Left
455 * 4 if it is NE, NorthEast, TopRight or UpRight
456 * 5 if it is SE, SouthEast, BottomRight or DownRight
457 * 6 if it is SW, SouthWest, BottomLeft or DownLeft
458 * 7 if it is NW, NorthWest, TopLeft or UpLeft
459 * 8 if it is C, Center or Centre
460 * default_ret if no string matches.
462 * A pointer to the first character in action behind the token is returned
463 * through ret_action in this case. ret_action may be NULL. If the token
464 * matches none of these strings the default_ret value is returned and the
465 * action itself is passed back in ret_action. */
466 direction_t
gravity_parse_dir_argument(
467 char *action
, char **ret_action
, direction_t default_ret
)
473 next
= GetNextTokenIndex(action
, gravity_dir_optlist
, 0, &index
);
476 /* nothing selected, use default and don't modify action */
482 rc
= index
/ STRINGS_PER_DIR
;
489 return (direction_t
)rc
;
492 char *gravity_dir_to_string(direction_t dir
, char *default_str
)
495 int d
= dir
* STRINGS_PER_DIR
;
497 if (d
>= sizeof(gravity_dir_optlist
)/sizeof(gravity_dir_optlist
[0]))
501 str
= gravity_dir_optlist
[d
];
511 multi_direction_t
gravity_parse_multi_dir_argument(
512 char *action
, char **ret_action
)
514 int rc
= MULTI_DIR_NONE
;
516 direction_t dir
= gravity_parse_dir_argument(action
, ret_action
, -1);
524 token
= PeekToken(action
, &str
);
525 if (StrEquals(token
, "all"))
536 return (multi_direction_t
)rc
;
539 void gravity_get_next_multi_dir(int dir_set
, multi_direction_t
*dir
)
541 if (*dir
== MULTI_DIR_NONE
)
543 *dir
= MULTI_DIR_FIRST
;
549 while(*dir
!= MULTI_DIR_LAST
)
557 *dir
= MULTI_DIR_NONE
;
562 direction_t
gravity_multi_dir_to_dir(multi_direction_t mdir
)
564 direction_t dir
= DIR_NONE
;
566 for ( ; mdir
!= 0; dir
++)
570 if (dir
> DIR_ALL_MASK
)
578 void gravity_rotate_xy(rotation_t rot
, int x
, int y
, int *ret_x
, int *ret_y
)
611 rotation_t
gravity_add_rotations(rotation_t rot1
, rotation_t rot2
)
615 rot
= ((rot1
+ rot2
) & ROTATION_MASK
);