summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@l3000.localdomain>2011-12-09 05:16:12 -0500
committerSøren Sandmann Pedersen <ssp@l3000.localdomain>2011-12-09 05:36:38 -0500
commitbf0ad74099e7001c3ad5c222fffbf0bf51d577fd (patch)
tree0371279eee77bb08c6501d5fbdb11c21fb9009a1
parent7d8876459ce6c4ac418046b93d31a46ce37fe496 (diff)
Keep track of valid regions
-rw-r--r--main.c18
-rw-r--r--window.c96
2 files changed, 100 insertions, 14 deletions
diff --git a/main.c b/main.c
index ee6cd97..e73aba1 100644
--- a/main.c
+++ b/main.c
@@ -108,6 +108,24 @@ on_event (window_t *window, ws_event_t *event, void *data)
break;
case WS_BUTTON_UP:
+ if (dragging == 1)
+ {
+ int dx = event->button.root_x - drag_x;
+ int dy = event->button.root_y - drag_y;
+
+ ws_window_resize (window, drag_w + dx, drag_h + dy);
+ need_repaint = 1;
+ }
+ else if (dragging == 2)
+ {
+ int dx = event->button.root_x - drag_x;
+ int dy = event->button.root_y - drag_y;
+
+#if 0
+ printf ("move to %d %d\n", drag_pos_x + dx, drag_pos_y + dy);
+#endif
+ ws_window_move (window, drag_pos_x + dx, drag_pos_y + dy);
+ }
if (dragging)
dragging = 0;
break;
diff --git a/window.c b/window.c
index c4623bd..436a26b 100644
--- a/window.c
+++ b/window.c
@@ -29,7 +29,8 @@ struct window_t
int ref_count;
pixman_image_t * backing_store;
int x, y;
- pixman_region32_t repaint;
+ pixman_region32_t expose;
+ pixman_region32_t valid;
list_t event_queue;
uint32_t motion_notify_time;
@@ -262,7 +263,23 @@ ws_window_get_y (window_t *window)
}
static void
-copy_backing_store_to_window (window_t *window, int x, int y, int width, int height)
+print_region (const char *name, pixman_region32_t *region)
+{
+ int n_boxes;
+ pixman_box32_t *boxes;
+
+ printf ("-- %s\n", name);
+ boxes = pixman_region32_rectangles (region, &n_boxes);
+ while (n_boxes--)
+ {
+ printf (" %d %d %d %d\n", boxes->x1, boxes->y1, boxes->x2, boxes->y2);
+ boxes++;
+ }
+}
+
+static void
+copy_backing_store_to_window (window_t *window,
+ int x, int y, int width, int height)
{
pixman_format_code_t format = window->ws->format;
Display *dpy = window->ws->display;
@@ -271,6 +288,13 @@ copy_backing_store_to_window (window_t *window, int x, int y, int width, int hei
XGCValues values;
GC gc;
+#if 0
+ /* This assertion triggers, but ideally it shouldn't FIXME find
+ * out why.
+ */
+ assert (width <= pixman_image_get_width (window->backing_store));
+#endif
+
format_to_masks (format, &a, &r, &g, &b);
image.width = get_width (window);
@@ -295,7 +319,6 @@ copy_backing_store_to_window (window_t *window, int x, int y, int width, int hei
XPutImage (dpy, window->xid, gc, &image,
x, y, x, y, width, height);
-
XFreeGC (dpy, gc);
}
@@ -307,11 +330,24 @@ update_local_geometry (window_t *window, int x, int y, int width, int height)
int old_width = get_width (window);
int old_height = get_height (window);
+ pixman_region32_intersect_rect (
+ &window->valid, &window->valid, 0, 0, width, height);
+
if (width != old_width || height != old_height)
{
+ /* We should never see this color.
+ * FIXME: we do see this color
+ */
+ pixman_color_t ugly = { 0x0000, 0xffff, 0xffff, 0xffff };
pixman_image_t *new_backing =
pixman_image_create_bits (
window->ws->format, width, height, NULL, -1);
+ pixman_image_t *solid_fill =
+ pixman_image_create_solid_fill (&ugly);
+
+ pixman_image_composite32 (
+ PIXMAN_OP_SRC, solid_fill, NULL, new_backing,
+ 0, 0, 0, 0, 0, 0, width, height);
pixman_image_composite32 (
PIXMAN_OP_SRC,
@@ -404,7 +440,7 @@ process_expose (ws_t *ws, const XEvent *event)
if (!(window = find_window (ws, event->xexpose.window)))
return;
- pixman_region32_union_rect (&window->repaint, &window->repaint,
+ pixman_region32_union_rect (&window->expose, &window->expose,
event->xexpose.x, event->xexpose.y,
event->xexpose.width, event->xexpose.height);
}
@@ -598,13 +634,16 @@ ws_process (ws_t *ws)
pixman_box32_t *boxes;
int n_boxes;
+ pixman_region32_intersect (
+ &window->expose, &window->expose, &window->valid);
+
/* FIXME: when resizing windows, the associated exposes end up
* causing undefined data to be copied to the window. Something
* should perhaps be done about that. For example by keeping
* track of windows bits that haven't been painted, and never
* painting those.
*/
- boxes = pixman_region32_rectangles (&window->repaint, &n_boxes);
+ boxes = pixman_region32_rectangles (&window->expose, &n_boxes);
while (n_boxes--)
{
copy_backing_store_to_window (window,
@@ -615,8 +654,8 @@ ws_process (ws_t *ws)
boxes++;
}
- pixman_region32_fini (&window->repaint);
- pixman_region32_init (&window->repaint);
+ pixman_region32_fini (&window->expose);
+ pixman_region32_init (&window->expose);
emit_events (window);
}
@@ -661,20 +700,25 @@ ws_create_window (ws_t *ws,
window_t *window = malloc (sizeof *window);
Window root = RootWindow (ws->display, 0);
XSetWindowAttributes attr;
+ unsigned long mask;
attr.background_pixmap = None;
attr.colormap = ws->colormap;
- attr.background_pixel = 0;
- attr.border_pixel = 0;
+ attr.background_pixel = 0x0;
+ attr.border_pixel = 0x0;
attr.bit_gravity = NorthWestGravity;
+ mask = CWBitGravity | CWBorderPixel | CWBackPixmap | CWColormap;
+
+ if (ws->has_alpha)
+ mask |= CWBackPixel;
+
#if 0
printf ("%d %x %x %x %x %x\n", ws->depth, ws->visual->red_mask, ws->visual->green_mask, ws->visual->blue_mask, ws->visual->visualid, ws->colormap);
#endif
window->xid = XCreateWindow (
ws->display, root, x, y, width, height, 0,
- ws->depth, InputOutput, ws->visual,
- CWBitGravity | CWBackPixel | CWBorderPixel | CWBackPixmap | CWColormap, &attr);
+ ws->depth, InputOutput, ws->visual, mask, &attr);
window->ref_count = 1;
window->backing_store =
@@ -689,7 +733,8 @@ ws_create_window (ws_t *ws,
PointerMotionMask | EnterWindowMask | LeaveWindowMask |
ButtonPressMask | ButtonReleaseMask);
- pixman_region32_init (&window->repaint);
+ pixman_region32_init (&window->expose);
+ pixman_region32_init (&window->valid);
list_init (&window->event_queue);
window->motion_notify_time = 0;
@@ -808,6 +853,17 @@ ws_window_copy_area (window_t *window,
pixman_image_get_format (window->backing_store);
pixman_image_t *tmp =
pixman_image_create_bits (format, width, height, NULL, -1);
+ pixman_region32_t moving_valid;
+ pixman_region32_t dest;
+
+ pixman_region32_init_rect (&moving_valid, src_x, src_y, width, height);
+ pixman_region32_intersect (&moving_valid, &moving_valid, &window->valid);
+ pixman_region32_translate (&moving_valid, dst_x - src_x, dst_y - src_y);
+ pixman_region32_init_rect (&dest, dst_x, dst_y, width, height);
+ pixman_region32_subtract (&dest, &window->valid, &dest);
+ pixman_region32_union (&window->valid, &dest, &moving_valid);
+ pixman_region32_fini (&moving_valid);
+ pixman_region32_fini (&dest);
pixman_image_composite32 (PIXMAN_OP_SRC,
window->backing_store, NULL, tmp,
@@ -827,6 +883,9 @@ ws_window_copy_from_image (window_t *window,
int width,
int height)
{
+ pixman_region32_union_rect (
+ &window->valid, &window->valid, win_x, win_y, width, height);
+
/* copy from image to backing */
pixman_image_composite32 (PIXMAN_OP_SRC,
image, NULL, window->backing_store,
@@ -860,9 +919,18 @@ ws_window_finish (window_t **windows,
for (i = 0; i < n_windows; ++i)
{
window_t *window = windows[i];
+ int n_boxes;
+ pixman_box32_t *boxes;
+
+ boxes = pixman_region32_rectangles (&window->valid, &n_boxes);
- copy_backing_store_to_window (
- window, 0, 0, get_width (window), get_height (window));
+ while (n_boxes--)
+ {
+ copy_backing_store_to_window (
+ window,
+ boxes->x1, boxes->y1,
+ boxes->x2 - boxes->x1, boxes->y2 - boxes->y1);
+ }
XFlush (window->ws->display);
}