shithub: npe

ref: 979ae53cfee913c2d303ab0f95aaa65dace1c7b5
dir: /libnpe_sdl3/cursor.c/

View raw version
#include "_sdl.h"

struct SDL_Cursor {
	Image *i;
	Image *m;
	Point hot;
};
static SDL_Cursor *oldcursor, *cursor;
static Cursor nocursor = {
	{0, 0},
	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	},
	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	},
};
static int showcursor = SDL_ENABLE;

bool
SDL_ShowCursor(void)
{
	showcursor = 1;
	setcursor(npe_sdl.mctl, cursor == nil ? nil : &nocursor);
	return true;
}

bool
SDL_HideCursor(void)
{
	showcursor = 0;
	setcursor(npe_sdl.mctl, &nocursor);
	return true;
}

SDL_Cursor *
SDL_CreateColorCursor(SDL_Surface *s, int hot_x, int hot_y)
{
	SDL_Cursor *c;
	Rectangle r;
	uchar *m;
	int n;

	m = nil;
	if((c = calloc(1, sizeof(*c))) == nil){
		werrstr("memory");
		goto err;
	}

	r = Rect(0, 0, s->w, s->h);
	if(s->keyset){
		if((c->m = allocimage(display, r, GREY8, 0, DTransparent)) == nil)
			goto err;
		if((m = malloc(s->w * s->h)) == nil)
			goto err;
		for(n = 0; n < s->w * s->h; n++){
			m[n] = ((u32int*)s->pixels)[n] == s->key ? 0x00 : 0xff;
			if(m[n] == 0)
				((u32int*)s->pixels)[n] = 0;
		}
		if(loadimage(c->m, r, m, n) < 1)
			goto err;
		free(m);
		m = nil;
	}
	if((c->i = allocimage(display, r, s->keyset ? XRGB32 : ARGB32, 0, DTransparent)) == nil)
		goto err;
	n = s->w * s->h * 4; /* FIXME non-ARGB8888 */
	if(loadimage(c->i, r, s->pixels, n) < 1)
		goto err;

	c->hot = Pt(hot_x, hot_y);

	return c;
err:
	werrstr("SDL_CreateColorCursor: %r");
	if(c != nil){
		freeimage(c->i);
		freeimage(c->m);
	}
	free(c);
	free(m);
	return nil;
}

SDL_Cursor *
SDL_GetDefaultCursor(void)
{
	return nil;
}

SDL_Cursor *
SDL_CreateSystemCursor(SDL_SystemCursor id)
{
	/* FIXME */
	USED(id);

	return nil;
}

void
SDL_SetCursor(SDL_Cursor *c)
{
	if(cursor != c){
		cursor = c;
		npe_sdl.mredraw = 1;
		setcursor(npe_sdl.mctl, (cursor == nil && showcursor) ? nil : &nocursor);
	}
}

void
SDL_FreeCursor(SDL_Cursor *c)
{
	freeimage(c->i);
	free(c);
	if(cursor == c){
		oldcursor = nil;
		cursor = nil;
	}
}

void
npe_draw_cursor(void)
{
	Rectangle r, clipr;

	if(cursor == nil || !showcursor)
		return;
	r.min = subpt(npe_sdl.m.xy, cursor->hot);
	r.max = addpt(r.min, cursor->i->r.max);
	if(!npe_sdl.fullredraw && oldcursor != nil){
		clipr.min = subpt(npe_sdl.om.xy, oldcursor->hot);
		clipr.max = addpt(clipr.min, oldcursor->i->r.max);
		combinerect(&clipr, r);
		replclipr(screen, 0, clipr);
		npe_sdl.om.xy = npe_sdl.m.xy;
	}
	draw(screen, r, cursor->i, cursor->m, ZP);
	oldcursor = cursor;
}