Find attached updated patch. Includes small performance improvement,
code tidyup & bugfix to ensure bindings work in windows with dynamically
changing class/resource/name values.

SCoTT. :)
-- 
[EMAIL PROTECTED]
Index: fvwm/add_window.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/add_window.c,v
retrieving revision 1.360
diff -u -r1.360 add_window.c
--- fvwm/add_window.c   19 Feb 2004 09:36:01 -0000      1.360
+++ fvwm/add_window.c   2 Mar 2004 16:48:06 -0000
@@ -1441,13 +1441,11 @@
         * list. */
        GrabAllWindowKeys(
                dpy, FW_W_FRAME(fw), Scr.AllBindings,
-               C_WINDOW|C_TITLE|C_RALL|C_LALL|C_SIDEBAR, GetUnusedModifiers(),
-               True);
+               C_WINDOW|C_TITLE|C_RALL|C_LALL|C_SIDEBAR, GetUnusedModifiers(), 
True);
 #endif
        GrabAllWindowKeys(
                dpy, FW_W_FRAME(fw), Scr.AllBindings,
-               C_TITLE|C_RALL|C_LALL|C_SIDEBAR|C_WINDOW, GetUnusedModifiers(),
-               True);
+               C_TITLE|C_RALL|C_LALL|C_SIDEBAR|C_WINDOW, GetUnusedModifiers(), 
True);
        setup_focus_policy(fw);
 
        return;
Index: fvwm/bindings.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/bindings.c,v
retrieving revision 1.87
diff -u -r1.87 bindings.c
--- fvwm/bindings.c     2 Nov 2003 17:04:44 -0000       1.87
+++ fvwm/bindings.c     2 Mar 2004 16:48:07 -0000
@@ -101,6 +101,11 @@
        return;
 }
 
