diff options
author | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2011-12-09 05:16:12 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2011-12-09 05:36:38 -0500 |
commit | bf0ad74099e7001c3ad5c222fffbf0bf51d577fd (patch) | |
tree | 0371279eee77bb08c6501d5fbdb11c21fb9009a1 | |
parent | 7d8876459ce6c4ac418046b93d31a46ce37fe496 (diff) |
Keep track of valid regions
-rw-r--r-- | main.c | 18 | ||||
-rw-r--r-- | window.c | 96 |
2 files changed, 100 insertions, 14 deletions
@@ -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; @@ -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); } |