Example #1
0
void
clientwin_destroy(ClientWin *cw, bool destroyed) {
	MainWin *mw = cw->mainwin;
	session_t * const ps = mw->ps;

	free_picture(ps, &cw->origin);
	free_picture(ps, &cw->destination);
	free_pixmap(ps, &cw->pixmap);
	free_pixmap(ps, &cw->cpixmap);

	if (cw->src.window && !destroyed) {
		free_damage(ps, &cw->damage);

		// Stop listening to events, this should be safe because we don't
		// monitor window re-map anyway
		XSelectInput(ps->dpy, cw->src.window, 0);

		if (cw->redirected)
			XCompositeUnredirectWindow(ps->dpy, cw->src.window, CompositeRedirectAutomatic);
	}

	if (cw->mini.window) {
		// Somehow it doesn't work without unmapping firstly
		XUnmapWindow(ps->dpy, cw->mini.window);
		XDestroyWindow(ps->dpy, cw->mini.window);
	}

	free(cw);
}
Example #2
0
void test_copy(uint32_t w, uint32_t h, uint32_t sformat, uint32_t dformat)
{
	PixmapPtr src, dest;
	C2D_OBJECT blit = {};
	C2D_RECT rect;
	c2d_ts_handle curTimestamp;

	RD_START("copy", "%dx%d format:%s->%s", w, h,
			fmtname(sformat), fmtname(dformat));

	dest = create_pixmap(w, h, dformat);
	src  = create_pixmap(13, 17, sformat);

	rect.x = 1;
	rect.y = 2;
	rect.width = w - 2;
	rect.height = h - 3;
	CHK(c2dFillSurface(dest->id, 0xff556677, &rect));

	rect.x = 0;
	rect.y = 0;
	rect.width = 13;
	rect.height = 17;
	CHK(c2dFillSurface(src->id, 0xff223344, &rect));

	blit.surface_id = src->id;
	blit.config_mask = DEFAULT_BLIT_MASK;
	blit.next = NULL;

	blit.source_rect.x = FIXED(1);
	blit.source_rect.y = FIXED(2);
	blit.source_rect.width = FIXED(13-1);
	blit.source_rect.height = FIXED(17-2);

	blit.target_rect.x = FIXED((w - 13) / 2);
	blit.target_rect.y = FIXED((h - 17) / 2);
	blit.target_rect.width = FIXED(13);
	blit.target_rect.height = FIXED(17);
	CHK(c2dDraw(dest->id, 0, NULL, 0, 0, &blit, 1));
	CHK(c2dFlush(dest->id, &curTimestamp));
	CHK(c2dWaitTimestamp(curTimestamp));

	free_pixmap(src);
	free_pixmap(dest);

	RD_END();

//	dump_pixmap(dest, "copy-%04dx%04d-%08x.bmp", w, h, dformat);
}
Example #3
0
void graph_end(void)
{
	int i;
	PIXMAP_INFO *xpm;

  if(vga_getcurrentmode() != TEXT)
			vga_setmode(TEXT);


	if (cm_pixels) free(cm_pixels);

	for (i=0; i<PaneCount; i++)
	{ xpm = all_panes[i];
     if (xpm != NULL)  free_pixmap(xpm);    
	}


}
Example #4
0
void free_pixmaps (void)
{
  unsigned i;

  free_pixmap (&update_pix);
  free_pixmap (&refresh_pix);
  free_pixmap (&refrsel_pix);
  free_pixmap (&stop_pix);

  free_pixmap (&connect_pix);
  free_pixmap (&observe_pix);
  free_pixmap (&record_pix);

  free_pixmap (&sfilter_pix);
  free_pixmap (&sfilter_cfg_pix);
  free_pixmap (&pfilter_pix);
  free_pixmap (&pfilter_cfg_pix);

  free_pixmap (&gplus_pix);
  free_pixmap (&rminus_pix);

  free_pixmap (&man_black_pix);
  free_pixmap (&man_red_pix);
  free_pixmap (&man_yellow_pix); // He's actually green

  for (i = 0; i < 3; i++)
    free_pixmap (&group_pix[i]);

  for (i = 0; i < 9; i++)
    free_pixmap (&buddy_pix[i]);

  free_pixmap (&error_pix);
  free_pixmap (&delete_pix);

  for (i = 0; i < 5; i++)
    free_pixmap (&server_status[i]);

  free_pixmap (&locked_pix);

  free_pixmap (&punkbuster_pix);
  free_pixmap (&locked_punkbuster_pix);

  for (i = 0; i < GAMES_TOTAL; i++)
  {
    free_pixmap(games[i].pix);
    g_free(games[i].pix);
    games[i].pix = NULL;
  }

  if (pixmaps_gc) {
    gdk_gc_destroy (pixmaps_gc);
    pixmaps_gc = NULL;
  }

  if (masks_gc) {
    gdk_gc_destroy (masks_gc);
    masks_gc = NULL;
  }
}
Example #5
0
void test_composite(const char *name, const struct blend_mode *blend,
		const struct format_mode *dst_format,
		uint32_t bw, uint32_t bh,
		const struct format_mode *src_format,
		uint32_t src_repeat, uint32_t sw, uint32_t sh,
		const struct format_mode *mask_format,
		uint32_t mask_repeat, uint32_t mw, uint32_t mh)
{
	PixmapPtr src, dest, mask = NULL;
	C2D_OBJECT blit = {};
	c2d_ts_handle curTimestamp;

	DEBUG_MSG("%s: op:%s src:%s (repeat:%d) mask=%s (repeat:%d) dst:%s",
			name, blend->name, src_format->name, src_repeat,
			mask_format ? mask_format->name : "none", mask_repeat,
			dst_format->name);
	RD_START(name, "op:%s src:%s (repeat:%d) mask=%s (repeat:%d) dst:%s",
			blend->name, src_format->name, src_repeat,
			mask_format ? mask_format->name : "none", mask_repeat,
			dst_format->name);

	blit.config_mask = DEFAULT_BLEND_MASK | blend->mode;

	dest = create_pixmap(1033, 1077, dst_format->format);

	if (src_repeat) {
		src  = create_pixmap(1, 1, src_format->format);
		blit.config_mask |= C2D_SOURCE_TILE_BIT;
	} else {
		src = create_pixmap(sw, sh, src_format->format);
	}

	blit.config_mask |= C2D_SOURCE_RECT_BIT;
	blit.surface_id = src->id;

	if (mask_format) {
		/* TODO not clear if mask repeat is really supported.. msm-exa-c2d2.c
		 * seems to reject it but C2D_MASK_TILE_BIT??
		 *
		 * Also, for src format, msm-exa-c2d2.c seems to encode fgcolor (like
		 * a solid fill) for repeats.. not really clear if TILE_BIT does what
		 * we expect or not??
		 *
		 * Seems like libC2D2 doesn't actually give any way to specify the
		 * maskX/maskY!!!  The previous c2d API does, so I'd have to assume
		 * this is actually supported by the hardware and this is just C2D2
		 * retardation
		 */
		if (mask_repeat) {
			mask = create_pixmap(1, 1, mask_format->format);
			blit.config_mask |= C2D_MASK_TILE_BIT;
		} else {
			mask = create_pixmap(mw, mh, mask_format->format);
		}

		blit.config_mask |= C2D_MASK_SURFACE_BIT;
		blit.mask_surface_id = mask->id;
	} else {
		// TODO make redump not confused when one column has extra rows
		mask = create_pixmap(1, 1, ARGB);
	}

	blit.next = NULL;

	blit.source_rect.x = FIXED(1);
	blit.source_rect.y = FIXED(2);
	blit.source_rect.width = FIXED(bw - blit.source_rect.x - 1);
	blit.source_rect.height = FIXED(bh - blit.source_rect.y - 2);

	blit.target_rect.x = FIXED((dest->width - sw) / 2);
	blit.target_rect.y = FIXED((dest->height - sh) / 2);
	blit.target_rect.width = blit.source_rect.width;
	blit.target_rect.height = blit.source_rect.height;
	CHK(c2dDraw(dest->id, 0, NULL, 0, 0, &blit, 1));
	CHK(c2dFlush(dest->id, &curTimestamp));
	CHK(c2dWaitTimestamp(curTimestamp));

	free_pixmap(src);
	free_pixmap(dest);
	if (mask)
		free_pixmap(mask);

	RD_END();

//	dump_pixmap(dest, "copy-%04dx%04d-%08x.bmp", w, h, format);
}
Example #6
0
void test_composite(uint32_t blend_mode,
		uint32_t dst_format, uint32_t dst_width, uint32_t dst_height,
		uint32_t src_format, uint32_t src_width, uint32_t src_height,
		uint32_t mask_format, uint32_t mask_width, uint32_t mask_height,
		uint32_t src_x, uint32_t src_y, uint32_t mask_x, uint32_t mask_y,
		uint32_t dst_x, uint32_t dst_y, uint32_t w, uint32_t h)
{
	PixmapPtr src, dest, mask = NULL;
	C2D_OBJECT blit = {};
	c2d_ts_handle curTimestamp;

	DEBUG_MSG("composite2: blend_mode:%08x, dst_format:%08x, dst_width:%x, dst_height=%x, "
			"src_format:%08x, src_width:%x, src_height:%x, "
			"mask_format:%08x, mask_width:%x, mask_height:%x, "
			"src_x:%x, src_y:%x, mask_x:%x, mask_y:%x, dst_x:%x, dst_y:%x, w:%x, h:%x",
			blend_mode, dst_format, dst_width, dst_height,
			src_format, src_width, src_height,
			mask_format, mask_width, mask_height,
			src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);
	RD_START("composite2","blend_mode:%08x, dst_format:%08x, dst_width:%x, dst_height=%x, "
			"src_format:%08x, src_width:%x, src_height:%x, "
			"mask_format:%08x, mask_width:%x, mask_height:%x, "
			"src_x:%x, src_y:%x, mask_x:%x, mask_y:%x, dst_x:%x, dst_y:%x, w:%x, h:%x",
			blend_mode, dst_format, dst_width, dst_height,
			src_format, src_width, src_height,
			mask_format, mask_width, mask_height,
			src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);

	blit.config_mask = DEFAULT_BLEND_MASK | blend_mode;

	dest = create_pixmap(dst_width, dst_height, dst_format);
	src  = create_pixmap(src_width, src_height, src_format);

	blit.config_mask |= C2D_SOURCE_RECT_BIT;
	blit.surface_id = src->id;

	if (mask_format) {
		/* TODO not clear if mask repeat is really supported.. msm-exa-c2d2.c
		 * seems to reject it but C2D_MASK_TILE_BIT??
		 *
		 * Also, for src format, msm-exa-c2d2.c seems to encode fgcolor (like
		 * a solid fill) for repeats.. not really clear if TILE_BIT does what
		 * we expect or not??
		 *
		 * Seems like libC2D2 doesn't actually give any way to specify the
		 * maskX/maskY!!!  The previous c2d API does, so I'd have to assume
		 * this is actually supported by the hardware and this is just C2D2
		 * retardation
		 */
		mask = create_pixmap(mask_width, mask_height, mask_format);

		blit.config_mask |= C2D_MASK_SURFACE_BIT;
		blit.mask_surface_id = mask->id;
	}

	blit.next = NULL;

	blit.source_rect.x = FIXED(src_x);
	blit.source_rect.y = FIXED(src_y);
	blit.source_rect.width = FIXED(w);
	blit.source_rect.height = FIXED(h);

	blit.target_rect.x = FIXED(dst_x);
	blit.target_rect.y = FIXED(dst_y);
	blit.target_rect.width = FIXED(w);
	blit.target_rect.height = FIXED(h);
	CHK(c2dDraw(dest->id, 0, NULL, 0, 0, &blit, 1));
	CHK(c2dFlush(dest->id, &curTimestamp));
	CHK(c2dWaitTimestamp(curTimestamp));

	free_pixmap(src);
	free_pixmap(dest);
	if (mask)
		free_pixmap(mask);

	RD_END();

//	dump_pixmap(dest, "copy-%04dx%04d-%08x.bmp", w, h, format);
}
Example #7
0
static int
handle_button( FL_OBJECT * obj,
               int         event,
               FL_Coord    mx,
               FL_Coord    my,
               int         key,
               void      * ev )
{
    static int oldval;
    int newval;
    FL_BUTTON_STRUCT *sp = obj->spec;
    FL_DrawButton drawit;
    FL_CleanupButton cleanup;
    int ret = FL_RETURN_NONE;

    switch ( event )
    {
        case FL_DRAW :
            sp->event = FL_DRAW;
            if (    obj->type != FL_HIDDEN_BUTTON
                 && obj->type != FL_HIDDEN_RET_BUTTON )
            {
                if ( ( drawit = lookup_drawfunc( obj->objclass ) ) )
                    drawit( obj );
                else
                    M_err( "handle_button", "Unknown button class: %d",
                           obj->objclass );
            }
            break;

        case FL_DRAWLABEL :
            sp->event = FL_DRAWLABEL;
            break;          /* TODO. Missing labels */

        case FL_LEAVE:
            /* FL_MENU_BUTTON objects never get a FL_RELEASE event,
               so we have to "fake" one */

            if ( obj->type == FL_MENU_BUTTON )
            {
                sp->event = FL_RELEASE;
                sp->is_pushed = 0;
                sp->val = 0;
            }
            /* fall through */

        case FL_ENTER :
            /* Keep active radio buttons from reacting */

            if ( obj->type == FL_RADIO_BUTTON && sp->val == 1 )
                obj->belowmouse = 0;

            sp->event = event;
            fl_redraw_object( obj );
            break;

        case FL_PUSH :
            /* Don't accept pushes for an already pushed button (e.g. if the
               user pushes another mouse button) or for mouse buttons the
               button isn't set up to react to */

            if (    sp->is_pushed )
                break;

            if (    key < FL_MBUTTON1
                 || key > FL_MBUTTON5
                 || ! sp->react_to[ key - 1 ] )
            {
                fli_int.pushobj = NULL;
                break;
            }

            sp->event = FL_PUSH;

            if ( obj->type == FL_RADIO_BUTTON )
            {
                obj->belowmouse = 0;
                sp->val = 1;
                fl_redraw_object( obj );
                return FL_RETURN_CHANGED | FL_RETURN_END;
            }

            oldval        = sp->val;
            sp->val       = ! sp->val;
            sp->is_pushed = 1;
            sp->mousebut  = key;
            sp->timdel    = 1;
            fl_redraw_object( obj );

            if ( obj->type == FL_MENU_BUTTON )
                ret |= FL_RETURN_END;

            if (    obj->type == FL_INOUT_BUTTON
                 || obj->type == FL_MENU_BUTTON
                 || obj->type == FL_TOUCH_BUTTON )
                ret |= FL_RETURN_CHANGED;
            break;

        case FL_MOTION :
            if (    obj->type == FL_RADIO_BUTTON
                 || obj->type == FL_INOUT_BUTTON
                 || obj->type == FL_MENU_BUTTON )
                break;

            newval = sp->val;

            if ( WITHIN( obj, mx, my ) )
            {
                obj->belowmouse = 1;
                if ( sp->react_to[ key - 1 ] )
                    newval = ! oldval;
            }
            else
            {
                obj->belowmouse = 0;
                if ( sp->react_to[ key - 1 ] )
                    newval = oldval;
            }

            if ( sp->val != newval )
            {
                sp->val = newval;
                fl_redraw_object( obj );
            }
            break;

        case FL_RELEASE :
            if ( key != sp->mousebut && obj->type != FL_RADIO_BUTTON )
            {
                fli_int.pushobj = obj;
                break;
            }

            sp->event = FL_RELEASE;
            sp->is_pushed = 0;

            if ( obj->type == FL_INOUT_BUTTON && ! WITHIN( obj, mx, my ) )
                obj->belowmouse = 0;

            if ( obj->type == FL_PUSH_BUTTON )
            {
                fl_redraw_object( obj );
                if ( sp->val != oldval )
                    ret |= FL_RETURN_END | FL_RETURN_CHANGED;
            }
            else if ( sp->val == 0 && obj->type != FL_MENU_BUTTON )
                fl_redraw_object( obj );
            else
            {
                sp->val = 0;
                fl_redraw_object( obj );

                if (    obj->type != FL_MENU_BUTTON
                     && obj->type != FL_TOUCH_BUTTON )
                    ret |= FL_RETURN_END | FL_RETURN_CHANGED;

                if ( obj->type == FL_TOUCH_BUTTON )
                    ret |= FL_RETURN_END;
            }

            break;

        case FL_UPDATE :                /* only FL_TOUCH_BUTTON receives it */
            sp->event = FL_UPDATE;
            if (    sp->val
                 && sp->timdel++ > 10
                 && ( sp->timdel & 1 ) == 0 )
                ret |= FL_RETURN_CHANGED;
            break;

        case FL_SHORTCUT :
            sp->event = FL_SHORTCUT;

            /* This is a horrible hack */

            if ( obj->type == FL_PUSH_BUTTON || obj->type == FL_RADIO_BUTTON )
            {
                sp->val = ! sp->val;
                obj->pushed = obj->type == FL_RADIO_BUTTON;
                fl_redraw_object( obj );
                wait_for_release( ev );
            }
            else if (    obj->type == FL_NORMAL_BUTTON
                      || obj->type == FL_RETURN_BUTTON )
            {
                int obl = obj->belowmouse;

                sp->val = obj->belowmouse = 1;
                fl_redraw_object( obj );
                wait_for_release( ev );
                sp->val = 0;
                obj->belowmouse = obl;
                fl_redraw_object( obj );
            }
            sp->mousebut = FL_SHORTCUT + key;
            ret |= FL_RETURN_END | FL_RETURN_CHANGED;
            break;

        case FL_FREEMEM :
            if ( ( cleanup = lookup_cleanupfunc( obj->objclass ) ) )
                cleanup( sp );
            free_pixmap( sp );
            fli_safe_free( obj->spec );
            break;
    }

    return ret;
}
Example #8
0
int save_pixmap(struct pixmap *p, char *name, int orientation, int format)
{
	struct pixmap	*to_be_saved = p,
					*p2 = NULL;
	char			 fname[1024];
	FILE			*ofp = NULL;
	int				 retval;

	/*
	 *	Rotate image
	 */

	switch (orientation) {
		case ROT_LEFT:
			p2 = rotate_left(p);
			to_be_saved = p2;
			break;
		case ROT_HEADDOWN:
			p2 = rotate_right(p);
			to_be_saved = rotate_right(p2);
			free_pixmap(p2);
			p2 = to_be_saved;
			break;
		case ROT_RIGHT:
			p2 = rotate_right(p);
			to_be_saved = p2;
		case ROT_STRAIGHT:
		default:
			break;
	}

	/*
	 *	Build the image name
	 */

	strcpy(fname, name);
	strcat(fname, ".");
	switch (format & SAVE_FORMATS) {
#ifdef USE_JPEG
		case SAVE_JPEG:
			strcat(fname, JPEG_EXT);
			break;
#endif /* USE_JPEG */
#ifdef USE_TIFF
		case SAVE_TIFF:
			strcat(fname, TIFF_EXT);
			break;
#endif /* USE_TIFF */
#ifdef USE_PNG
		case SAVE_PNG:
			strcat(fname, PNG_EXT);
			break;
#endif /* USE_PNG */
		default:
			strcat(fname, (to_be_saved->components == 3) ? PPM_EXT : PGM_EXT );
			break;
	}

	/*
	 *	Open the output file, if necessary
	 */

	switch (format & SAVE_FORMATS) {
#ifdef USE_JPEG
		case SAVE_JPEG:
#endif /* USE_JPEG */
#ifdef USE_PNG
		case SAVE_PNG:
#endif /* USE_PNG */
		default:
			if ((ofp = fopen(fname, "wb")) == NULL) {
				if (!quiet) {
					perror("fopen");
					fprintf(stderr, "%s: save_pixmap: cannot open %s for output\n", __progname, fname);
				}
				if (p2) free_pixmap(p2);
				return -1;
			}
#ifdef USE_TIFF
		case SAVE_TIFF:
#endif /* USE_TIFF */
			break;
	}

	/*
	 *	Save the image
	 */

	switch (format & SAVE_FORMATS) {
#ifdef USE_JPEG
		case SAVE_JPEG:
			retval = save_pixmap_jpeg(to_be_saved, quality, ofp);
			break;
#endif /* USE_JPEG */
#ifdef USE_TIFF
		case SAVE_TIFF:
			retval = save_pixmap_tiff(to_be_saved, tiff_compression, quality, tiff_predictor, fname);
			break;
#endif /* USE_TIFF */
#ifdef USE_PNG
		case SAVE_PNG:
			retval = save_pixmap_png(to_be_saved, ofp);
			break;
#endif /* USE_PNG */
		default:
			retval = save_pixmap_pxm(to_be_saved, ofp);
			break;
	}

	if (ofp) fclose(ofp);

	if (p2) free_pixmap(p2);

	return retval;
}
Example #9
0
int
lincity_main (int argc, char *argv[])
{
#if defined (LC_X11)
    char *geometry = NULL;
#endif

#if defined (SVGALIB)
    int q;
    vga_init ();
#endif

#if !defined (WIN32)
    signal (SIGPIPE, SIG_IGN);    /* broken pipes are ignored. */
#endif

    /* Initialize some global variables */
    make_dir_ok_flag = 1;
    main_screen_originx = 1;
    main_screen_originy = 1;
    given_scene[0] = 0;
    quit_flag = network_flag = load_flag = save_flag 
	    = prefs_flag = cheat_flag = monument_bul_flag
	    = river_bul_flag = shanty_bul_flag;
    prefs_drawn_flag = 0;
    kmouse_val = 8;

#ifdef LC_X11
    borderx = 0;
    bordery = 0;
    parse_xargs (argc, argv, &geometry);
#endif

    /* I18n */
    lincity_set_locale ();

    /* Set up the paths to certain files and directories */
    init_path_strings ();

    /* Make sure that things are installed where they should be */
    verify_package ();

    /* Make sure the save directory exists */
    check_savedir ();

    /* Load preferences */
    load_lincityrc ();

#ifndef CS_PROFILE
#ifdef SEED_RAND
    srand (time (0));
#endif
#endif

#ifdef LC_X11
#if defined (commentout)
    borderx = 0;
    bordery = 0;
    parse_xargs (argc, argv, &geometry);
#endif
    Create_Window (geometry);
    pirate_cursor = XCreateFontCursor (display.dpy, XC_pirate);
#elif defined (WIN32)
    /* Deal with all outstanding messages */
    ProcessPendingEvents ();
#else
    parse_args (argc, argv);
    q = vga_setmode (G640x480x256);
    gl_setcontextvga (G640x480x256);
#endif

#if defined (WIN32) || defined (LC_X11)
    initialize_pixmap ();
#endif

    init_fonts ();

#if defined (SKIP_OPENING_SCENE)
    skip_splash_screen = 1;
#endif
    if (!skip_splash_screen) {
	load_start_image ();
    }

#ifdef LC_X11
    unlock_window_size ();
#endif

    Fgl_setfont (8, 8, main_font);
    Fgl_setfontcolors (TEXT_BG_COLOUR, TEXT_FG_COLOUR);

    initialize_geometry (&scr);

#if defined (SVGALIB)
    set_vga_mode ();
#endif

    initialize_monthgraph ();
    init_mouse_registry ();
    init_mini_map_mouse ();

#ifdef LC_X11
    x_key_value = 0;
#elif defined (WIN32)
    RefreshScreen ();
#endif
    setcustompalette ();
    draw_background ();
    prog_box (_("Loading the game"), 1);
    init_types ();
    init_modules();
    init_mappoint_array ();
    initialize_tax_rates ();
    prog_box ("", 95);
    mouse_hide_count = 0;
    suppress_ok_buttons = 0;
    prog_box ("", 100);
#ifdef USE_PIXMAPS
    prog_box (_("Creating pixmaps"), 1);
    init_pixmaps ();
    prog_box ("", 100);
#endif
    //draw_normal_mouse (1, 1);
#if defined (LC_X11)
    init_x_mouse ();
#endif
    init_timer_buttons();
    mouse_initialized = 1;
    //set_selected_module (CST_TRACK_LR);
    screen_setup ();

    /* Main loop! */
    client_main_loop ();

#if defined (SVGALIB)
    mouse_close ();
    vga_setmode (TEXT);
#endif

    print_results ();

#if defined (WIN32) || defined (LC_X11)
    free_pixmap ();
#endif

#if defined (WIN32)
    return 0;
#else
    exit (0);
#endif
}
Example #10
0
void test_multi(void)
{
	PixmapPtr src, dest;
	C2D_OBJECT blit = {};
	C2D_RECT rect;
	c2d_ts_handle curTimestamp;
	uint32_t w = 1920, h = 1080, format = xRGB;
	int i;

	DEBUG_MSG("multi: %04dx%04d-%08x", w, h, format);
	RD_START("multi", "%dx%d format:%08x", w, h, format);

	dest = create_pixmap(w, h, format);
	src  = create_pixmap(w, h, format);

	for (i = 0; i < 200; i++ ) {

		rect.x = 1;
		rect.y = 2;
		rect.width = w - 2;
		rect.height = h - 3;
		CHK(c2dFillSurface(dest->id, 0xff556677, &rect));
		CHK(c2dFillSurface(dest->id, 0xff556677, &rect));
		CHK(c2dFillSurface(dest->id, 0xff556677, &rect));
		CHK(c2dFillSurface(dest->id, 0xff556677, &rect));
		CHK(c2dFillSurface(dest->id, 0xff556677, &rect));
		CHK(c2dFillSurface(dest->id, 0xff556677, &rect));
		CHK(c2dFillSurface(dest->id, 0xff556677, &rect));
		CHK(c2dFillSurface(dest->id, 0xff556677, &rect));

		rect.x = 0;
		rect.y = 0;
		rect.width = 13;
		rect.height = 17;
		CHK(c2dFillSurface(src->id, 0xff223344, &rect));
		CHK(c2dFillSurface(src->id, 0xff223344, &rect));
		CHK(c2dFillSurface(src->id, 0xff223344, &rect));
		CHK(c2dFillSurface(src->id, 0xff223344, &rect));
		CHK(c2dFillSurface(src->id, 0xff223344, &rect));
		CHK(c2dFillSurface(src->id, 0xff223344, &rect));
		CHK(c2dFillSurface(src->id, 0xff223344, &rect));
		CHK(c2dFillSurface(src->id, 0xff223344, &rect));

		blit.surface_id = src->id;
		blit.config_mask = DEFAULT_BLIT_MASK;
		blit.next = NULL;

		blit.source_rect.x = FIXED(1);
		blit.source_rect.y = FIXED(2);
		blit.source_rect.width = FIXED(13-2);
		blit.source_rect.height = FIXED(17-4);

		blit.target_rect.x = FIXED((w - 13) / 2);
		blit.target_rect.y = FIXED((h - 17) / 2);
		blit.target_rect.width = blit.source_rect.width;
		blit.target_rect.height = blit.source_rect.height;
		CHK(c2dDraw(dest->id, 0, NULL, 0, 0, &blit, 1));
		// well, identical copy twice is fine, and I'm lazy:
		CHK(c2dDraw(dest->id, 0, NULL, 0, 0, &blit, 1));
		CHK(c2dDraw(dest->id, 0, NULL, 0, 0, &blit, 1));
		CHK(c2dDraw(dest->id, 0, NULL, 0, 0, &blit, 1));
		CHK(c2dDraw(dest->id, 0, NULL, 0, 0, &blit, 1));
		CHK(c2dDraw(dest->id, 0, NULL, 0, 0, &blit, 1));
		CHK(c2dDraw(dest->id, 0, NULL, 0, 0, &blit, 1));
		CHK(c2dDraw(dest->id, 0, NULL, 0, 0, &blit, 1));
		CHK(c2dDraw(dest->id, 0, NULL, 0, 0, &blit, 1));

		CHK(c2dFlush(dest->id, &curTimestamp));

		if (!(i % 16))
		CHK(c2dWaitTimestamp(curTimestamp));

	}

	free_pixmap(src);
	free_pixmap(dest);

	RD_END();
}