示例#1
0
文件: visual.c 项目: antrik/libggi
int GGI_libkgi_setflags(struct ggi_visual *vis, uint32_t flags)
{
  fprintf(stderr, "GGI_libkgi_setflags\n");
        LIBGGI_FLAGS(vis) = flags;
	LIBGGI_FLAGS(vis) &= GGIFLAG_ASYNC; /* Unkown flags don't take. */
        return 0;
}
示例#2
0
文件: mode.c 项目: antrik/libggi
int GGI_vcsa_setflags(struct ggi_visual *vis, uint32_t flags)
{
	LIBGGI_FLAGS(vis) = flags;
	LIBGGI_FLAGS(vis) &= GGIFLAG_ASYNC; /* Unkown flags don't take. */

	return 0;
}
示例#3
0
文件: mode.c 项目: antrik/libggi
int GGI_palemu_setflags(struct ggi_visual *vis, uint32_t flags)
{
	LIBGGI_FLAGS(vis) = flags;

	MANSYNC_SETFLAGS(vis, flags);
	LIBGGI_FLAGS(vis) &= GGIFLAG_ASYNC; /* Unkown flags don't take. */

	return 0;
}
示例#4
0
文件: mode.c 项目: Nekrofage/DoomRPi
int GGI_sub_setflags(ggi_visual *vis,ggi_flags flags)
{
	int rc;
	ggi_sub_priv *priv = SUB_PRIV(vis);

	rc = ggiSetFlags(priv->parent, flags);
	if (rc < 0) return rc;

	LIBGGI_FLAGS(vis) = flags;
	LIBGGI_FLAGS(vis) &= GGIFLAG_ASYNC; /* Unkown flags don't take. */

	return 0;	
}
示例#5
0
文件: ddinit.c 项目: antrik/libggi
int
GGI_directx_DDChangeMode(struct ggi_visual *vis, ggi_mode *mode)
{
	directx_priv *priv = GGIDIRECTX_PRIV(vis);
	/* destroy any existing surface */
	DDDestroySurface(priv);

	/* recreate the primary surface and back storage */
	if (!DDCreateSurface(priv, mode))
		return 0;

	if (!priv->fullscreen)
		/* set the new window size */
		DDChangeWindow(priv, mode->visible.x, mode->visible.y);

	/* set a timer to have the window refreshed at regular intervals,
	   and show the window */
	if (!(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC))
		priv->timer_id = SetTimer(priv->hWnd, 1, 33, NULL);
	ShowWindow(priv->hWnd, SW_SHOWNORMAL);
	if (priv->hParent == NULL)
		SetForegroundWindow(priv->hWnd);

	return 1;
}
示例#6
0
文件: mode.c 项目: antrik/libggi
int GGI_palemu_setmode(struct ggi_visual *vis, ggi_mode *mode)
{ 
	ggi_palemu_priv *priv = PALEMU_PRIV(vis);
	int err;

	DPRINT_MODE("display-palemu: setmode %dx%d#%dx%dF%d[0x%02x]\n",
			mode->visible.x, mode->visible.y,
			mode->virt.x, mode->virt.y, 
			mode->frames, mode->graphtype);

	MANSYNC_ignore(vis);

	if ((err = ggiCheckMode(vis->instance.stem, mode)) != 0) {
		return err;
	}

	_ggiZapMode(vis, 0);

	*LIBGGI_MODE(vis) = *mode;
	
	priv->parent_mode.visible = mode->visible;
	priv->parent_mode.virt    = mode->virt;
	priv->parent_mode.dpp     = mode->dpp;
	priv->parent_mode.size    = mode->size;
	priv->parent_mode.frames  = 1;

	if ((err = do_setmode(vis)) != 0) {
		DPRINT_MODE("display-palemu: setmode failed (%d).\n", err);
		return err;
	}

	priv->squish.x = mode->visible.x / target_width;
	priv->squish.y = mode->visible.y / target_height;

	DPRINT_MODE("display-palemu: Attempting to setmode on parent "
		"visual...\n");

	if (priv->target == PALEMU_TARGET) {
		err = _ggi_palemu_Open(vis);
	} else {
		err = _ggi_monotext_Open(vis);
	}
	if (err != 0) {
		return err;
	}

	/* Initialize palette */
	ggiSetColorfulPalette(vis->instance.stem);

	MANSYNC_SETFLAGS(vis, LIBGGI_FLAGS(vis));
	MANSYNC_cont(vis);

	DPRINT_MODE("display-palemu: setmode succeeded.\n");

	return 0;
}
示例#7
0
static int
GGI_directx_setflags(ggi_visual *vis, ggi_flags flags)
{
	directx_priv *priv = GGIDIRECTX_PRIV(vis);

	if ((LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC) && !(flags & GGIFLAG_ASYNC))
		ggiFlush(vis);
	/* Clear out unknown flags */
	LIBGGI_FLAGS(vis) = flags & GGIFLAG_ASYNC;

	if(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC) {
		if (priv->timer_id)
			KillTimer(priv->hWnd, priv->timer_id);
		priv->timer_id = 0;
	}
	else
		priv->timer_id = SetTimer(priv->hWnd, 1, 33, NULL);
	return GGI_OK;
}
示例#8
0
文件: buffer.c 项目: antrik/libggi
int GGI_X_db_acquire(struct ggi_resource *res, uint32_t actype) {
	struct ggi_visual *vis;
	vis = res->priv;
	if ((LIBGGI_FLAGS(vis) & GGIFLAG_TIDYBUF) &&
	    (vis->w_frame->resource == res) && 
	    (actype & GGI_ACTYPE_WRITE)) {
		if (GGIX_PRIV(vis)->opmansync) MANSYNC_stop(vis);
	}
	res->curactype = actype;
	res->count++;
	return 0;
}
示例#9
0
文件: visual.c 项目: antrik/libggi
static int GGIexit(struct ggi_visual *vis, struct ggi_dlhandle *dlh)
{
	if (PALEMU_PRIV(vis) && PALEMU_PRIV(vis)->opmansync) {
		if (!(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC)) {
			MANSYNC_stop(vis);
		}
		MANSYNC_deinit(vis);
		MANSYNC_close(PALEMU_PRIV(vis));
	}

	return 0;
}
示例#10
0
文件: buffer.c 项目: antrik/libggi
int GGI_X_db_release(struct ggi_resource *res) {
	struct ggi_visual *vis;
	vis = res->priv;
	if ((vis->w_frame->resource == res) && 
	    (res->curactype & GGI_ACTYPE_WRITE)) {
		if (LIBGGI_FLAGS(vis) & GGIFLAG_TIDYBUF) {
			if (GGIX_PRIV(vis)->opmansync) MANSYNC_start(vis);
		} else {
			_ggiFlush(vis);
		}
	}
	res->curactype = 0;
	res->count--;
	return 0;
}
示例#11
0
文件: mode.c 项目: antrik/libggi
int GGI_trueemu_setmode(struct ggi_visual *vis, ggi_mode *mode)
{ 
	ggi_trueemu_priv *priv = TRUEEMU_PRIV(vis);
	int err;

	DPRINT_MODE("display-trueemu: setmode %dx%d#%dx%dF%d[0x%02x]\n",
			mode->visible.x, mode->visible.y,
			mode->virt.x, mode->virt.y, 
			mode->frames, mode->graphtype);

	MANSYNC_ignore(vis);

	if ((err = ggiCheckMode(vis->instance.stem, mode)) != 0) {
		return err;
	}

	_ggiZapMode(vis, 0);

	*LIBGGI_MODE(vis) = *mode;

	priv->mode.visible = mode->visible;
	priv->mode.virt    = mode->virt;
	priv->mode.dpp     = mode->dpp;
	priv->mode.size    = mode->size;
	priv->mode.frames  = 1;

	if ((err = do_setmode(vis)) != 0) {
		DPRINT_MODE("display-trueemu: setmode failed (%d).\n", err);
		return err;
	}

	DPRINT_MODE("display-trueemu: Attempting to setmode on parent "
		"visual...\n");

	if ((err = _ggi_trueemu_Open(vis)) != 0) {
		return err;
	}

	MANSYNC_SETFLAGS(vis, LIBGGI_FLAGS(vis));
	MANSYNC_cont(vis);

	DPRINT_MODE("display-trueemu: setmode succeeded.\n");

	return 0;
}
示例#12
0
文件: line.c 项目: Nekrofage/DoomRPi
int GGI_kgi_radeon_drawline_2d(ggi_visual *vis, int x1, int y1, int x2, int y2)
{
	struct {
	
		cce_type3_header_t h;
		cce_gui_control_t gc;
		cce_scissor_t tl;
		cce_scissor_t br;
		uint32_t bp;
		cce_polyline_t pl;
	} packet;

	memset(&packet, 0, sizeof(packet));
	
	packet.h.it_opcode = CCE_IT_OPCODE_POLYLINE;
	packet.h.count     = sizeof(packet) / 4 - 2;
	packet.h.type      = 0x3;

	packet.gc.dst_clipping = 1;
	packet.gc.brush_type = 14;
	packet.gc.dst_type   = RADEON_CONTEXT(vis)->dst_type;
	packet.gc.src_type   = 3;
	packet.gc.win31_rop  = ROP3_PATCOPY;

	packet.gc.dst_type = RADEON_CONTEXT(vis)->dst_type;

	packet.tl.x = LIBGGI_GC(vis)->cliptl.x;
	packet.tl.y = LIBGGI_GC(vis)->cliptl.y;
	packet.br.x = LIBGGI_GC(vis)->clipbr.x;
	packet.br.y = LIBGGI_GC(vis)->clipbr.y;

	packet.bp = LIBGGI_GC_FGCOLOR(vis);

	packet.pl.x0 = x1;
	packet.pl.y0 = y1;
	packet.pl.x1 = x2;
	packet.pl.y1 = y2;

	RADEON_WRITEPACKET(vis, packet);
        if (!(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC)) RADEON_FLUSH(vis);

	return 0;
}
示例#13
0
文件: line.c 项目: Nekrofage/DoomRPi
int GGI_kgi_radeon_drawline_3d(ggi_visual *vis, int x1, int y1, int x2, int y2)
{
	struct {
		cce_type3_header_t h;
		cce_se_se_vtx_fmt_t vfmt;
		cce_se_se_vf_cntl_t vctl;
		/* TODO: this wrongly assumes float is 32 bit everywhere. */
	  float v1x, v1y; /* v1z; */ 
	  float v2x, v2y; /* v2z; */ 
	} packet;

	RADEON_RESTORE_CTX(vis, RADEON_SOLIDFILL_CTX);
	
	memset(&packet, 0, sizeof(packet));
	packet.h.it_opcode = CCE_IT_OPCODE_3D_DRAW_IMMD;
	packet.h.count     = (sizeof(packet) / 4) - 2;
	packet.h.type      = 3;

	packet.vfmt.z = 0 /* 1 */;

	packet.vctl.num_vertices = 2;
	packet.vctl.en_maos = 1;
	packet.vctl.fmt_mode = 1;
	packet.vctl.prim_walk = 3;   /* Vertex data follows in packet. */
	packet.vctl.prim_type = 2;   /* Line list */

	packet.v1x = x1;
	packet.v1y = y1;
	packet.v2x = x2;
	packet.v2y = y2;

	/*	packet.v1z = packet.v2z = packet.v3z = 0; */
	
	RADEON_WRITEPACKET(vis, packet);
        if (!(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC)) RADEON_FLUSH(vis);

	return 0;
}
示例#14
0
文件: buffer.c 项目: antrik/libggi
int GGI_X_setwriteframe_slave(struct ggi_visual *vis, int num) {
	int err;
	ggi_x_priv *priv;
	ggi_directbuffer *db;

	db = _ggi_db_find_frame(vis, num);

        if (db == NULL) {
                return GGI_ENOSPACE;
        }
	
	priv = GGIX_PRIV(vis);
	if (LIBGGI_FLAGS(vis) & GGIFLAG_TIDYBUF) {
		if (priv->opmansync && (GGI_ACTYPE_WRITE & 
					(vis->w_frame->resource->curactype ^
					 db->resource->curactype))) {
			vis->w_frame_num = num;
			vis->w_frame = db;
			if (GGI_ACTYPE_WRITE & db->resource->curactype) 
				MANSYNC_stop(vis);
			else {
				MANSYNC_start(vis);
			}
		} else {
			vis->w_frame_num = num;
			vis->w_frame = db;
		}
	} else {
	  	_ggiFlush(vis);
		vis->w_frame_num = num;
		vis->w_frame = db;
	}
        /* Dirty region doesn't span frames. */
        priv->dirtytl.x = 1; priv->dirtybr.x = 0;
	err = priv->slave->opdraw->setwriteframe(priv->slave, num);
	return err;
}
示例#15
0
文件: mode.c 项目: Nekrofage/DoomRPi
int GGI_vgl_setflags(ggi_visual *vis,ggi_flags flags)
{
	LIBGGI_FLAGS(vis)=flags;
	LIBGGI_FLAGS(vis) &= GGIFLAG_ASYNC; /* Unkown flags don't take. */
	return 0;
}
示例#16
0
文件: visual.c 项目: antrik/libggi
static int GGIopen_monotext(struct ggi_visual *vis, struct ggi_dlhandle *dlh,
				const char *args, void *argptr, uint32_t *dlret)
{
	ggi_palemu_priv *priv;
	gg_option options[MONOTEXT_NUM_OPTS];
	char target[1024];
	struct gg_api *api;
	struct gg_observer *obs = NULL;
	int val;
	int err = 0;

	DPRINT("display-monotext: GGIopen start.\n");

	memcpy(options, monotext_optlist, sizeof(options));
	if (args) {
		args = ggParseOptions(args, options, MONOTEXT_NUM_OPTS);
		if (args == NULL) {
			fprintf(stderr,
				"display-monotext: error in arguments\n");
			return GGI_EARGINVAL;
		}
	}

	/* open the parent visual */
	DPRINT("display-monotext: opening target: %s\n", args);

	if (args != NULL) {
		if (ggParseTarget(args, target, sizeof(target)) == NULL) {
			/* error occured */
			return GGI_EARGINVAL;
		}
	}

	/* Find out the parent target */
	while (args && *args && isspace((uint8_t)*args)) {
		args++;
	}

	*target = '\0';
	if (args) {
		if (ggParseTarget(args, target, sizeof(target)) == NULL) {
			return GGI_EARGINVAL;
		}
	}

	if (*target == '\0') {
		strcpy(target, "auto");
	}

	LIBGGI_GC(vis) = malloc(sizeof(ggi_gc));
	if (LIBGGI_GC(vis) == NULL) {
		err = GGI_ENOMEM;
		goto err0;
	}
	LIBGGI_PRIVATE(vis) = priv = malloc(sizeof(ggi_palemu_priv));
	if (priv == NULL) {
		err = GGI_ENOMEM;
		goto err1;
	}

	priv->flush_lock = ggLockCreate();
	if (priv->flush_lock == NULL) {
		err = GGI_ENOMEM;
		goto err2;
	}
	priv->opmansync = malloc(sizeof(_ggi_opmansync));
	if (priv->opmansync == NULL) {
		err = GGI_ENOMEM;
		goto err3;
	}

	priv->flags = 0;
	priv->fb_ptr = NULL;
	priv->target = MONOTEXT_TARGET;


	DPRINT("display-monotext: opening target: %s\n", target);
	priv->parent = ggNewStem(NULL);
	if (priv->parent == NULL) {
		fprintf(stderr,
			"display-monotext: Failed to create stem for target: %s\n",
			target);
		err = GGI_ENODEVICE;
		goto err3;
	}

	/* XXX Should iterate over the apis attached to vis->instance.stem
	 * instead of only looking for ggi and gii.
	 */
	if (ggiAttach(priv->parent) < 0) {
		ggDelStem(priv->parent);
		priv->parent = NULL;
		fprintf(stderr,
			"display-monotext: Failed to attach ggi to stem for target: %s\n",
			target);
		err = GGI_ENODEVICE;
		goto err4;
	}

	api = ggGetAPIByName("gii");
	if (api != NULL) {
		/* XXX This should probably be done in pseudo-stubs-gii */
		if (STEM_HAS_API(vis->instance.stem, api)) {
			if (ggAttach(api, priv->parent) < 0) {
				ggDelStem(priv->parent);
				priv->parent = NULL;
				fprintf(stderr,
					"Failed to attach gii to stem for target: %s\n",
					target);
				err = GGI_ENODEVICE;
				goto err4;
			}
			obs = ggObserve(GG_STEM_API_CHANNEL(priv->parent, api),
					transfer_gii_src, vis->instance.stem);
		}
	}

	if (ggiOpen(priv->parent, target, NULL) < 0) {
		if (obs) {
			ggDelObserver(obs);
			obs = NULL;
		}
		fprintf(stderr,
			"display-monotext: Failed to open target: '%s'\n",
			target);
		ggDelStem(priv->parent);
		priv->parent = NULL;
		err = GGI_ENODEVICE;
		goto err4;
	}
	if (obs) {
		ggDelObserver(obs);
		obs = NULL;
	}

	ggiSetFlags(priv->parent, GGIFLAG_ASYNC);


	/* set defaults */
	priv->parent_defmode.graphtype = GT_TEXT16;
	priv->flags = 0;
	priv->squish.x = priv->squish.y = 1;

	val = strtol(options[OPT_A].result, NULL, 0);	
	if (val != 0) {
		priv->accuracy.x = priv->accuracy.y = val;
	} else {
		priv->accuracy.x = strtol(options[OPT_X].result, NULL, 0);
		priv->accuracy.y = strtol(options[OPT_Y].result, NULL, 0);
	}

	/* Setup mansync */
	MANSYNC_open(vis, priv);
	if (priv->mod_mansync == NULL) {
		fprintf(stderr,
			"display-monotext: Cannot load helper-mansync!\n");
		GGIclose_monotext(vis, dlh);
		goto err4;
	}

	MANSYNC_init(vis);
	if (!(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC)) {
		MANSYNC_start(vis);
	}

	/* Has mode management */
	vis->opdisplay->getmode   = GGI_palemu_getmode;
	vis->opdisplay->setmode   = GGI_palemu_setmode;
	vis->opdisplay->checkmode = GGI_monotext_checkmode;
	vis->opdisplay->getapi    = GGI_palemu_getapi;
	vis->opdisplay->flush     = GGI_palemu_flush;
	vis->opdisplay->setflags  = GGI_palemu_setflags;

	DPRINT("display-monotext: GGIopen succeeded.\n");

	*dlret = GGI_DL_OPDISPLAY;
	return 0;

err4:
	free(priv->opmansync);
err3:
	ggLockDestroy(priv->flush_lock);
err2:
	free(priv);
err1:
	free(LIBGGI_GC(vis));
err0:
	return err;
}
示例#17
0
文件: visual.c 项目: antrik/libggi
static int GGIopen_palemu(struct ggi_visual *vis, struct ggi_dlhandle *dlh,
		   const char *args, void *argptr, uint32_t *dlret)
{
	ggi_palemu_priv *priv;
	gg_option options[PALEMU_NUM_OPTS];
	char target[1024];
	int err = GGI_ENOMEM;
	struct gg_api *api;
	struct gg_observer *obs = NULL;

	DPRINT("display-palemu: GGIopen start.\n");

	/* handle arguments */
	memcpy(options, palemu_optlist, sizeof(options));
	if (args) {
		args = ggParseOptions(args, options, PALEMU_NUM_OPTS);

		if (args == NULL) {
			fprintf(stderr,
				"display-palemu: error in arguments.\n");
			return GGI_EARGINVAL;
		}
	}
	if (getenv("GGI_PALEMU_OPTIONS") != NULL) {
		if (ggParseOptions(getenv("GGI_PALEMU_OPTIONS"), options,
				   PALEMU_NUM_OPTS) == NULL) {
			fprintf(stderr, "display-palemu: error in ""$GGI_PALEMU_OPTIONS.\n");
			return GGI_EARGINVAL;
		}
	}

	/* Find out the parent target. */
	while (args && *args && isspace((uint8_t)*args)) {
		args++;
	}

	*target = '\0';
	if (args) {
		if (ggParseTarget(args, target, 1024) == NULL) {
			return GGI_EARGINVAL;
		}
	}
	if (*target == '\0') {
		strcpy(target, "auto");
	}

	LIBGGI_GC(vis) = malloc(sizeof(ggi_gc));
	if (LIBGGI_GC(vis) == NULL) {
		return GGI_ENOMEM;
	}
	LIBGGI_PRIVATE(vis) = priv = malloc(sizeof(*priv));
	if (priv == NULL) {
		goto out_freegc;
	}
	priv->flush_lock = ggLockCreate();
	if (priv->flush_lock == NULL) {
		goto out_freepriv;
	}
	priv->opmansync = malloc(sizeof(_ggi_opmansync));
	if (priv->opmansync == NULL) {
		goto out_freelock;
	}

	priv->flags  = 0;
	priv->fb_ptr = NULL;
	priv->target = PALEMU_TARGET;

	DPRINT("display-palemu: parent mode is '%s'\n",
		  options[OPT_PARENT].result);
	ggiParseMode(options[OPT_PARENT].result, &priv->parent_defmode);

	DPRINT("display-palemu: opening target: %s\n", target);
	priv->parent = ggNewStem(NULL);
	if (priv->parent == NULL) {
		fprintf(stderr,
			"display-palemu: Failed to create stem for target: '%s'\n",
			target);
		err = GGI_ENODEVICE;
		goto out_freeopmansync;
	}
	/* FIXME! Should iterate over the apis attached to vis->instance.stem
	 * instead of only looking for ggi and gii.
	 */
	if (ggiAttach(priv->parent) < 0) {
		ggDelStem(priv->parent);
		priv->parent = NULL;
		fprintf(stderr,
			"display-palemu: Failed to attach ggi to stem for target: '%s'\n",
			target);
		err = GGI_ENODEVICE;
		goto out_freeopmansync;
	}
	if ((api = ggGetAPIByName("gii")) != NULL) {
		/* FIXME! This should probably be done in pseudo-stubs-gii */
		if (STEM_HAS_API(vis->instance.stem, api)) {
			if (ggAttach(api, priv->parent) < 0) {
				ggDelStem(priv->parent);
				priv->parent = NULL;
				fprintf(stderr,
					"display-palemu: Failed to attach gii to stem for target: '%s'\n",
					target);
				err = GGI_ENODEVICE;
				goto out_freeopmansync;
			}
			obs = ggObserve(GG_STEM_API_CHANNEL(priv->parent, api),
			    transfer_gii_src, vis->instance.stem);
		}
	}
	if (ggiOpen(priv->parent, target, NULL) < 0) {
		if (obs) {
			ggDelObserver(obs);
			obs = NULL;
		}
		fprintf(stderr,
			"display-palemu: Failed to open target: '%s'\n",
			target);
		ggDelStem(priv->parent);
		priv->parent = NULL;
		err = GGI_ENODEVICE;
		goto out_freeopmansync;
	}
	if (obs) {
		ggDelObserver(obs);
		obs = NULL;
	}

	ggiSetFlags(priv->parent, GGIFLAG_ASYNC);

	/* Setup mansync */
	MANSYNC_open(vis, priv);
	if (priv->mod_mansync == NULL) {
		fprintf(stderr,
			"display-palemu: Cannot load helper-mansync!\n");
		GGIclose_palemu(vis, dlh);
		return err;
	}

	MANSYNC_init(vis);
	if (!(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC)) {
		MANSYNC_start(vis);
	}

	/* Has mode management */
	vis->opdisplay->getmode = GGI_palemu_getmode;
	vis->opdisplay->setmode = GGI_palemu_setmode;
	vis->opdisplay->checkmode = GGI_palemu_checkmode;
	vis->opdisplay->getapi = GGI_palemu_getapi;
	vis->opdisplay->flush = GGI_palemu_flush;
	vis->opdisplay->setflags = GGI_palemu_setflags;

	DPRINT("display-palemu: GGIopen succeeded.\n");

	*dlret = GGI_DL_OPDISPLAY;
	return 0;

  out_freelock:
	ggLockDestroy(priv->flush_lock);
  out_freeopmansync:
	free(priv->opmansync);
  out_freepriv:
	free(priv);
  out_freegc:
	free(LIBGGI_GC(vis));

	return err;
}
示例#18
0
文件: line.c 项目: Nekrofage/DoomRPi
int GGI_kgi_radeon_putvline_3d(ggi_visual *vis, int x, int y, int h, const void *buf)
{
	int wb, w32;
	radeon_context_t *ctx;

	struct {
		cce_type3_header_t h;
		cce_se_se_vtx_fmt_t vfmt;
		cce_se_se_vf_cntl_t vctl;
		/* TODO: this wrongly assumes float is 32 bit everywhere. */
		float v1x, v1y, v1s, v1t; /* v1z; */ 
		float v2x, v2y, v2s, v2t; /* v2z; */ 
		float v3x, v3y, v3s, v3t; /* v3z; */ 
	} packet;
	struct {
		cce_type0_header_t h;
		uint32_t txoffset;
	} offsetpkt;


	ctx = RADEON_CONTEXT(vis);

	wb = GT_ByPP(LIBGGI_GT(vis)) * h;
	w32 = ((wb + 31) / 32) * 32;

	if (ctx->ctx_loaded != RADEON_PUT_CTX) {
		ctx->put_ctx.tex_size.usize = w32 / GT_ByPP(LIBGGI_GT(vis));
		ctx->put_ctx.tex_size.vsize = 1;
		ctx->put_ctx.txpitch.txpitch = (w32/32) - 1;
		RADEON_RESTORE_CTX(vis, RADEON_PUT_CTX);
	} else {
		struct {
			cce_type0_header_t h;
			pp_tex_size_t tex_size;
			pp_txpitch_t txpitch;
		} packet2;

		memset(&packet2, 0, sizeof(packet2));

		packet2.h.base_index = PP_TEX_SIZE_1 >> 2;
		packet2.h.count = 1;
		packet2.tex_size.usize = w32 / GT_ByPP(LIBGGI_GT(vis));
		packet2.tex_size.vsize = 1;
		packet2.txpitch.txpitch = (w32/32) - 1;
		
		RADEON_RESTORE_CTX(vis, RADEON_BASE_CTX);
		RADEON_WRITEPACKET(vis, packet2);
		ctx->ctx_loaded = RADEON_PUT_CTX;
	}

	memset(&packet, 0, sizeof(packet));

	packet.h.it_opcode = CCE_IT_OPCODE_3D_DRAW_IMMD;
	packet.h.count     = 13;
	packet.h.type      = 3;

	packet.vfmt.st0 = 1;
	packet.vfmt.z = 0 /* 1 */;

	packet.vctl.num_vertices = 3;
	packet.vctl.en_maos = 1;
	packet.vctl.fmt_mode = 1;
	packet.vctl.prim_walk = 3;   /* Vertex data follows in packet. */
	packet.vctl.prim_type = 8;   /* Rectangle list */

	packet.v1x = packet.v3x = x;
	packet.v2x = x + 1;
	packet.v1y = packet.v2y = y;
	packet.v3y = y + h;
	packet.v1s = packet.v2s = 0;
        packet.v3s = h;
	packet.v1t = packet.v3t = 1;
	packet.v2t = 0;

	memset(&offsetpkt, 0, sizeof(offsetpkt));
	offsetpkt.h.base_index = PP_TXOFFSET_1 >> 2;

	if ((KGI_PRIV(vis)->swatch_size - ctx->swatch_inuse) < w32) {
		/* idleaccel */
	        ctx->swatch_inuse = 0;
	}

	offsetpkt.txoffset = 
	  (uint32_t)KGI_PRIV(vis)->swatch_gp + ctx->swatch_inuse;

	RADEON_WRITEPACKET(vis, offsetpkt);

	memcpy(KGI_PRIV(vis)->swatch + ctx->swatch_inuse,
	       (char *)buf, wb);
	
	RADEON_WRITEPACKET(vis, packet);

	if (!(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC)) RADEON_FLUSH(vis);	
	return 0;
}
示例#19
0
文件: buffer.c 项目: antrik/libggi
int GGI_X_flush_ximage_child(struct ggi_visual *vis, 
			     int x, int y, int w, int h, int tryflag)
{
	ggi_x_priv *priv;
	int mansync;
	priv = GGIX_PRIV(vis);

	if (tryflag == 0) {
		/* flush later, this is in signal handler context
		 * when using the signal based scheduler
		 */
		ggUnlock(priv->flushlock);
		return 0;
	}

	if (priv->opmansync) MANSYNC_ignore(vis);
	mansync = 1; /* Do we call MANSYNC_cont later? By default, yes. */

	if (tryflag != 2) GGI_X_LOCK_XLIB(vis);

	_ggi_x_flush_cmap(vis);		/* Update the palette/gamma */

	/* Flush any pending Xlib operations. */
	XSync(priv->disp, 0);

	if (priv->fullflush || 
	    (GGI_ACTYPE_WRITE & vis->w_frame->resource->curactype)) {
		/* Flush all requested data */
		if (tryflag != 2) {
			GGI_X_CLEAN(vis, x, y, w, h);
			y = GGI_X_WRITE_Y;
		} /* else it's a non-translated exposure event. */
		XPutImage(priv->disp, priv->drawable, priv->tempgc, priv->ximage, 
			  x, y, x, y, (unsigned)w, (unsigned)h);
		if (LIBGGI_FLAGS(vis) & GGIFLAG_TIDYBUF) mansync = 0;
	} else {
		/* Just flush the intersection with the dirty region */
 	  	int x2, y2;

		if (priv->dirtytl.x > priv->dirtybr.x) goto clean;
		if (x > priv->dirtybr.x) goto clean;
		if (y > priv->dirtybr.y) goto clean;
		x2 = x + w - 1;
		if (x2 < priv->dirtytl.x) goto clean;
		y2 = y + h - 1;
		if (y2 < priv->dirtytl.y) goto clean;
		if (x < priv->dirtytl.x)  x  = priv->dirtytl.x;
		if (y < priv->dirtytl.y)  y  = priv->dirtytl.y;
		if (x2 > priv->dirtybr.x) x2 = priv->dirtybr.x;
		if (y2 > priv->dirtybr.y) y2 = priv->dirtybr.y;
		w = x2 - x + 1;
		h = y2 - y + 1;
		if ((w <= 0) || (h <= 0)) goto clean;

		XPutImage(priv->disp, priv->drawable, priv->tempgc, priv->ximage, 
			  x, GGI_X_WRITE_Y, x, GGI_X_WRITE_Y,
			  (unsigned)w, (unsigned)h);
		GGI_X_CLEAN(vis, x, y, w, h);
	}

	/* Tell X Server to start blitting */
	XFlush(priv->disp);
 clean:

	if (tryflag != 2) GGI_X_UNLOCK_XLIB(vis);
	if (priv->opmansync && mansync) MANSYNC_cont(vis);
	return 0;
}