+Bool bindingAppliesToFWindow (Binding *b, FvwmWindow *fw)
+{
+       return bindingAppliesToWindow(b, &fw->class, fw->name.name);
+}
+
 static int activate_binding(Binding *binding, binding_t type, Bool do_grab)
 {
        FvwmWindow *t;
@@ -136,6 +141,13 @@
        /* grab keys immediately */
        for (t = Scr.FvwmRoot.next; t != NULL; t = t->next)
        {
+#if 0
+               if (!bindingAppliesToFWindow(binding, t))
+               {
+                       continue;
+               }
+#endif
+
                if (!IS_EWMH_DESKTOP(FW_W(t)) &&
                    (binding->Context & (C_WINDOW | C_DECOR)) &&
                    BIND_IS_KEY_BINDING(type))
@@ -237,8 +249,8 @@
        int *nr_left_buttons, int *nr_right_buttons,
        unsigned short *buttons_grabbed, Bool is_silent)
 {
-       char *action, context_string[20], modifier_string[20], *ptr, *token;
-       char key_string[201] = "";
+       char *action, context_string[80], modifier_string[20], *ptr, *token;
+       char key_string[201] = "", buffer[80], *windowName = NULL;
        int button = 0;
        int n1=0,n2=0,n3=0;
        KeySym keysym = NoSymbol;
@@ -361,7 +373,34 @@
        token = PeekToken(ptr, &ptr);
        if (token != NULL)
        {
-               n2 = sscanf(token, "%19s", context_string);
+               char *p = token;
+               if (*p == '(')
+               {
+                       /* A window name has been specified for the binding. */
+                       strcpy(buffer, p+1);
+                       p = buffer;
+                       while (*p != ')')
+                       {
+                               if (*p == '\0')
+                               {
+                                       if (!is_silent)
+                                               fvwm_msg(ERR, "ParseBinding",
+                                                       "Syntax error in line 
%s - missing ')'", tline);
+                                       return 0;
+                               }
+                               ++p;
+                       }
+                       *p++ = '\0';
+                       windowName = buffer;
+                       if (*p == '\0')
+                       {
+                               if (!is_silent)
+                                       fvwm_msg(ERR, "ParseBinding",
+                                               "Syntax error in line %s - no 
context specified with window", tline);
+                               return 0;
+                       }
+               }
+               n2 = sscanf(p, "%79s", context_string);
        }
        token = PeekToken(ptr, &action);
        if (token != NULL)
@@ -437,7 +476,7 @@
        /* BEGIN remove */
        CollectBindingList(
                dpy, pblist, &rmlist, type, STROKE_ARG((void *)stroke)
-               button, keysym, modifier, context);
+               button, keysym, modifier, context, windowName);
        if (rmlist != NULL)
        {
                is_binding_removed = True;
@@ -502,7 +541,7 @@
        rc = AddBinding(
                dpy, pblist, type, STROKE_ARG((void *)stroke)
                button, keysym, key_string, modifier, context, (void *)action,
-               NULL);
+               NULL, windowName);
 
        return rc;
 }
Index: fvwm/bindings.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/bindings.h,v
retrieving revision 1.16
diff -u -r1.16 bindings.h
--- fvwm/bindings.h     29 Jun 2003 19:53:22 -0000      1.16
+++ fvwm/bindings.h     2 Mar 2004 16:48:07 -0000
@@ -4,6 +4,8 @@
 #define BINDINGS_H
 
 /* ---------------------------- included header files ---------------------- */
+#include "fvwm.h"                      /* FvwmWindow */
+#include "libs/Bindings.h"     /* Binding */
 
 /* ---------------------------- global definitions ------------------------- */
 
@@ -20,6 +22,16 @@
 void update_key_bindings(void);
 unsigned int MaskUsedModifiers(unsigned int in_modifiers);
 unsigned int GetUnusedModifiers(void);
+Bool bindingAppliesToFWindow (Binding *b, FvwmWindow *fw);
+void grabAllFWindowKeys(
+    Display *dpy, Window w, Binding *blist, unsigned int contexts,
+    unsigned int dead_modifiers, Bool fGrab, FvwmWindow *fw);
+void grabAllFWindowKeysAndButtons(
+    Display *dpy, Window w, Binding *blist, unsigned int contexts,
+    unsigned int dead_modifiers, Cursor cursor, Bool fGrab,
+    FvwmWindow *fw);
+
+
 
 #endif /* BINDINGS_H */
 
Index: fvwm/builtins.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/builtins.c,v
retrieving revision 1.405
diff -u -r1.405 builtins.c
--- fvwm/builtins.c     19 Feb 2004 09:36:01 -0000      1.405
+++ fvwm/builtins.c     2 Mar 2004 16:48:14 -0000
@@ -2553,12 +2553,13 @@
                        }
                        else if (e.type == KeyPress)
                        {
+                               /* TODO: should I be using <t> or <exc->w.fw>? 
*/
+                               int context = GetContext(&t, t, &e, &nonewin);
                                escape = CheckBinding(
                                        Scr.AllBindings, STROKE_ARG(0)
                                        e.xkey.keycode, e.xkey.state,
-                                       GetUnusedModifiers(),
-                                       GetContext(&t, t, &e, &nonewin),
-                                       BIND_KEYPRESS);
+                                       GetUnusedModifiers(), context,
+                                       BIND_KEYPRESS, &t->class, t->name.name);
                                if (escape != NULL)
                                {
                                        if (!strcasecmp(escape,"escapefunc"))
@@ -4209,7 +4210,8 @@
        /* check for a binding */
        stroke_action = CheckBinding(
                Scr.AllBindings, sequence, 0, modifiers, GetUnusedModifiers(),
-               exc->w.wcontext, BIND_STROKE);
+               exc->w.wcontext, BIND_STROKE, &exc->w.fw->class,
+               exc->w.fw->name.name);
 
        /* execute the action */
        if (stroke_action != NULL)
Index: fvwm/events.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/events.c,v
retrieving revision 1.490
diff -u -r1.490 events.c
--- fvwm/events.c       26 Feb 2004 14:40:34 -0000      1.490
+++ fvwm/events.c       2 Mar 2004 16:48:24 -0000
@@ -1461,14 +1461,18 @@
 static void __handle_bpress_on_root(const exec_context_t *exc)
 {
        char *action;
+       XClassHint tmp;
 
        PressedW = None;
        __handle_bpress_stroke();
        /* search for an appropriate mouse binding */
+       /* exc->w.fw is always NULL, hence why we use "root". */
+       tmp.res_class = tmp.res_name = "root";
        action = CheckBinding(
                Scr.AllBindings, STROKE_ARG(0) exc->x.etrigger->xbutton.button,
                exc->x.etrigger->xbutton.state, GetUnusedModifiers(), C_ROOT,
-               BIND_BUTTONPRESS);
+               BIND_BUTTONPRESS, &tmp, tmp.res_class);
+
        if (action && *action)
        {
                const exec_context_t *exc2;
@@ -1541,7 +1545,7 @@
                action = CheckBinding(
                        Scr.AllBindings, STROKE_ARG(0) e->xbutton.button,
                        e->xbutton.state, GetUnusedModifiers(),
-                       exc->w.wcontext, BIND_BUTTONPRESS);
+                       exc->w.wcontext, BIND_BUTTONPRESS, &fw->class, 
fw->name.name);
                if (__handle_bpress_action(exc, action))
                {
                        f.do_swallow_click = 1;
@@ -1616,7 +1620,9 @@
        /* need to search for an appropriate stroke binding */
        action = CheckBinding(
                Scr.AllBindings, sequence, te->xbutton.button, real_modifier,
-               GetUnusedModifiers(), ea->exc->w.wcontext, BIND_STROKE);
+               GetUnusedModifiers(), ea->exc->w.wcontext, BIND_STROKE,
+               &ea->exc->w.fw->class, ea->exc->w.fw->name.name);
+
        /* got a match, now process it */
        if (action != NULL && (action[0] != 0))
        {
@@ -2280,45 +2286,60 @@
        const XEvent *te = ea->exc->x.etrigger;
        const FvwmWindow * const fw = ea->exc->w.fw;
        Bool is_second_binding;
+       const XClassHint *winClass1, *winClass2;
+       XClassHint tmp;
+       char *name1, *name2;
+       const exec_context_t *exc;
+       exec_context_changes_t ecc;
 
        PressedW = None;
 
        /* Here's a real hack - some systems have two keys with the
         * same keysym and different keycodes. This converts all
         * the cases to one keycode. */
-       kc = XKeysymToKeycode(
-               dpy, XKeycodeToKeysym(dpy, te->xkey.keycode, 0));
+       kc = XKeysymToKeycode(dpy, XKeycodeToKeysym(dpy, te->xkey.keycode, 0));
 
        /* Check if there is something bound to the key */
        sf = get_focus_window();
        if (sf == NULL)
        {
+               tmp.res_name = tmp.res_class = name1 = "root";
+               winClass1 = &tmp;
                kcontext = C_ROOT;
        }
-       else if (sf == ea->exc->w.fw)
+       else
        {
-               kcontext = ea->exc->w.wcontext;
+               winClass1 = &sf->class;
+               name1 = sf->name.name;
+               kcontext = (sf == fw ? ea->exc->w.wcontext : C_WINDOW);
+       }
+
+       if (fw == NULL)
+       {
+               tmp.res_name = tmp.res_class = name2 = "root";
+               winClass2 = &tmp;
        }
        else
        {
-               kcontext = C_WINDOW;
+               winClass2 = &fw->class;
+               name2 = fw->name.name;
        }
-       action = CheckTwoBindings(
-               &is_second_binding, Scr.AllBindings, STROKE_ARG(0) kc,
-               te->xkey.state, GetUnusedModifiers(), kcontext, BIND_KEYPRESS,
-               ea->exc->w.wcontext, BIND_PKEYPRESS);
+       /* Searching the binding list with a different 'type' value
+        * (ie. BIND_KEYPRESS vs BIND_PKEYPRESS) doesn't make a difference.
+        * The different context value does though. */
+       action = CheckTwoBindings(&is_second_binding, Scr.AllBindings,
+               STROKE_ARG(0) kc, te->xkey.state, GetUnusedModifiers(), 
kcontext,
+               BIND_KEYPRESS, winClass1, name1, ea->exc->w.wcontext,
+               BIND_PKEYPRESS, winClass2, name2);
+
        if (action != NULL)
        {
-               const exec_context_t *exc;
-               exec_context_changes_t ecc;
-
                exc = ea->exc;
                if (is_second_binding == False)
                {
                        ecc.w.fw = sf;
                        ecc.w.wcontext = kcontext;
-                       exc = exc_clone_context(
-                               ea->exc, &ecc, ECC_FW | ECC_WCONTEXT);
+                       exc = exc_clone_context(ea->exc, &ecc, ECC_FW | 
ECC_WCONTEXT);
                }
                execute_function(NULL, exc, action, 0);
                if (is_second_binding == False)
Index: fvwm/fvwm.1.in
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/fvwm.1.in,v
retrieving revision 1.123
diff -u -r1.123 fvwm.1.in
--- fvwm/fvwm.1.in      19 Feb 2004 09:36:01 -0000      1.123
+++ fvwm/fvwm.1.in      2 Mar 2004 16:49:00 -0000
@@ -5753,6 +5753,26 @@
 which mouse button is used to tear off menus.  See the section
 "Tear Off Menus" for details.
 
+By default, the binding applies to all windows. You can specify that
+the binding only applies within an individual window by prefixing the
+.I Context
+field with a wildcard pattern (in brackets) containing the class, resource
+or name of the window you want the binding to apply to.
+
+The following example shows how the same key-binding can be used to
+perform different functions depending on the window that is focussed:
+.EX
+Key V (rxvt)A C Echo ctrl-V-in-RXVT
+Key V (*term)A C Echo ctrl-V-in-Term
+Key V A C Echo ctrl-V-elsewhere
+.EE
+
+This example shows how to display the WindowList when Button 3 is
+pressed on an rxvt window:
+.EX
+Mouse 3 (rxvt)A A WindowList
+.EE
+
 .I Modifiers
 is any combination of 'N' for no modifiers, 'C' for control, 'S'
 for shift, 'M' for Meta, 'L' for Caps-Lock or 'A' for any
Index: fvwm/module_interface.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/module_interface.c,v
retrieving revision 1.159
diff -u -r1.159 module_interface.c
--- fvwm/module_interface.c     2 Mar 2004 11:19:33 -0000       1.159
+++ fvwm/module_interface.c     2 Mar 2004 16:49:11 -0000
@@ -619,7 +619,7 @@
                                GetContext(
                                        NULL, exc->w.fw, &tmpevent,
                                        &targetWindow),
-                               BIND_KEYPRESS);
+                               BIND_KEYPRESS, &exc->w.fw->class, 
exc->w.fw->name.name);
                        if (escape != NULL)
                        {
                                if (!strcasecmp(escape,"escapefunc"))
Index: libs/Bindings.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/libs/Bindings.c,v
retrieving revision 1.60
diff -u -r1.60 Bindings.c
--- libs/Bindings.c     17 Feb 2004 14:17:06 -0000      1.60
+++ libs/Bindings.c     2 Mar 2004 16:49:13 -0000
@@ -52,6 +52,10 @@
        {
                free(b->Action2);
        }
+       if (b->windowName)
+       {
+               free(b->windowName);
+       }
        free(b);
 
        return;
@@ -128,7 +132,7 @@
        Display *dpy, Binding **pblist, binding_t type,
        STROKE_ARG(void *stroke)
        int button, KeySym keysym, char *key_name, int modifiers, int contexts,
-       void *action, void *action2)
+       void *action, void *action2, char *windowName)
 {
        int i;
        int min;
@@ -250,6 +254,8 @@
                                        (action) ? stripcpy(action) : NULL;
                                (*pblist)->Action2 =
                                        (action2) ? stripcpy(action2) : NULL;
+                               (*pblist)->windowName =
+                                       windowName ? stripcpy(windowName) : 
NULL;
                                (*pblist)->NextBinding = temp;
                                bound_mask |= bind_mask;
                                count++;
@@ -259,7 +265,11 @@
        return count;
 }
 
