URI: 
       tdevdraw: use indirect impl interface - 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 94d381ec9d579e5336f3817b68cf4d1a8a7333db
   DIR parent 162d0d5cd94fabab822ac66655be8957151cef99
  HTML Author: Russ Cox <rsc@swtch.com>
       Date:   Sat, 25 Jan 2020 14:31:52 -0500
       
       devdraw: use indirect impl interface
       
       Setting up for a real window system.
       
       Diffstat:
         M src/cmd/devdraw/devdraw.c           |       4 ++--
         M src/cmd/devdraw/devdraw.h           |      23 ++++++++++++++---------
         M src/cmd/devdraw/mac-screen.m        |      38 ++++++++++++++++++++++++-------
         M src/cmd/devdraw/srv.c               |      26 +++++++++++++++-----------
       
       4 files changed, 61 insertions(+), 30 deletions(-)
       ---
   DIR diff --git a/src/cmd/devdraw/devdraw.c b/src/cmd/devdraw/devdraw.c
       t@@ -143,7 +143,7 @@ addflush(Client *c, Rectangle r)
                        // during a resize.
                        rpc_gfxdrawunlock();
                        qunlock(&c->drawlk);
       -                rpc_flush(c, fr);
       +                c->impl->rpc_flush(c, fr);
                        qlock(&c->drawlk);
                        rpc_gfxdrawlock();
                }
       t@@ -188,7 +188,7 @@ drawflush(Client *c)
                        // during a resize.
                        rpc_gfxdrawunlock();
                        qunlock(&c->drawlk);
       -                rpc_flush(c, r);
       +                c->impl->rpc_flush(c, r);
                        qlock(&c->drawlk);
                        rpc_gfxdrawlock();
                }
   DIR diff --git a/src/cmd/devdraw/devdraw.h b/src/cmd/devdraw/devdraw.h
       t@@ -7,6 +7,7 @@ typedef struct Mousebuf Mousebuf;
        typedef struct Tagbuf Tagbuf;
        
        typedef struct Client Client;
       +typedef struct ClientImpl ClientImpl;
        typedef struct DImage DImage;
        typedef struct DScreen DScreen;
        typedef struct CScreen CScreen;
       t@@ -43,6 +44,18 @@ struct Tagbuf
                int wi;
        };
        
       +struct ClientImpl
       +{
       +        void (*rpc_resizeimg)(Client*);
       +        void (*rpc_resizewindow)(Client*, Rectangle);
       +        void (*rpc_setcursor)(Client*, Cursor*, Cursor2*);
       +        void (*rpc_setlabel)(Client*, char*);
       +        void (*rpc_setmouse)(Client*, Point);
       +        void (*rpc_topwin)(Client*);
       +        void (*rpc_bouncemouse)(Client*, Mouse);
       +        void (*rpc_flush)(Client*, Rectangle);
       +};
       +
        struct Client
        {
                int                rfd;
       t@@ -82,6 +95,7 @@ struct Client
                int                nname;
                DName*                name;
                int                namevers;
       +        ClientImpl*        impl;
        
                // Only accessed/modified by the graphics thread.
                const void*                view;
       t@@ -196,17 +210,8 @@ void        gfx_started(void);
        Memimage *rpc_attach(Client*, char*, char*);
        char*        rpc_getsnarf(void);
        void        rpc_putsnarf(char*);
       -void        rpc_resizeimg(Client*);
       -void        rpc_resizewindow(Client*, Rectangle);
       -void        rpc_serve(Client*);
       -void        rpc_setcursor(Client*, Cursor*, Cursor2*);
       -void        rpc_setlabel(Client*, char*);
       -void        rpc_setmouse(Client*, Point);
        void        rpc_shutdown(void);
       -void        rpc_topwin(Client*);
        void        rpc_main(void);
       -void        rpc_bouncemouse(Client*, Mouse);
       -void        rpc_flush(Client*, Rectangle);
        
        // rpc_gfxdrawlock and rpc_gfxdrawunlock
        // are called around drawing operations to lock and unlock
   DIR diff --git a/src/cmd/devdraw/mac-screen.m b/src/cmd/devdraw/mac-screen.m
       t@@ -37,6 +37,27 @@ static void setprocname(const char*);
        static uint keycvt(uint);
        static uint msec(void);
        
       +static void        rpc_resizeimg(Client*);
       +static void        rpc_resizewindow(Client*, Rectangle);
       +static void        rpc_serve(Client*);
       +static void        rpc_setcursor(Client*, Cursor*, Cursor2*);
       +static void        rpc_setlabel(Client*, char*);
       +static void        rpc_setmouse(Client*, Point);
       +static void        rpc_topwin(Client*);
       +static void        rpc_bouncemouse(Client*, Mouse);
       +static void        rpc_flush(Client*, Rectangle);
       +
       +static ClientImpl macimpl = {
       +        rpc_resizeimg,
       +        rpc_resizewindow,
       +        rpc_setcursor,
       +        rpc_setlabel,
       +        rpc_setmouse,
       +        rpc_topwin,
       +        rpc_bouncemouse,
       +        rpc_flush
       +};
       +
        @class DrawView;
        @class DrawLayer;
        
       t@@ -201,6 +222,7 @@ rpc_attach(Client *c, char *label, char *winsize)
        {
                LOG(@"attachscreen(%s, %s)", label, winsize);
        
       +        c->impl = &macimpl;
                dispatch_sync(dispatch_get_main_queue(), ^(void) {
                        @autoreleasepool {
                                DrawView *view = [[DrawView new] attach:c winsize:winsize label:label];
       t@@ -302,7 +324,7 @@ rpc_attach(Client *c, char *label, char *winsize)
        
        // rpc_topwin moves the window to the top of the desktop.
        // Called from an RPC thread with no client lock held.
       -void
       +static void
        rpc_topwin(Client *c)
        {
                DrawView *view = (__bridge DrawView*)c->view;
       t@@ -319,7 +341,7 @@ rpc_topwin(Client *c)
        // rpc_setlabel updates the client window's label.
        // If label == nil, the call is a no-op.
        // Called from an RPC thread with no client lock held.
       -void
       +static void
        rpc_setlabel(Client *client, char *label)
        {
                DrawView *view = (__bridge DrawView*)client->view;
       t@@ -344,7 +366,7 @@ rpc_setlabel(Client *client, char *label)
        // rpc_setcursor updates the client window's cursor image.
        // Either c and c2 are both non-nil, or they are both nil to use the default arrow.
        // Called from an RPC thread with no client lock held.
       -void
       +static void
        rpc_setcursor(Client *client, Cursor *c, Cursor2 *c2)
        {
                DrawView *view = (__bridge DrawView*)client->view;
       t@@ -460,7 +482,7 @@ rpc_setcursor(Client *client, Cursor *c, Cursor2 *c2)
        // rpc_flush flushes changes to view.img's rectangle r
        // to the on-screen window, making them visible.
        // Called from an RPC thread with no client lock held.
       -void
       +static void
        rpc_flush(Client *client, Rectangle r)
        {
                DrawView *view = (__bridge DrawView*)client->view;
       t@@ -506,7 +528,7 @@ rpc_flush(Client *client, Rectangle r)
        // rpc_resizeimg forces the client window to discard its current window and make a new one.
        // It is called when the user types Cmd-R to toggle whether retina mode is forced.
        // Called from an RPC thread with no client lock held.
       -void
       +static void
        rpc_resizeimg(Client *c)
        {
                DrawView *view = (__bridge DrawView*)c->view;
       t@@ -541,7 +563,7 @@ rpc_resizeimg(Client *c)
        
        // rpc_resizewindow asks for the client window to be resized to size r.
        // Called from an RPC thread with no client lock held.
       -void
       +static void
        rpc_resizewindow(Client *c, Rectangle r)
        {
                DrawView *view = (__bridge DrawView*)c->view;
       t@@ -696,7 +718,7 @@ rpc_resizewindow(Client *c, Rectangle r)
        
        // rpc_setmouse moves the mouse cursor.
        // Called from an RPC thread with no client lock held.
       -void
       +static void
        rpc_setmouse(Client *c, Point p)
        {
                DrawView *view = (__bridge DrawView*)c->view;
       t@@ -1095,7 +1117,7 @@ rpc_putsnarf(char *s)
        // rpc_bouncemouse is for sending a mouse event
        // back to the X11 window manager rio(1).
        // Does not apply here.
       -void
       +static void
        rpc_bouncemouse(Client *c, Mouse m)
        {
        }
   DIR diff --git a/src/cmd/devdraw/srv.c b/src/cmd/devdraw/srv.c
       t@@ -54,6 +54,7 @@ threadmain(int argc, char **argv)
                        usage();
                }ARGEND
        
       +        memimageinit();
                fmtinstall('H', encodefmt);
                if((p = getenv("DEVDRAWTRACE")) != nil)
                        trace = atoi(p);
       t@@ -202,8 +203,11 @@ runmsg(Client *c, Wsysmsg *m)
                        break;
        
                case Tinit:
       -                memimageinit();
                        i = rpc_attach(c, m->label, m->winsize);
       +                if(i == nil) {
       +                        replyerror(c, m);
       +                        break;
       +                }
                        draw_initdisplaymemimage(c, i);
                        replymsg(c, m);
                        break;
       t@@ -241,35 +245,35 @@ runmsg(Client *c, Wsysmsg *m)
                        break;
        
                case Tmoveto:
       -                rpc_setmouse(c, m->mouse.xy);
       +                c->impl->rpc_setmouse(c, m->mouse.xy);
                        replymsg(c, m);
                        break;
        
                case Tcursor:
                        if(m->arrowcursor)
       -                        rpc_setcursor(c, nil, nil);
       +                        c->impl->rpc_setcursor(c, nil, nil);
                        else {
                                scalecursor(&m->cursor2, &m->cursor);
       -                        rpc_setcursor(c, &m->cursor, &m->cursor2);
       +                        c->impl->rpc_setcursor(c, &m->cursor, &m->cursor2);
                        }
                        replymsg(c, m);
                        break;
        
                case Tcursor2:
                        if(m->arrowcursor)
       -                        rpc_setcursor(c, nil, nil);
       +                        c->impl->rpc_setcursor(c, nil, nil);
                        else
       -                        rpc_setcursor(c, &m->cursor, &m->cursor2);
       +                        c->impl->rpc_setcursor(c, &m->cursor, &m->cursor2);
                        replymsg(c, m);
                        break;
        
                case Tbouncemouse:
       -                rpc_bouncemouse(c, m->mouse);
       +                c->impl->rpc_bouncemouse(c, m->mouse);
                        replymsg(c, m);
                        break;
        
                case Tlabel:
       -                rpc_setlabel(c, m->label);
       +                c->impl->rpc_setlabel(c, m->label);
                        replymsg(c, m);
                        break;
        
       t@@ -306,12 +310,12 @@ runmsg(Client *c, Wsysmsg *m)
                        break;
        
                case Ttop:
       -                rpc_topwin(c);
       +                c->impl->rpc_topwin(c);
                        replymsg(c, m);
                        break;
        
                case Tresize:
       -                rpc_resizewindow(c, m->rect);
       +                c->impl->rpc_resizewindow(c, m->rect);
                        replymsg(c, m);
                        break;
                }
       t@@ -513,7 +517,7 @@ gfx_keystroke(Client *c, int ch)
                        else
                                c->forcedpi = 225;
                        qunlock(&c->eventlk);
       -                rpc_resizeimg(c);
       +                c->impl->rpc_resizeimg(c);
                        return;
                }
                if(!c->kbd.alting){