Allow mouse chords to target different layers. - sam - An updated version of the sam text editor.
 (HTM) git clone git://vernunftzentrum.de/sam.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit 4cc22366dbfaadaaf0439d322f6aa5ac8215e7e6
 (DIR) parent cd90f3113b35f1b35c6bce5f030a85a2d62a53e7
 (HTM) Author: Rob King <jking@deadpixi.com>
       Date:   Thu,  1 Sep 2016 12:29:45 -0500
       
       Allow mouse chords to target different layers.
       
       The available targets are Tcurrent, for the current typing layer; and
       Tmouse, for the layer containing the mouse. This has the affect of
       allowing scrolling of a layer even if it's not the focused one.
       
       Note that we should probably rename Keystroke to Command at this point,
       since it's rapidly becoming the sole event type that is used.
       
       Diffstat:
         chords.h.def                        |      14 ++++++++------
         include/commands.h                  |       5 +++++
         include/libg.h                      |       2 ++
         libXg/Gwin.h                        |       2 +-
         libXg/gwin.c                        |      12 ++++++------
         libXg/xtbinit.c                     |       6 ++++--
         samterm/main.c                      |      13 +++++++++++--
       
       7 files changed, 37 insertions(+), 17 deletions(-)
       ---
 (DIR) diff --git a/chords.h.def b/chords.h.def
       @@ -6,6 +6,8 @@
         * start    - the start state (i.e. what mouse buttons were pressed)
         * end      - the end state (i.e. what mouse buttons are now pressed)
         * action   - one of the commands listed in commands.h (or commands.h.def)
       + * target   - Tcurrent for the current (typing) layer
       + *          - Tmouse for the layer containing the mouse
         *
         * The following values are available for state definitions:
         *      None    - No buttons are pressed
       @@ -18,11 +20,11 @@
         * "classic" Unix sam of the 1980s.
         */
        
       -{B1, B1|B2, Kcommand, Ccut},
       -{B1, B1|B3, Kcommand, Cpaste},
       +{B1, B1|B2, Kcommand, Ccut, Tcurrent},
       +{B1, B1|B3, Kcommand, Cpaste, Tcurrent},
        
       -{B4, 0, Kcommand, Cscrollupline},
       -{B5, 0, Kcommand, Cscrolldownline},
       +{B4, 0, Kcommand, Cscrollupline, Tmouse},
       +{B5, 0, Kcommand, Cscrolldownline, Tmouse},
        
        /* The lines below "cancel" the mouse movement that is implicit above
         * in the Ccut and Cpaste chords. If these lines are not present, dot
       @@ -31,5 +33,5 @@
         * Some people might like that kind of behavior: if so, just remove
         * these lines.
         */
       -{B1|B3, B1, Kcommand, Cnone},
       -{B1|B2, B1, Kcommand, Cnone},
       +{B1|B3, B1, Kcommand, Cnone, Tcurrent},
       +{B1|B2, B1, Kcommand, Cnone, Tcurrent},
 (DIR) diff --git a/include/commands.h b/include/commands.h
       @@ -34,4 +34,9 @@ enum{
            Cmax
        }; /* virtual command keystrokes */
        
       +enum{
       +    Tcurrent,
       +    Tmouse
       +};
       +
        #endif
 (DIR) diff --git a/include/libg.h b/include/libg.h
       @@ -62,6 +62,8 @@ struct  Keystroke
        {
            int k;
            int c;
       +    int t;
       +    Point p;
        };
        
        struct        Cursor
 (DIR) diff --git a/libXg/Gwin.h b/libXg/Gwin.h
       @@ -34,7 +34,7 @@ typedef struct {
                } Gwinmouse;
        
        typedef void (*Reshapefunc)(int, int, int, int);
       -typedef void (*Charfunc)(int, int);
       +typedef void (*Charfunc)(int, int, int, int, int);
        typedef void (*Mousefunc)(Gwinmouse*);
        
        /* Method declarations */
 (DIR) diff --git a/libXg/gwin.c b/libXg/gwin.c
       @@ -161,7 +161,7 @@ Mappingaction(Widget w, XEvent *e, String *p, Cardinal *np)
                                        f = ((GwinWidget)w)->gwin.gotchar; \
                                        if (f) \
                                                for (c = 0; c < composing; c++) \
       -                                                (*f)(compose[c], 0)
       +                                                (*f)(compose[c], 0, Tcurrent, 0, 0)
        
        typedef struct Keymapping Keymapping;
        struct Keymapping{
       @@ -204,7 +204,7 @@ Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
                if (e->xkey.state == m->mask && k == m->sym){
                    f = ((GwinWidget)w)->gwin.gotchar;
                    if (f)
       -                (*f)(m->result, m->kind);
       +                (*f)(m->result, m->kind, Tcurrent, 0, 0);
                    return;
                }
            }
       @@ -283,7 +283,7 @@ Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
        
                f = ((GwinWidget)w)->gwin.gotchar;
                if(f)
       -                (*f)(c, kind);
       +                (*f)(c, kind, Tcurrent, 0, 0);
        }
        
        typedef struct Chordmapping Chordmapping;
       @@ -292,6 +292,7 @@ struct Chordmapping{
            int end;
            int kind;
            int result;
       +    int target;
        };
        
        #define B1 Button1Mask
       @@ -302,7 +303,7 @@ struct Chordmapping{
        
        Chordmapping chordmappings[] ={
            #include "../chords.h"
       -    {0, 0, Kend, 0}
       +    {0, 0, Kend, 0, 0}
        };
        
        static void
       @@ -357,10 +358,9 @@ Mouseaction(Widget w, XEvent *e, String *p, Cardinal *np)
                if (ps == cm->start && s == cm->end){
                    Charfunc kf = ((GwinWidget)w)->gwin.gotchar;
                    if (kf)
       -                (*kf)(cm->result, cm->kind);
       +                (*kf)(cm->result, cm->kind, cm->target, m.xy.x, m.xy.y);
        
                    memset(&m, 0, sizeof(m));
       -                // XXX m.buttons = 0;
                        f = ((GwinWidget)w)->gwin.gotmouse;
                        if(f)
                                (*f)(&m);
 (DIR) diff --git a/libXg/xtbinit.c b/libXg/xtbinit.c
       @@ -119,7 +119,7 @@ static int Stimer = -1;
        
        
        static void        reshaped(int, int, int, int);
       -static void        gotchar(int, int);
       +static void        gotchar(int, int, int, int, int);
        static void        gotmouse(Gwinmouse *);
        static int        ilog2(int);
        static void        pixtocolor(Pixel, XColor *);
       @@ -314,7 +314,7 @@ reshaped(int minx, int miny, int maxx, int maxy)
        }
        
        static void
       -gotchar(int c, int kind)
       +gotchar(int c, int kind, int target, int x, int y)
        {
            Ebuf *eb;
            Keystroke k;
       @@ -326,6 +326,8 @@ gotchar(int c, int kind)
                    berror("eballoc can't malloc");
            k.c = c;
            k.k = kind;
       +    k.t = target;
       +    k.p = Pt(x, y);
            memcpy(eb->buf, &k, sizeof(Keystroke));
            esrc[Skeyboard].count++;
        }
 (DIR) diff --git a/samterm/main.c b/samterm/main.c
       @@ -861,9 +861,18 @@ type(Flayer *l, int res)        /* what a bloody mess this is -- but it's getting bette
                if (k.c < 0 || k.c >= Cmax)
                    panic("command table miss");
        
       +        Flayer *kl = (k.t == Tcurrent) ? l : flwhich(k.p);
       +        Text *kt = (k.t == Tcurrent) ? t : (Text *)l->user1;
       +        long ka = (k.t == Tcurrent) ? a : l->p0;
                CommandEntry *e = &commands[k.c];
       -        if (!e->unlocked || !lock)
       -            a = e->f(l, a, t);
       +        if (!e->unlocked || !lock){
       +            if (k.t == Tcurrent)
       +                a = e->f(l, a, t);
       +            else{
       +                Flayer *lt = flwhich(k.p);
       +                lt->p0 = e->f(lt, lt->p0, (Text *)lt->user1);
       +            }
       +        }
            }
        
            if (p > buf){