-static Bool AreBindingsEqual(Binding *b1, Binding *b2)
+/*
+ * replacesBinding() - does the new binding, b1, replace a current
+ * binding, b2?
+ */
+static Bool replacesBinding(Binding *b1, Binding *b2)
 {
        if (b1->type != b2->type)
        {
@@ -277,6 +287,24 @@
        {
                return False;
        }
+
+       /* definition: "global binding" => b->windowName == NULL
+        * definition: "window-specific binding" => b->windowName != NULL
+        */
+       if (b1->windowName && b2->windowName)
+       {
+               /* Both bindings are window-specific. The existing binding, b2,
+                * is only replaced (by b1) if it applies to the same window */
+               if (strcmp(b1->windowName, b2->windowName) != 0)
+                       return False;
+       }
+       else if (b1->windowName || b2->windowName)
+       {
+               /* 1 binding is window-specific, the other is global - no need 
to
+                * replace this binding. */
+               return False;
+       }
+
        if (BIND_IS_KEY_BINDING(b1->type) || BIND_IS_MOUSE_BINDING(b1->type))
        {
                return True;
@@ -301,7 +329,7 @@
 void CollectBindingList(
        Display *dpy, Binding **pblist_src, Binding **pblist_dest,
        binding_t type, STROKE_ARG(void *stroke)
-       int button, KeySym keysym, int modifiers, int contexts)
+       int button, KeySym keysym, int modifiers, int contexts, char 
*windowName)
 {
        Binding *tmplist = NULL;
        Binding *btmp;
@@ -312,7 +340,7 @@
        /* generate a private list of bindings to be removed */
        AddBinding(
                dpy, &tmplist, type, STROKE_ARG(stroke)
-               button, keysym, NULL, modifiers, contexts, NULL, NULL);
+               button, keysym, NULL, modifiers, contexts, NULL, NULL, 
windowName);
        /* now find equivalent bindings in the given binding list and move
         * them to the new clist */
        for (bold = *pblist_src, oldprev = NULL; bold != NULL;
@@ -321,7 +349,7 @@
                for (btmp = tmplist, tmpprev = NULL; btmp != NULL;
                     tmpprev = btmp, btmp = btmp->NextBinding)
                {
-                       if (AreBindingsEqual(btmp, bold))
+                       if (replacesBinding(btmp, bold))
                        {
                                /* move matched binding from src list to dest
                                 * list */
@@ -342,10 +370,37 @@
        return;
 }
 
+/*
+ * bindingAppliesToWindow()
+ *
+ * The Key/Mouse/PointerKey syntax (optionally) allows a window name
+ * (or class or resource) to be specified with the binding, denoting
+ * which windows the binding can be invoked in. This function determines
+ * if the binding actually applies to a window based on its
+ * name/class/resource.
+ */
+Bool bindingAppliesToWindow(Binding *binding, const XClassHint *winClass,
+       const char *winName)
+{
+       /* If no window name is specified with the binding then that means
+        * the binding applies to ALL windows. */
+       if (binding->windowName == NULL)
+               return True;
+
+       if (matchWildcards(binding->windowName, winName) == TRUE ||
+               matchWildcards(binding->windowName, winClass->res_name) == TRUE 
||
+               matchWildcards(binding->windowName, winClass->res_class) == 
TRUE)
+       {
+               return True;
+       }
+       return False;
+}
+
 Bool __compare_binding(
        Binding *b, STROKE_ARG(char *stroke)
        int button_keycode, unsigned int modifier, unsigned int used_modifiers,
-       int Context, binding_t type)
+       int Context, binding_t type, const XClassHint *winClass,
+    const char *winName)
 {
        if (b->type != type || !(b->Context & Context))
        {
@@ -356,24 +411,30 @@
        {
                return False;
        }
+
        if (BIND_IS_MOUSE_BINDING(type) &&
-           (b->Button_Key == button_keycode || b->Button_Key == 0))
+           (b->Button_Key != button_keycode && b->Button_Key != 0))
        {
-               return True;
+               return False;
        }
-       if (BIND_IS_KEY_BINDING(type) &&
-           b->Button_Key == button_keycode)
+       else if (BIND_IS_KEY_BINDING(type) && b->Button_Key != button_keycode)
        {
-               return True;
+               return False;
        }
-       if (0 STROKE_CODE(|| ((BIND_IS_STROKE_BINDING(type) &&
-                              (strcmp(b->Stroke_Seq,stroke) == 0) &&
-                              b->Button_Key == button_keycode))))
+#ifdef HAVE_STROKE
+       else if (BIND_IS_STROKE_BINDING(type) &&
+               (strcmp(b->Stroke_Seq, stroke) != 0) &&
+                b->Button_Key != button_keycode)
        {
-               return True;
+               return False;
        }
+#endif
 
-       return False;
+       if (!bindingAppliesToWindow(b, winClass, winName))
+       {
+               return False;
+       }
+       return True;
 }
 
 /* Check if something is bound to a key or button press and return the action
@@ -381,84 +442,68 @@
 void *CheckBinding(
        Binding *blist, STROKE_ARG(char *stroke)
        int button_keycode, unsigned int modifier,unsigned int dead_modifiers,
-       int Context, binding_t type)
+       int Context, binding_t type, const XClassHint *winClass,
+       const char *winName)
 {
        Binding *b;
        unsigned int used_modifiers = ~dead_modifiers;
+       void *action = NULL;
 
        modifier &= (used_modifiers & ALL_MODIFIERS);
        for (b = blist; b != NULL; b = b->NextBinding)
        {
                if (__compare_binding(
-                           b, STROKE_ARG(stroke) button_keycode, modifier,
-                           used_modifiers, Context, type) == True)
+                               b, STROKE_ARG(stroke) button_keycode, modifier,
+                           used_modifiers, Context, type, winClass, winName) 
== True)
                {
-                       return b->Action;
+                       action = b->Action;
+                       /* If this is a global binding, keep searching <blist> 
in the
+                        * hope of finding a window-specific binding. */
+                       if (b->windowName)
+                               break;
                }
        }
 
-       return NULL;
+       return action;
 }
 
 void *CheckTwoBindings(
        Bool *ret_is_second_binding, Binding *blist, STROKE_ARG(char *stroke)
        int button_keycode, unsigned int modifier,unsigned int dead_modifiers,
-       int Context, binding_t type, int Context2, binding_t type2)
+       int Context, binding_t type, const XClassHint *winClass,
+       const char *winName, int Context2, binding_t type2,
+       const XClassHint *winClass2, const char *winName2)
 {
        Binding *b;
        unsigned int used_modifiers = ~dead_modifiers;
+       void *action = NULL;
 
        modifier &= (used_modifiers & ALL_MODIFIERS);
        for (b = blist; b != NULL; b = b->NextBinding)
        {
                if (__compare_binding(
                            b, STROKE_ARG(stroke) button_keycode, modifier,
-                           used_modifiers, Context, type) == True)
+                           used_modifiers, Context, type, winClass, winName) 
== True)
                {
                        *ret_is_second_binding = False;
-                       return b->Action;
+                       action = b->Action;
+                       if (b->windowName)
+                               break;
                }
                if (__compare_binding(
                            b, STROKE_ARG(stroke) button_keycode, modifier,
-                           used_modifiers, Context2, type2) == True)
+                           used_modifiers, Context2, type2, winClass2, 
winName2) == True)
                {
+                       if (action && !b->windowName)
+                               continue;
                        *ret_is_second_binding = True;
-                       return b->Action;
+                       action = b->Action;
+                       if (b->windowName)
+                               break;
                }
        }
