libdraw: add Cursor2, a 32x32 high-res cursor

Also add setcursor2, esetcursor2, and draw protocol encoding.
Calls to the old setcursor, esetcursor create a 32x32 by
pixel doubling when needed.
This commit is contained in:
Russ Cox 2018-11-15 20:22:59 -05:00
parent 9af9ceca26
commit 8581c2b567
11 changed files with 86 additions and 7 deletions

View file

@ -12,6 +12,16 @@ struct Cursor
uchar set[2*16]; uchar set[2*16];
}; };
typedef struct Cursor2 Cursor2;
struct Cursor2
{
Point offset;
uchar clr[4*32];
uchar set[4*32];
};
void scalecursor(Cursor2*, Cursor*);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif

View file

@ -568,9 +568,10 @@ int mousescrollsize(int);
*/ */
struct Mouse; struct Mouse;
struct Cursor; struct Cursor;
struct Cursor2;
int _displaybouncemouse(Display *d, struct Mouse *m); int _displaybouncemouse(Display *d, struct Mouse *m);
int _displayconnect(Display *d); int _displayconnect(Display *d);
int _displaycursor(Display *d, struct Cursor *c); int _displaycursor(Display *d, struct Cursor *c, struct Cursor2 *c2);
int _displayinit(Display *d, char *label, char *winsize); int _displayinit(Display *d, char *label, char *winsize);
int _displaylabel(Display *d, char *label); int _displaylabel(Display *d, char *label);
int _displaymoveto(Display *d, Point p); int _displaymoveto(Display *d, Point p);

View file

@ -13,6 +13,9 @@ tag[1] Rmoveto
tag[1] Tcursor cursor[] tag[1] Tcursor cursor[]
tag[1] Rcursor tag[1] Rcursor
tag[1] Tcursor2 cursor[]
tag[1] Rcursor2
tag[1] Tbouncemouse x[4] y[4] button[4] tag[1] Tbouncemouse x[4] y[4] button[4]
tag[1] Rbouncemouse tag[1] Rbouncemouse
@ -89,6 +92,8 @@ enum {
Rtop, Rtop,
Tresize = 26, Tresize = 26,
Rresize, Rresize,
Tcursor2 = 28,
Rcursor2,
Tmax, Tmax,
}; };
@ -104,6 +109,7 @@ struct Wsysmsg
Mouse mouse; Mouse mouse;
int resized; int resized;
Cursor cursor; Cursor cursor;
Cursor2 cursor2;
int arrowcursor; int arrowcursor;
Rune rune; Rune rune;
char *winsize; char *winsize;

View file

@ -61,7 +61,9 @@ extern int emenuhit(int, Mouse*, Menu*);
extern int eatomouse(Mouse*, char*, int); extern int eatomouse(Mouse*, char*, int);
extern Rectangle getrect(int, Mouse*); extern Rectangle getrect(int, Mouse*);
struct Cursor; struct Cursor;
struct Cursor2;
extern void esetcursor(struct Cursor*); extern void esetcursor(struct Cursor*);
extern void esetcursor2(struct Cursor*, struct Cursor2*);
extern void emoveto(Point); extern void emoveto(Point);
extern Rectangle egetrect(int, Mouse*); extern Rectangle egetrect(int, Mouse*);
extern void edrawgetrect(Rectangle, int); extern void edrawgetrect(Rectangle, int);

View file

@ -38,7 +38,9 @@ extern void moveto(Mousectl*, Point);
extern int readmouse(Mousectl*); extern int readmouse(Mousectl*);
extern void closemouse(Mousectl*); extern void closemouse(Mousectl*);
struct Cursor; struct Cursor;
struct Cursor2;
extern void setcursor(Mousectl*, struct Cursor*); extern void setcursor(Mousectl*, struct Cursor*);
extern void setcursor2(Mousectl*, struct Cursor*, struct Cursor2*);
extern void drawgetrect(Rectangle, int); extern void drawgetrect(Rectangle, int);
extern Rectangle getrect(int, Mousectl*); extern Rectangle getrect(int, Mousectl*);
extern int menuhit(int, Mousectl*, Menu*, Screen*); extern int menuhit(int, Mousectl*, Menu*, Screen*);

32
src/libdraw/cursor.c Normal file
View file

@ -0,0 +1,32 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <cursor.h>
static uint8 expand[16] = {
0x00, 0x03, 0x0c, 0x0f,
0x30, 0x33, 0x3c, 0x3f,
0xc0, 0xc3, 0xcc, 0xcf,
0xf0, 0xf3, 0xfc, 0xff,
};
void
scalecursor(Cursor2 *c2, Cursor *c)
{
int y;
c2->offset.x = 2*c->offset.x;
c2->offset.y = 2*c->offset.y;
memset(c2->clr, 0, sizeof c2->clr);
memset(c2->set, 0, sizeof c2->set);
for(y = 0; y < 16; y++) {
c2->clr[8*y] = c2->clr[8*y+4] = expand[c->clr[2*y]>>4];
c2->set[8*y] = c2->set[8*y+4] = expand[c->set[2*y]>>4];
c2->clr[8*y+1] = c2->clr[8*y+5] = expand[c->clr[2*y]&15];
c2->set[8*y+1] = c2->set[8*y+5] = expand[c->set[2*y]&15];
c2->clr[8*y+2] = c2->clr[8*y+6] = expand[c->clr[2*y+1]>>4];
c2->set[8*y+2] = c2->set[8*y+6] = expand[c->set[2*y+1]>>4];
c2->clr[8*y+3] = c2->clr[8*y+7] = expand[c->clr[2*y+1]&15];
c2->set[8*y+3] = c2->set[8*y+7] = expand[c->set[2*y+1]&15];
}
}

