/************************************************************************** Mark the entire screen area as "dirty" so that we can flush it later. **************************************************************************/ void dirty_all(void) { if (mapview_is_frozen()) { return; } num_dirty_rects = MAX_DIRTY_RECTS; queue_flush(); }
/************************************************************************** Flush the given part of the canvas buffer (if there is one) to the screen. **************************************************************************/ void flush_mapcanvas(int canvas_x, int canvas_y, int pixel_width, int pixel_height) { GdkRectangle rectangle = {canvas_x, canvas_y, pixel_width, pixel_height}; if (gtk_widget_get_realized(map_canvas) && !mapview_is_frozen()) { gdk_window_invalidate_rect(gtk_widget_get_window(map_canvas), &rectangle, FALSE); } }
/************************************************************************** Flush the given part of the canvas buffer (if there is one) to the screen. **************************************************************************/ void flush_mapcanvas(int canvas_x, int canvas_y, int pixel_width, int pixel_height) { if (NULL != map_canvas->window && !mapview_is_frozen()) { gdk_draw_drawable(map_canvas->window, civ_gc, mapview.store->v.pixmap, canvas_x, canvas_y, canvas_x, canvas_y, pixel_width, pixel_height); } }
/************************************************************************** Redraw map canvas. **************************************************************************/ gboolean map_canvas_draw(GtkWidget *w, cairo_t *cr, gpointer data) { if (can_client_change_view() && map_exists() && !mapview_is_frozen()) { /* First we mark the area to be updated as dirty. Then we unqueue * any pending updates, to make sure only the most up-to-date data * is written (otherwise drawing bugs happen when old data is copied * to screen). Then we draw all changed areas to the screen. */ unqueue_mapview_updates(FALSE); cairo_set_source_surface(cr, mapview.store->surface, 0, 0); cairo_paint(cr); } return TRUE; }
/************************************************************************** Map canvas exposed **************************************************************************/ gboolean map_canvas_expose(GtkWidget *w, GdkEventExpose *ev, gpointer data) { if (can_client_change_view() && map_exists() && !mapview_is_frozen()) { /* First we mark the area to be updated as dirty. Then we unqueue * any pending updates, to make sure only the most up-to-date data * is written (otherwise drawing bugs happen when old data is copied * to screen). Then we draw all changed areas to the screen. */ unqueue_mapview_updates(FALSE); gdk_draw_drawable(map_canvas->window, civ_gc, mapview.store->v.pixmap, ev->area.x, ev->area.y, ev->area.x, ev->area.y, ev->area.width, ev->area.height); } return TRUE; }
/************************************************************************** Mark the rectangular region as "dirty" so that we know to flush it later. **************************************************************************/ void dirty_rect(int canvas_x, int canvas_y, int pixel_width, int pixel_height) { if (mapview_is_frozen()) { return; } if (num_dirty_rects < MAX_DIRTY_RECTS) { dirty_rects[num_dirty_rects].x = canvas_x; dirty_rects[num_dirty_rects].y = canvas_y; dirty_rects[num_dirty_rects].width = pixel_width; dirty_rects[num_dirty_rects].height = pixel_height; num_dirty_rects++; queue_flush(); } }
/************************************************************************** Flush all regions that have been previously marked as dirty. See dirty_rect and dirty_all. This function is generally called after we've processed a batch of drawing operations. **************************************************************************/ void flush_dirty(void) { if (mapview_is_frozen()) { return; } if (num_dirty_rects == MAX_DIRTY_RECTS) { flush_mapcanvas(0, 0, map_canvas->allocation.width, map_canvas->allocation.height); } else { int i; for (i = 0; i < num_dirty_rects; i++) { flush_mapcanvas(dirty_rects[i].x, dirty_rects[i].y, dirty_rects[i].width, dirty_rects[i].height); } } num_dirty_rects = 0; }