-       *ret_is_second_binding = False;
 
-       return NULL;
-}
-
-/* same as above, but only returns exactly matching bindings, i.e. wildcards 
for
- * mouse buttons and modifiers must match exactly. */
-Bool MatchBindingExactly(
-       Binding *b, STROKE_ARG(void *stroke)
-       int button, KeyCode keycode, unsigned int modifier, int Context,
-       binding_t type)
-{
-       modifier &= ALL_MODIFIERS;
-       if (b->type != type || b->Context != Context || b->Modifier != modifier)
-       {
-               return False;
-       }
-       if (BIND_IS_KEY_BINDING(type) && b->Button_Key != keycode)
-       {
-               return False;
-       }
-       if (BIND_IS_MOUSE_BINDING(type) && b->Button_Key != button)
-       {
-               return False;
-       }
-       if (0 STROKE_CODE(|| ((BIND_IS_STROKE_BINDING(type) &&
-                              (b->Button_Key != button ||
-                               (strcmp(b->Stroke_Seq,stroke) != 0))))))
-       {
-               return False;
-       }
-
-       return True;
+       return action;
 }
 
 /*
@@ -658,8 +703,8 @@
        is_grabbing_everything = True;
        for ( ; blist != NULL; blist = blist->NextBinding)
        {
-               GrabWindowButton(
-                       dpy, w, blist, contexts, dead_modifiers, cursor, fGrab);
+               GrabWindowButton(dpy, w, blist, contexts, dead_modifiers,
+                       cursor, fGrab);
        }
        is_grabbing_everything = False;
        MyXUngrabServer(dpy);
Index: libs/Bindings.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/libs/Bindings.h,v
retrieving revision 1.6
diff -u -r1.6 Bindings.h
--- libs/Bindings.h     5 Jul 2003 01:37:47 -0000       1.6
+++ libs/Bindings.h     2 Mar 2004 16:49:13 -0000
@@ -1,5 +1,7 @@
 /* -*-c-*- */
 