View file

@ -292,17 +292,22 @@ _displaymoveto(Display *d, Point p)
} }
int int
_displaycursor(Display *d, Cursor *c) _displaycursor(Display *d, Cursor *c, Cursor2 *c2)
{ {
Wsysmsg tx, rx; Wsysmsg tx, rx;
tx.type = Tcursor; tx.type = Tcursor;
if(c == nil){ if(c == nil){
memset(&tx.cursor, 0, sizeof tx.cursor); memset(&tx.cursor, 0, sizeof tx.cursor);
memset(&tx.cursor2, 0, sizeof tx.cursor2);
tx.arrowcursor = 1; tx.arrowcursor = 1;
}else{ }else{
tx.arrowcursor = 0; tx.arrowcursor = 0;
tx.cursor = *c; tx.cursor = *c;
if(c2 != nil)
tx.cursor2 = *c2;
else
scalecursor(&tx.cursor2, c);
} }
return displayrpc(d, &tx, &rx, nil); return displayrpc(d, &tx, &rx, nil);
} }

View file

@ -64,7 +64,7 @@ sizeW2M(Wsysmsg *m)
case Tmoveto: case Tmoveto:
return 4+1+1+4+4; return 4+1+1+4+4;
case Tcursor: case Tcursor:
return 4+1+1+4+4+2*16+2*16+1; return 4+1+1+4+4+2*16+2*16+4+4+4*32+4*32+1;
case Rerror: case Rerror:
return 4+1+1+_stringsize(m->error); return 4+1+1+_stringsize(m->error);
case Rrdkbd: case Rrdkbd:
@ -141,7 +141,11 @@ convW2M(Wsysmsg *m, uchar *p, uint n)
PUT(p+10, m->cursor.offset.y); PUT(p+10, m->cursor.offset.y);
memmove(p+14, m->cursor.clr, sizeof m->cursor.clr); memmove(p+14, m->cursor.clr, sizeof m->cursor.clr);
memmove(p+46, m->cursor.set, sizeof m->cursor.set); memmove(p+46, m->cursor.set, sizeof m->cursor.set);
p[78] = m->arrowcursor; PUT(p+78, m->cursor2.offset.x);
PUT(p+82, m->cursor2.offset.y);
memmove(p+86, m->cursor2.clr, sizeof m->cursor2.clr);
memmove(p+214, m->cursor2.set, sizeof m->cursor2.set);
p[342] = m->arrowcursor;
break; break;
case Rrdkbd: case Rrdkbd:
PUT2(p+6, m->rune); PUT2(p+6, m->rune);
@ -229,7 +233,11 @@ convM2W(uchar *p, uint n, Wsysmsg *m)
GET(p+10, m->cursor.offset.y); GET(p+10, m->cursor.offset.y);
memmove(m->cursor.clr, p+14, sizeof m->cursor.clr); memmove(m->cursor.clr, p+14, sizeof m->cursor.clr);
memmove(m->cursor.set, p+46, sizeof m->cursor.set); memmove(m->cursor.set, p+46, sizeof m->cursor.set);
m->arrowcursor = p[78]; GET(p+78, m->cursor2.offset.x);
GET(p+82, m->cursor2.offset.y);
memmove(m->cursor2.clr, p+86, sizeof m->cursor2.clr);
memmove(m->cursor2.set, p+214, sizeof m->cursor2.set);
m->arrowcursor = p[342];
break; break;
case Rrdkbd: case Rrdkbd:
GET2(p+6, m->rune); GET2(p+6, m->rune);

View file

@ -416,7 +416,13 @@ emoveto(Point pt)
void void
esetcursor(Cursor *c) esetcursor(Cursor *c)
{ {
_displaycursor(display, c); _displaycursor(display, c, nil);
}
void
esetcursor2(Cursor *c, Cursor2 *c2)
{
_displaycursor(display, c, c2);
} }
int int

View file

@ -14,6 +14,7 @@ OFILES=\
cloadimage.$O\ cloadimage.$O\
computil.$O\ computil.$O\
creadimage.$O\ creadimage.$O\
cursor.$O\
debug.$O\ debug.$O\
defont.$O\ defont.$O\
draw.$O\ draw.$O\

View file

@ -85,6 +85,12 @@ initmouse(char *file, Image *i)
void void
setcursor(Mousectl *mc, Cursor *c) setcursor(Mousectl *mc, Cursor *c)
{ {
_displaycursor(mc->display, c); _displaycursor(mc->display, c, nil);
}
void
setcursor2(Mousectl *mc, Cursor *c, Cursor2 *c2)
{
_displaycursor(mc->display, c, c2);
} }