As attachement, but I think gmail is messing this up:
On Fri, Jul 22, 2016 at 6:39 PM, Bill Spitzak <[email protected]> wrote:
> /* Translate xdg_positioner v4 settings to proposed list-of-rectangles api
> *
> * I cannot find any proposed implementation, so I have to base this
> off the comments
> * in the protocol spec, which are somewhat ambiguous. See FIXME notes
> for where I
> * guessed and may have mis-interpreted the spec.
> */
>
> #include <limits.h>
> #include <stdio.h>
>
> /* bits for anchor and gravity */
> #define TOP 1
> #define BOTTOM 2
> #define LEFT 4
> #define RIGHT 8
>
> /* bits for constrain_adjustment */
> #define SLIDE_X 1
> #define SLIDE_Y 2
> #define FLIP_X 4
> #define FLIP_Y 8
>
> /* v4 positioner data */
> typedef struct {
> struct { int width; int height; } size;
> struct { int x; int y; int width; int height; } anchor_rect;
> int anchor;
> int gravity;
> int constrain_adjustment;
> struct { int x; int y; } offset;
> } V4Positioner;
>
> /* The new positioner api */
> extern void add_rectangle( int x0, int y0, int x1, int y1 ) {
> printf("add_rectangle( %d, %d, %d, %d );\n", x0, y0, x1, y1);
> }
>
> /* Possibly the api should support this rather than the 4-number rectangle.
> * x0,y0 must be upper-left corner, x1,y1 the lower-right corner, x,y
> is preferred
> * location which must be inside the rectangle.
> */
> void add_rectangle6( int x, int y, int x0, int y0, int x1, int y1 )
> {
> if (y > y0) {
> if (x > x0)
> add_rectangle(x, y, x0, y0);
> add_rectangle(x, y, x1, y0);
> }
> if (x > x0)
> add_rectangle(x, y, x0, y1);
> add_rectangle(x, y, x1, y1);
> }
>
> /* Do one part of a "flip" */
> void single_anchor(const V4Positioner* v4, int anchor, int gravity,
> int constrain_adjustment) {
>
> int x, y; /* preferred position */
>
> /* Find anchor point */
> if (anchor & LEFT)
> x = v4->anchor_rect.x;
> else if (anchor & RIGHT)
> x = v4->anchor_rect.x + v4->anchor_rect.width;
> else
> x = v4->anchor_rect.x + v4->anchor_rect.width / 2;
>
> if (anchor & TOP)
> y = v4->anchor_rect.y;
> else if (anchor & BOTTOM)
> y = v4->anchor_rect.y + v4->anchor_rect.height;
> else
> y = v4->anchor_rect.y + v4->anchor_rect.height / 2;
>
> /* move to top-left of size */
> if (gravity & LEFT)
> ;
> else if (gravity & RIGHT)
> x -= v4->size.width;
> else
> x -= v4->size.width / 2;
> if (gravity & TOP)
> ;
> else if (gravity & BOTTOM)
> y -= v4->size.height;
> else
> y -= v4->size.height / 2;
>
> /* Handle offset.
> * FIXME: I am assuming the "widget in the child" is a rectangle
> defined by offset,size.
> * Documentation seems to imply the meaning of offset depends on
> the gravity, but
> * that is pretty useless for FLIP setups so I did not do that.
> */
> x -= v4->offset.x;
> y -= v4->offset.y;
>
> /* Add slide to get resulting rectangles
> * FIXME: unclear if slide is limited to touch the anchor
> rectangle. I believe
> * this is not true so I use INT_MAX here.
> * FIXME: unclear if slide is limited to touch the parent surface.
> My opinion
> * now is that the compositor can enforce this.
> */
> int x0, y0, x1, y1;
> if (constrain_adjustment & SLIDE_X) {
> x0 = -INT_MAX;
> x1 = +INT_MAX;
> } else {
> x0 = x1 = x;
> }
> if (constrain_adjustment & SLIDE_Y) {
> y0 = -INT_MAX;
> y1 = +INT_MAX;
> } else {
> y0 = y1 = y;
> }
>
> add_rectangle6(x, y, x0, y0, x1, y1);
> }
>
> /* Do the full conversion.
> * FIXME: This will produce redundant identical rectangles. Preventing
> this requires more
> * testing for useless flip states.
> */
> void convert(const V4Positioner* v4) {
>
> if (v4->constrain_adjustment & FLIP_Y) {
> /* try the preferred position first, no sliding */
> single_anchor(v4, v4->anchor, v4->gravity,
> v4->constrain_adjustment & (~SLIDE_Y));
> /* try the flipped position */
> single_anchor(v4, v4->anchor ^ (TOP|BOTTOM), v4->gravity ^
> (TOP|BOTTOM),
> v4->constrain_adjustment & (~SLIDE_Y));
> /* FIXME: this only does slide on the original side. Unclear
> if slide is on other side too.
> */
> }
>
> /* FIXME: what happens if both FLIP_X and FLIP_Y are set is
> unclear. This version only
> * tries three locations, not four.
> */
> if (v4->constrain_adjustment & FLIP_X) {
> /* try the preferred position first, no sliding */
> single_anchor(v4, v4->anchor, v4->gravity,
> v4->constrain_adjustment & (~SLIDE_X));
> /* try the flipped position */
> single_anchor(v4, v4->anchor ^ (LEFT|RIGHT), v4->gravity ^
> (LEFT|RIGHT),
> v4->constrain_adjustment & (~SLIDE_X));
> }
>
> /* Do the non-flipped position */
> single_anchor(v4, v4->anchor, v4->gravity, v4->constrain_adjustment);
> }
>
> int main() {
> V4Positioner v4;
>
> v4.size.width = 100;
> v4.size.height = 100;
>
> v4.anchor_rect.x = 60;
> v4.anchor_rect.y = 90;
> v4.anchor_rect.width = 0;
> v4.anchor_rect.height = 0;
>
> v4.anchor = 0;
> v4.gravity = TOP;
> v4.constrain_adjustment = FLIP_Y | SLIDE_X;
>
> v4.offset.x = 0;
> v4.offset.y = 0;
>
> convert(&v4);
> return 0;
> }
/* Translate xdg_positioner v4 settings to proposed list-of-rectangles api
*
* I cannot find any proposed implementation, so I have to base this off the comments
* in the protocol spec, which are somewhat ambiguous. See FIXME notes for where I
* guessed and may have mis-interpreted the spec.
*/
#include <limits.h>
#include <stdio.h>
/* bits for anchor and gravity */
#define TOP 1
#define BOTTOM 2
#define LEFT 4
#define RIGHT 8
/* bits for constrain_adjustment */
#define SLIDE_X 1
#define SLIDE_Y 2
#define FLIP_X 4
#define FLIP_Y 8
/* v4 positioner data */
typedef struct {
struct { int width; int height; } size;
struct { int x; int y; int width; int height; } anchor_rect;
int anchor;
int gravity;
int constrain_adjustment;
struct { int x; int y; } offset;
} V4Positioner;
/* The new positioner api */
extern void add_rectangle( int x0, int y0, int x1, int y1 ) {
printf("add_rectangle( %d, %d, %d, %d );\n", x0, y0, x1, y1);
}
/* Possibly the api should support this rather than the 4-number rectangle.
* x0,y0 must be upper-left corner, x1,y1 the lower-right corner, x,y is preferred
* location which must be inside the rectangle.
*/
void add_rectangle6( int x, int y, int x0, int y0, int x1, int y1 )
{
if (y > y0) {
if (x > x0)
add_rectangle(x, y, x0, y0);
add_rectangle(x, y, x1, y0);
}
if (x > x0)
add_rectangle(x, y, x0, y1);
add_rectangle(x, y, x1, y1);
}
/* Do one part of a "flip" */
void single_anchor(const V4Positioner* v4, int anchor, int gravity, int constrain_adjustment) {
int x, y; /* preferred position */
/* Find anchor point */
if (anchor & LEFT)
x = v4->anchor_rect.x;
else if (anchor & RIGHT)
x = v4->anchor_rect.x + v4->anchor_rect.width;
else
x = v4->anchor_rect.x + v4->anchor_rect.width / 2;
if (anchor & TOP)
y = v4->anchor_rect.y;
else if (anchor & BOTTOM)
y = v4->anchor_rect.y + v4->anchor_rect.height;
else
y = v4->anchor_rect.y + v4->anchor_rect.height / 2;
/* move to top-left of size */
if (gravity & LEFT)
;
else if (gravity & RIGHT)
x -= v4->size.width;
else
x -= v4->size.width / 2;
if (gravity & TOP)
;
else if (gravity & BOTTOM)
y -= v4->size.height;
else
y -= v4->size.height / 2;
/* Handle offset.
* FIXME: I am assuming the "widget in the child" is a rectangle defined by offset,size.
* Documentation seems to imply the meaning of offset depends on the gravity, but
* that is pretty useless for FLIP setups so I did not do that.
*/
x -= v4->offset.x;
y -= v4->offset.y;
/* Add slide to get resulting rectangles
* FIXME: unclear if slide is limited to touch the anchor rectangle. I believe
* this is not true so I use INT_MAX here.
* FIXME: unclear if slide is limited to touch the parent surface. My opinion
* now is that the compositor can enforce this.
*/
int x0, y0, x1, y1;
if (constrain_adjustment & SLIDE_X) {
x0 = -INT_MAX;
x1 = +INT_MAX;
} else {
x0 = x1 = x;
}
if (constrain_adjustment & SLIDE_Y) {
y0 = -INT_MAX;
y1 = +INT_MAX;
} else {
y0 = y1 = y;
}
add_rectangle6(x, y, x0, y0, x1, y1);
}
/* Do the full conversion.
* FIXME: This will produce redundant identical rectangles. Preventing this requires more
* testing for useless flip states.
*/
void convert(const V4Positioner* v4) {
if (v4->constrain_adjustment & FLIP_Y) {
/* try the preferred position first, no sliding */
single_anchor(v4, v4->anchor, v4->gravity, v4->constrain_adjustment & (~SLIDE_Y));
/* try the flipped position */
single_anchor(v4, v4->anchor ^ (TOP|BOTTOM), v4->gravity ^ (TOP|BOTTOM),
v4->constrain_adjustment & (~SLIDE_Y));
/* FIXME: this only does slide on the original side, that is what I think the
* documentation says. Not entirely clear however.
*/
}
/* FIXME: what happens if both FLIP_X and FLIP_Y are set is unclear. This version only
* tries three locations, not four.
*/
if (v4->constrain_adjustment & FLIP_X) {
/* try the preferred position first, no sliding */
single_anchor(v4, v4->anchor, v4->gravity, v4->constrain_adjustment & (~SLIDE_X));
/* try the flipped position */
single_anchor(v4, v4->anchor ^ (LEFT|RIGHT), v4->gravity ^ (LEFT|RIGHT),
v4->constrain_adjustment & (~SLIDE_X));
/* FIXME: this only does slide on the original side, that is what I think the
* documentation says. Not entirely clear however.
*/
}
/* Do the non-flipped position */
single_anchor(v4, v4->anchor, v4->gravity, v4->constrain_adjustment);
}
int main() {
V4Positioner v4;
v4.size.width = 100;
v4.size.height = 100;
v4.anchor_rect.x = 60;
v4.anchor_rect.y = 90;
v4.anchor_rect.width = 0;
v4.anchor_rect.height = 0;
v4.anchor = 0;
v4.gravity = TOP;
v4.constrain_adjustment = FLIP_Y | SLIDE_X;
v4.offset.x = 0;
v4.offset.y = 0;
convert(&v4);
return 0;
}
_______________________________________________
wayland-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/wayland-devel