+#include <X11/Xutil.h> /* XClassHint */
+
 #ifndef FVWMLIB_BINDINGS_H_H
 #define FVWMLIB_BINDINGS_H_H
 
@@ -32,12 +34,14 @@
 {
        binding_t_t type;       /* Is it a mouse, key, or stroke binding */
        STROKE_CODE(void *Stroke_Seq;) /* stroke sequence */
-               int Button_Key;         /* Mouse Button number or Keycode */
+       int Button_Key;         /* Mouse Button number or Keycode */
        char *key_name;         /* In case of keycode, give the key_name too */
        int Context;            /* Fvwm context, ie titlebar, frame, etc */
        int Modifier;           /* Modifiers for keyboard state */
        void *Action;           /* What to do? */
        void *Action2;          /* This one can be used too */
+       char *windowName;               /* Name of window (regex pattern) this 
binding
+                                                          applies to. NULL 
means all windows. */
        struct Binding *NextBinding;
 } Binding;
 
@@ -46,11 +50,11 @@
 void CollectBindingList(
        Display *dpy, Binding **pblist_src, Binding **pblist_dest,
        binding_t type, STROKE_ARG(void *stroke) int button, KeySym keysym,
-       int modifiers, int contexts);
+       int modifiers, int contexts, char *windowName);
 int AddBinding(
        Display *dpy, Binding **pblist, binding_t type,
        STROKE_ARG(void *stroke) int button, KeySym keysym, char *key_name,
-       int modifiers, int contexts, void *action, void *action2);
+       int modifiers, int contexts, void *action, void *action2, char 
*windowName);
 void FreeBindingStruct(Binding *b);
 void FreeBindingList(Binding *b);
 void RemoveBinding(Binding **pblist, Binding *b, Binding *prev);
