ref: 979ae53cfee913c2d303ab0f95aaa65dace1c7b5
dir: /libnpe_sdl3/cursor.c/
#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;
}