URI:
       tlibdraw: add Cursor2, a 32x32 high-res cursor - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 8581c2b56763d7787604c8c833d2bd78bdc6a466
   DIR parent 9af9ceca26596d562a3ae89fda70bad9f8822ab0
  HTML Author: Russ Cox <rsc@swtch.com>
       Date:   Thu, 15 Nov 2018 20:22:59 -0500
       
       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.
       
       Diffstat:
         M include/cursor.h                    |      10 ++++++++++
         M include/draw.h                      |       3 ++-
         M include/drawfcall.h                 |       6 ++++++
         M include/event.h                     |       2 ++
         M include/mouse.h                     |       2 ++
         A src/libdraw/cursor.c                |      32 +++++++++++++++++++++++++++++++
         M src/libdraw/drawclient.c            |       7 ++++++-
         M src/libdraw/drawfcall.c             |      14 +++++++++++---
         M src/libdraw/event.c                 |       8 +++++++-
         M src/libdraw/mkfile                  |       1 +
         M src/libdraw/mouse.c                 |       8 +++++++-
       
       11 files changed, 86 insertions(+), 7 deletions(-)
       ---
   DIR diff --git a/include/cursor.h b/include/cursor.h
       t@@ -12,6 +12,16 @@ struct        Cursor
                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)
        }
        #endif
   DIR diff --git a/include/draw.h b/include/draw.h
       t@@ -568,9 +568,10 @@ int        mousescrollsize(int);
         */
        struct Mouse;
        struct Cursor;
       +struct Cursor2;
        int                _displaybouncemouse(Display *d, struct Mouse *m);
        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                _displaylabel(Display *d, char *label);
        int                _displaymoveto(Display *d, Point p);
   DIR diff --git a/include/drawfcall.h b/include/drawfcall.h
       t@@ -13,6 +13,9 @@ tag[1] Rmoveto
        tag[1] Tcursor cursor[]
        tag[1] Rcursor
        
       +tag[1] Tcursor2 cursor[]
       +tag[1] Rcursor2
       +
        tag[1] Tbouncemouse x[4] y[4] button[4]
        tag[1] Rbouncemouse
        
       t@@ -89,6 +92,8 @@ enum {
                Rtop,
                Tresize = 26,
                Rresize,
       +        Tcursor2 = 28,
       +        Rcursor2,
                Tmax,
        };
        
       t@@ -104,6 +109,7 @@ struct Wsysmsg
                Mouse mouse;
                int resized;
                Cursor cursor;
       +        Cursor2 cursor2;
                int arrowcursor;
                Rune rune;
                char *winsize;
   DIR diff --git a/include/event.h b/include/event.h
       t@@ -61,7 +61,9 @@ extern int         emenuhit(int, Mouse*, Menu*);
        extern int        eatomouse(Mouse*, char*, int);
        extern Rectangle        getrect(int, Mouse*);
        struct Cursor;
       +struct Cursor2;
        extern void         esetcursor(struct Cursor*);
       +extern void         esetcursor2(struct Cursor*, struct Cursor2*);
        extern void         emoveto(Point);
        extern Rectangle        egetrect(int, Mouse*);
        extern void                edrawgetrect(Rectangle, int);
   DIR diff --git a/include/mouse.h b/include/mouse.h
       t@@ -38,7 +38,9 @@ extern void                moveto(Mousectl*, Point);
        extern int                        readmouse(Mousectl*);
        extern void                closemouse(Mousectl*);
        struct Cursor;
       +struct Cursor2;
        extern void                setcursor(Mousectl*, struct Cursor*);
       +extern void                setcursor2(Mousectl*, struct Cursor*, struct Cursor2*);
        extern void                drawgetrect(Rectangle, int);
        extern Rectangle        getrect(int, Mousectl*);
        extern int                         menuhit(int, Mousectl*, Menu*, Screen*);
   DIR diff --git a/src/libdraw/cursor.c b/src/libdraw/cursor.c
       t@@ -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];
       +        }
       +}
   DIR diff --git a/src/libdraw/drawclient.c b/src/libdraw/drawclient.c
       t@@ -292,17 +292,22 @@ _displaymoveto(Display *d, Point p)
        }
        
        int
       -_displaycursor(Display *d, Cursor *c)
       +_displaycursor(Display *d, Cursor *c, Cursor2 *c2)
        {
                Wsysmsg tx, rx;
                
                tx.type = Tcursor;
                if(c == nil){
                        memset(&tx.cursor, 0, sizeof tx.cursor);
       +                memset(&tx.cursor2, 0, sizeof tx.cursor2);
                        tx.arrowcursor = 1;
                }else{
                        tx.arrowcursor = 0;
                        tx.cursor = *c;
       +                if(c2 != nil)
       +                        tx.cursor2 = *c2;
       +                else
       +                        scalecursor(&tx.cursor2, c);
                }
                return displayrpc(d, &tx, &rx, nil);
        }
   DIR diff --git a/src/libdraw/drawfcall.c b/src/libdraw/drawfcall.c
       t@@ -64,7 +64,7 @@ sizeW2M(Wsysmsg *m)
                case Tmoveto:
                        return 4+1+1+4+4;
                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:
                        return 4+1+1+_stringsize(m->error);
                case Rrdkbd:
       t@@ -141,7 +141,11 @@ convW2M(Wsysmsg *m, uchar *p, uint n)
                        PUT(p+10, m->cursor.offset.y);
                        memmove(p+14, m->cursor.clr, sizeof m->cursor.clr);
                        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;
                case Rrdkbd:
                        PUT2(p+6, m->rune);
       t@@ -229,7 +233,11 @@ convM2W(uchar *p, uint n, Wsysmsg *m)
                        GET(p+10, m->cursor.offset.y);
                        memmove(m->cursor.clr, p+14, sizeof m->cursor.clr);
                        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;
                case Rrdkbd:
                        GET2(p+6, m->rune);
   DIR diff --git a/src/libdraw/event.c b/src/libdraw/event.c
       t@@ -416,7 +416,13 @@ emoveto(Point pt)
        void
        esetcursor(Cursor *c)
        {
       -        _displaycursor(display, c);
       +        _displaycursor(display, c, nil);
       +}
       +
       +void
       +esetcursor2(Cursor *c, Cursor2 *c2)
       +{
       +        _displaycursor(display, c, c2);
        }
        
        int
   DIR diff --git a/src/libdraw/mkfile b/src/libdraw/mkfile
       t@@ -14,6 +14,7 @@ OFILES=\
                cloadimage.$O\
                computil.$O\
                creadimage.$O\
       +        cursor.$O\
                debug.$O\
                defont.$O\
                draw.$O\
   DIR diff --git a/src/libdraw/mouse.c b/src/libdraw/mouse.c
       t@@ -85,6 +85,12 @@ initmouse(char *file, Image *i)
        void
        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);
        }