@@ -61,14 +65,13 @@
 void *CheckBinding(
        Binding *blist, STROKE_ARG(char *stroke) int button_keycode,
        unsigned int modifier, unsigned int dead_modifiers, int Context,
-       binding_t type);
+       binding_t type, const XClassHint *winClass, const char *winName);
 void *CheckTwoBindings(
        Bool *ret_is_second_binding, Binding *blist, STROKE_ARG(char *stroke)
        int button_keycode, unsigned int modifier,unsigned int dead_modifiers,
-       int Context, binding_t type, int Context2, binding_t type2);
-Bool MatchBindingExactly(
-       Binding *b, STROKE_ARG(void *stroke) int button, KeyCode keycode,
-       unsigned int modifier, int Context, binding_t type);
+       int Context, binding_t type, const XClassHint *winClass,
+       const char *winName, int Context2, binding_t type2,
+       const XClassHint *winClass2, const char *winName2);
 void GrabWindowKey(
        Display *dpy, Window w, Binding *binding, unsigned int contexts,
        unsigned int dead_modifiers, Bool fGrab);
@@ -88,5 +91,8 @@
        Display *dpy, Window w, Binding *binding, unsigned int contexts,
        unsigned int dead_modifiers, Cursor cursor, Bool fGrab);
 KeySym FvwmStringToKeysym(Display *dpy, char *key);
