Added the unbind and unchord samrc directives. - 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 37bf82df8a1adab4f40e844ddc65d8e977d2ba0d
 (DIR) parent 6a54452391a83964a0a5a955185926c56d7dd4e7
 (HTM) Author: Rob King <jking@deadpixi.com>
       Date:   Sat, 10 Sep 2016 16:12:07 -0500
       
       Added the unbind and unchord samrc directives.
       
       Diffstat:
         doc/samrc.5                         |      39 +++++++++++++++++++++++++++++++
         include/libg.h                      |       8 ++++++++
         libXg/gwin.c                        |      68 ++++++++++++++++++++++++++-----
         samterm/samrc.c                     |      10 ++++++++--
         samterm/samterm.h                   |      44 ++++++++++++++++----------------
       
       5 files changed, 135 insertions(+), 34 deletions(-)
       ---
 (DIR) diff --git a/doc/samrc.5 b/doc/samrc.5
       @@ -65,6 +65,23 @@ specification of a character
        .Pq "for raw and composed characters" "."
        .Pp
        Note that keyboard symbol names are implementation-defined and often case-sensitive.
       +.It unbind
       +Remove all bindings associated with a key sequence.
       +The form is:
       +.Bd -literal
       +
       +    unbind M K
       +
       +.Ed
       +where
       +.Em M
       +is a string describing a set of modifier keys and
       +.Em K
       +is the name of a keyboard symbol,
       +as for
       +.Dq bind
       +above.
       +The key sequence may be subsequently rebound.
        .It chord
        Bind a mouse chord to a command.
        The form is:
       @@ -93,6 +110,20 @@ see
        .Sx "Targets"
        below
        .Pc "."
       +.It unchord
       +Remove all bindings for a given mouse chord.
       +The form is:
       +.Bd -literal
       +
       +    unchord S1 S2
       +
       +.Ed
       +where
       +.Em S1
       +and
       +.Em S2
       +are strings describing the initial and following mouse button states.
       +The chord may be subsequently rebound.
        .It foreground
        Names the color used to draw text.
        It is of the form:
       @@ -214,6 +245,14 @@ write        Write current file        None
        eol        Move to end of line        None
        bol        Move to beginning of line        None
        .TE
       +.Pp
       +Additionally,
       +the command name
       +.Dq none
       +means that the given binding should perform no action,
       +and the command name
       +.Dq default
       +means that the given binding should perform whatever action was previously defined for it.
        .Ss "Mouse Button States"
        Chords are described using two states:
        a beginning state and an end state.
 (DIR) diff --git a/include/libg.h b/include/libg.h
       @@ -105,6 +105,12 @@ enum{
        };
        
        enum{
       +    Cnone,      /* no command */
       +    Cdefault,   /* default action */
       +    Csysmax
       +};
       +
       +enum{
            Tcurrent,   /* command is sent to focused layer */
            Tmouse      /* command is sent to layer containing the mouse */
        };
       @@ -244,6 +250,8 @@ extern  XftColor bgcolor;
        
        extern int installbinding(int, KeySym, int, int);
        extern int installchord(int, int, int, int);
       +extern int removebinding(int, KeySym);
       +extern int removechord(int, int);
        
        extern char foregroundspec[1024];
        extern char backgroundspec[1024];
 (DIR) diff --git a/libXg/gwin.c b/libXg/gwin.c
       @@ -213,6 +213,20 @@ installbinding(int m, KeySym s, int k, int c)
            return 0;
        }
        
       +int
       +removebinding(int m, KeySym s)
       +{
       +    if (m < 0 || s == NoSymbol)
       +        return -1;
       +
       +    for (Keymapping *km = keymappings; km; km = km->next){
       +        if (km->m == m && km->s == s)
       +            km->c = Cdefault;
       +    }
       +
       +    return 0;
       +}
       +
        void
        freebindings(void)
        {
       @@ -255,10 +269,19 @@ Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
        
                if (l == m->s){
                    if (m->m == 0 || (m->m & ~e->xkey.state) == 0){
       -                f = ((GwinWidget)w)->gwin.gotchar;
       -                if (f)
       -                    (*f)(m->c, m->k, Tcurrent, 0, 0);
       -                return;
       +                switch (m->c){
       +                    case Cnone:
       +                        return;
       +
       +                    case Cdefault:
       +                        continue;
       +
       +                    default:
       +                        f = ((GwinWidget)w)->gwin.gotchar;
       +                        if (f)
       +                            (*f)(m->c, m->k, Tcurrent, 0, 0);
       +                        return;
       +                }
                    }
                }
            }
       @@ -369,6 +392,20 @@ installchord(int s1, int s2, int c, int t)
            return 0;
        }
        
       +int
       +removechord(int s1, int s2)
       +{
       +    if (s1 < 0 || s2 < 0)
       +        return -1;
       +
       +    for (Chordmapping *m = chordmap; m; m = m->next){
       +        if (m->s1 == s1 && m->s2 == s2)
       +            m->c = Cdefault;
       +    }
       +
       +    return 0;
       +}
       +
        void
        freechords(void)
        {
       @@ -387,6 +424,7 @@ Mouseaction(Widget w, XEvent *e, String *p, Cardinal *np)
            int ps = 0; /* the previous state */
            int ob = 0;
            static bool chording = false;
       +    Charfunc kf;
        
            XButtonEvent *be = (XButtonEvent *)e;
            XMotionEvent *me = (XMotionEvent *)e;
       @@ -450,12 +488,22 @@ Mouseaction(Widget w, XEvent *e, String *p, Cardinal *np)
            /* Check to see if it's a chord first. */
            for (Chordmapping *cm = chordmap; cm; cm = cm->next){
                if (ob == cm->s1 && m.buttons == cm->s2){
       -            Charfunc kf = ((GwinWidget)w)->gwin.gotchar;
       -            if (kf)
       -                (*kf)(cm->c, Kcommand, cm->t, m.xy.x, m.xy.y);
       -
       -            m.buttons = 0;
       -            chording = true;
       +            switch (cm->c){
       +                case Cdefault:
       +                    continue;
       +
       +                case Cnone:
       +                    break;
       +
       +                default:
       +                    kf = ((GwinWidget)w)->gwin.gotchar;
       +                    if (kf)
       +                        (*kf)(cm->c, Kcommand, cm->t, m.xy.x, m.xy.y);
       +        
       +                    m.buttons = 0;
       +                    chording = true;
       +                    break;
       +            }
                }
            }
        
 (DIR) diff --git a/samterm/samrc.c b/samterm/samrc.c
       @@ -21,6 +21,8 @@ struct Namemapping{
        };
        
        static Namemapping commandmapping[] ={
       +    {"none",            Cnone},
       +    {"default",         Cdefault},
            {"escape",          Cescape},
            {"scrolldown",      Cscrolldown},
            {"scrollup",        Cscrollup},
       @@ -216,8 +218,8 @@ loadrcfile(FILE *f)
            size_t ln = 0;
        
            while ((r = getline(&l, &n, f)) >= 0){
       -        char s1[6] = {0};
       -        char s2[6] = {0};
       +        char s1[100] = {0};
       +        char s2[100] = {0};
                char cname[1024] = {0};
                char tname[1024] = {0};
                char c = 0;
       @@ -241,6 +243,10 @@ loadrcfile(FILE *f)
                    rc = installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kcomposed, c);
                else if (sscanf(l, " bind %5[*camshNCAMSH12345] %99s command %99s", s1, s2, cname) == 3)
                    rc = installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kcommand, nametocommand(cname));
       +        else if (sscanf(l, " unbind %5[*camshNCAMSH12345] %99s", s1, s2) == 2)
       +            rc = removebinding(statetomask(s1, modmapping), XStringToKeysym(s2));
       +        else if (sscanf(l, " unchord %5[Nn12345] %5[Nn12345]", s1, s2) == 2)
       +            rc = removechord(statetomask(s1, buttonmapping), statetomask(s2, buttonmapping));
                else if (sscanf(l, " foreground %1023s", cname) == 1)
                    strncpy(foregroundspec, cname, sizeof(foregroundspec) - 1);
                else if (sscanf(l, " background %1023s", cname) == 1)
 (DIR) diff --git a/samterm/samterm.h b/samterm/samterm.h
       @@ -6,28 +6,28 @@
        #define NL  5
        
        enum{
       -    Cnone,              /* invalid command */
       -    Cescape,            /* highlight recently typed text */
       -    Cscrolldown,        /* scroll file down by screen */
       -    Cscrollup,          /* scroll file up by screen */
       -    Cscrolldownline,    /* scroll file down by line */
       -    Cscrollupline,      /* scroll file up by line */
       -    Cjump,              /* jump to/from command file */
       -    Ccharright,         /* move dot right by character */
       -    Ccharleft,          /* move dot left by character */
       -    Clinedown,          /* move dot down by line */
       -    Clineup,            /* move dot up by line */
       -    Cdelword,           /* delete word to left of dot */
       -    Cdelbol,            /* delete to beginning of line */
       -    Cdel,               /* delete character to left of dot */
       -    Csnarf,             /* snarf dot */
       -    Ccut,               /* cut dot */
       -    Cpaste,             /* paste from snarf buffer */
       -    Cexchange,          /* exchange snarf buffer with OS */
       -    Cwrite,             /* write file */
       -    Ceol,               /* move to beginning of line */
       -    Cbol,               /* move to end of line */
       -    Cmax                /* invalid command */
       +
       +    Cescape = Csysmax + 1, /* highlight recently typed text */
       +    Cscrolldown,           /* scroll file down by screen */
       +    Cscrollup,             /* scroll file up by screen */
       +    Cscrolldownline,       /* scroll file down by line */
       +    Cscrollupline,         /* scroll file up by line */
       +    Cjump,                 /* jump to/from command file */
       +    Ccharright,            /* move dot right by character */
       +    Ccharleft,             /* move dot left by character */
       +    Clinedown,             /* move dot down by line */
       +    Clineup,               /* move dot up by line */
       +    Cdelword,              /* delete word to left of dot */
       +    Cdelbol,               /* delete to beginning of line */
       +    Cdel,                  /* delete character to left of dot */
       +    Csnarf,                /* snarf dot */
       +    Ccut,                  /* cut dot */
       +    Cpaste,                /* paste from snarf buffer */
       +    Cexchange,             /* exchange snarf buffer with OS */
       +    Cwrite,                /* write file */
       +    Ceol,                  /* move to beginning of line */
       +    Cbol,                  /* move to end of line */
       +    Cmax                   /* invalid command */
        };
        
        enum{