2018-10-04 05:14:51 +08:00
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
|
2018-09-30 06:36:53 +08:00
|
|
|
#pragma once
|
2018-09-30 21:11:10 +08:00
|
|
|
#include <xcb/xcb.h>
|
2018-09-30 06:36:53 +08:00
|
|
|
#include <pixman.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "utils.h"
|
2018-10-21 09:56:50 +08:00
|
|
|
|
2018-09-30 06:36:53 +08:00
|
|
|
typedef struct pixman_region32 pixman_region32_t;
|
|
|
|
typedef struct pixman_box32 pixman_box32_t;
|
|
|
|
typedef pixman_region32_t region_t;
|
|
|
|
typedef pixman_box32_t rect_t;
|
|
|
|
|
|
|
|
RC_TYPE(region_t, rc_region, pixman_region32_init, pixman_region32_fini, static inline)
|
|
|
|
|
|
|
|
/// copy a region_t
|
|
|
|
static inline void
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
copy_region(region_t *dst, const region_t *p) {
|
2018-09-30 06:36:53 +08:00
|
|
|
pixman_region32_copy(dst, (region_t *)p);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
dump_region(const region_t *x) {
|
2018-09-30 06:36:53 +08:00
|
|
|
int nrects;
|
|
|
|
const rect_t *rects = pixman_region32_rectangles((region_t *)x, &nrects);
|
|
|
|
fprintf(stderr, "nrects: %d\n", nrects);
|
|
|
|
for (int i = 0; i < nrects; i++)
|
|
|
|
fprintf(stderr, "(%d, %d) - (%d, %d)\n", rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
|
|
|
|
}
|
2018-09-30 21:11:10 +08:00
|
|
|
|
|
|
|
/// Convert one xcb rectangle to our rectangle type
|
|
|
|
static inline rect_t
|
|
|
|
from_x_rect(const xcb_rectangle_t *rect) {
|
|
|
|
return (rect_t) {
|
|
|
|
.x1 = rect->x,
|
|
|
|
.y1 = rect->y,
|
|
|
|
.x2 = rect->x + rect->width,
|
|
|
|
.y2 = rect->y + rect->height,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert an array of xcb rectangles to our rectangle type
|
|
|
|
/// Returning an array that needs to be freed
|
|
|
|
static inline rect_t *
|
|
|
|
from_x_rects(int nrects, const xcb_rectangle_t *rects) {
|
|
|
|
rect_t *ret = calloc(nrects, sizeof *ret);
|
|
|
|
for (int i = 0; i < nrects; i++)
|
|
|
|
ret[i] = from_x_rect(rects+i);
|
|
|
|
return ret;
|
|
|
|
}
|