+Bool bindingAppliesToWindow(Binding *binding, const XClassHint *winClass,
+       const char *winName);
+
 
 #endif /* FVWMLIB_BINDINGS_H_H */
Index: libs/fvwmlib.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/libs/fvwmlib.h,v
retrieving revision 1.119
diff -u -r1.119 fvwmlib.h
--- libs/fvwmlib.h      7 Aug 2003 17:23:27 -0000       1.119
+++ libs/fvwmlib.h      2 Mar 2004 16:49:15 -0000
@@ -109,7 +109,7 @@
 #include "envvar.h"
 #include "safemalloc.h"
 
-int matchWildcards(char *pattern, char *string);
+extern int matchWildcards(const char *pattern, const char *string);
 
 #define MAX_MODULE_INPUT_TEXT_LEN 1000
 
Index: libs/wild.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/libs/wild.c,v
retrieving revision 1.8
diff -u -r1.8 wild.c
--- libs/wild.c 29 Jun 2003 19:53:24 -0000      1.8
+++ libs/wild.c 2 Mar 2004 16:49:15 -0000
@@ -34,7 +34,7 @@
  *      It is public domain, no strings attached. No guarantees either.
  *
  */
-int matchWildcards(char *pattern, char *string)
+int matchWildcards(const char *pattern, const char *string)
 {
        if(string == NULL)
        {
Index: libs/wild.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/libs/wild.h,v
retrieving revision 1.4
diff -u -r1.4 wild.h
--- libs/wild.h 29 Jun 2003 19:53:24 -0000      1.4
+++ libs/wild.h 2 Mar 2004 16:49:15 -0000
@@ -9,4 +9,4 @@
  *      It is public domain, no strings attached. No guarantees either.
  *
  */
-int matchWildcards(char *pattern, char *string);
+int matchWildcards(const char *pattern, const char *string);
Index: modules/FvwmIconBox/FvwmIconBox.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmIconBox/FvwmIconBox.h,v
retrieving revision 1.29
diff -u -r1.29 FvwmIconBox.h
--- modules/FvwmIconBox/FvwmIconBox.h   6 Jul 2003 14:34:07 -0000       1.29
+++ modules/FvwmIconBox/FvwmIconBox.h   2 Mar 2004 16:49:16 -0000
@@ -63,7 +63,7 @@
 extern Bool SortItem(struct icon_info *item);
 extern struct icon_info *MinItem(struct icon_info *head);
 extern void ExecuteKey(XEvent event);
-extern int matchWildcards(char *pattern, char *string);
+extern int matchWildcards(const char *pattern, const char *string);
 extern Bool GetBackPixmap(void);
 extern int LookInList(struct icon_info *item);
 extern char *stripcpy2(char *source);
Index: modules/FvwmScript/FvwmScript.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmScript/FvwmScript.c,v
retrieving revision 1.70
diff -u -r1.70 FvwmScript.c
--- modules/FvwmScript/FvwmScript.c     4 Jan 2004 12:39:30 -0000       1.70
+++ modules/FvwmScript/FvwmScript.c     2 Mar 2004 16:49:20 -0000
@@ -857,6 +857,7 @@
   Bool find = False;
   char *action;
   int ex, ey, ex2, ey2;
+  XClassHint tmp;
 
   while (FEventsQueued(dpy, QueuedAfterReading))
   {
@@ -936,14 +937,17 @@
        XKeysymToKeycode(dpy,XKeycodeToKeysym(dpy,event.xkey.keycode,0));
 
       /* check for bindings defined by the Key instruction */
+         tmp.res_class = tmp.res_name = "root";
       if ((action = CheckBinding(
                   BindingsList, STROKE_ARG(0) event.xkey.keycode,
-                  event.xkey.state, LockMask, C_WINDOW, BIND_KEYPRESS)) !=
+                  event.xkey.state, LockMask, C_WINDOW, BIND_KEYPRESS,
+                  &tmp, tmp.res_class)) !=
          NULL)
       {
        SendMsgAndString(action, "CheckBinding");
        break;
       }
+
       if (ks == XK_Tab) {
        isTab = 1;
        if (event.xkey.state & ShiftMask) {
Index: modules/FvwmScript/Instructions.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmScript/Instructions.c,v
retrieving revision 1.50
diff -u -r1.50 Instructions.c
--- modules/FvwmScript/Instructions.c   5 Jul 2003 01:37:47 -0000       1.50
+++ modules/FvwmScript/Instructions.c   2 Mar 2004 16:49:23 -0000
@@ -1828,7 +1828,7 @@
 
   AddBinding(
          dpy, &BindingsList, BIND_KEYPRESS, STROKE_ARG(0) 0, keysym,
-         key_string, modifier, C_WINDOW, (void *)action, NULL);
+         key_string, modifier, C_WINDOW, (void *)action, NULL, NULL);
   free(key_string);
   free(in_modifier);
 }

Reply via email to