]> Dogcows Code - chaz/openbox/blobdiff - plugins/mouse/mouse.c
move the openbox engine into librender and the kernel. the theme is loaded and stored...
[chaz/openbox] / plugins / mouse / mouse.c
index 9a1549362f029419f4852ffe0ba43f794767d39e..b2173c25156a9a2a3c870a7a59a3cb4cf4b71e67 100644 (file)
-#include "../../kernel/openbox.h"
-#include "../../kernel/dispatch.h"
-#include "../../kernel/action.h"
-#include "../../kernel/event.h"
-#include "../../kernel/client.h"
-#include "../../kernel/frame.h"
-#include "../../kernel/grab.h"
-#include "../../kernel/engine.h"
+#include "kernel/openbox.h"
+#include "kernel/dispatch.h"
+#include "kernel/action.h"
+#include "kernel/event.h"
+#include "kernel/client.h"
+#include "kernel/grab.h"
+#include "kernel/parse.h"
+#include "kernel/frame.h"
 #include "translate.h"
 #include "mouse.h"
 #include "translate.h"
 #include "mouse.h"
-#include "mouserc_parse.h"
+#include "mouseparse.h"
 #include <glib.h>
 
 #include <glib.h>
 
-void plugin_setup_config()
+static int threshold;
+static int dclicktime;
+
+static void parse_assign(char *name, ParseToken *value)
 {
 {
+    if (!g_ascii_strcasecmp(name, "dragthreshold")) {
+        if (value->type != TOKEN_INTEGER)
+            yyerror("invalid value");
+        else {
+            if (value->data.integer >= 0)
+                threshold = value->data.integer;
+        }
+    } else if (!g_ascii_strcasecmp(name, "doubleclicktime")) {
+        if (value->type != TOKEN_INTEGER)
+            yyerror("invalid value");
+        else {
+            if (value->data.integer >= 0)
+                dclicktime = value->data.integer;
+        }
+    } else
+        yyerror("invalid option");
+    parse_free_token(value);
 }
 
 }
 
-static int drag_threshold = 3;
-
-/* GData of GSList*s of PointerBinding*s. */
-static GData *bound_contexts;
-
-struct foreach_grab_temp {
-    Client *client;
-    gboolean grab;
-};
-
-static void foreach_grab(GQuark key, gpointer data, gpointer user_data)
+void plugin_setup_config()
 {
 {
-    struct foreach_grab_temp *d = user_data;
-    GSList *it;
-    for (it = data; it != NULL; it = it->next) {
-        /* grab/ungrab the button */
-       MouseBinding *b = it->data;
-        Window win;
-        int mode;
-        unsigned int mask;
-
-        if (key == g_quark_try_string("frame")) {
-            win = d->client->frame->window;
-            mode = GrabModeAsync;
-            mask = ButtonPressMask | ButtonMotionMask | ButtonReleaseMask;
-        } else if (key == g_quark_try_string("client")) {
-            win = d->client->frame->plate;
-            mode = GrabModeSync; /* this is handled in event */
-            mask = ButtonPressMask; /* can't catch more than this with Sync
-                                       mode the release event is manufactured
-                                       in event */
-        } else return;
-
-        if (d->grab)
-            grab_button(b->button, b->state, win, mask, mode);
-        else
-            ungrab_button(b->button, b->state, win);
-    }
+    threshold = 3;
+    dclicktime = 200;
+    parse_reg_section("mouse", mouseparse, parse_assign);
 }
 }
-  
+
+/* Array of GSList*s of PointerBinding*s. */
+static GSList *bound_contexts[NUM_CONTEXTS];
+
 static void grab_for_client(Client *client, gboolean grab)
 {
 static void grab_for_client(Client *client, gboolean grab)
 {
-    struct foreach_grab_temp bt;
-    bt.client = client;
-    bt.grab = grab;
-    g_datalist_foreach(&bound_contexts, foreach_grab, &bt);
+    int i;
+    GSList *it;
+
+    for (i = 0; i < NUM_CONTEXTS; ++i)
+        for (it = bound_contexts[i]; it != NULL; it = it->next) {
+            /* grab/ungrab the button */
+            MouseBinding *b = it->data;
+            Window win;
+            int mode;
+            unsigned int mask;
+
+            if (i == Context_Frame) {
+                win = client->frame->window;
+                mode = GrabModeAsync;
+                mask = ButtonPressMask | ButtonMotionMask | ButtonReleaseMask;
+            } else if (i == Context_Client) {
+                win = client->frame->plate;
+                mode = GrabModeSync; /* this is handled in event */
+                mask = ButtonPressMask; /* can't catch more than this with Sync
+                                           mode the release event is
+                                           manufactured in event() */
+            } else continue;
+
+            if (grab)
+                grab_button(b->button, b->state, win, mask, mode);
+            else
+                ungrab_button(b->button, b->state, win);
+        }
 }
 
 static void grab_all_clients(gboolean grab)
 {
 }
 
 static void grab_all_clients(gboolean grab)
 {
-    GSList *it;
+    GList *it;
 
     for (it = client_list; it != NULL; it = it->next)
        grab_for_client(it->data, grab);
 }
 
 
     for (it = client_list; it != NULL; it = it->next)
        grab_for_client(it->data, grab);
 }
 
-static void foreach_clear(GQuark key, gpointer data, gpointer user_data)
+static void clearall()
 {
 {
+    int i;
     GSList *it;
     GSList *it;
-    user_data = user_data;
-    for (it = data; it != NULL; it = it->next) {
-       int i;
-
-        MouseBinding *b = it->data;
-       for (i = 0; i < NUM_MOUSEACTION; ++i)
-            if (b->action[i] != NULL)
-                action_free(b->action[i]);
-        g_free(b);
+    
+    for(i = 0; i < NUM_CONTEXTS; ++i) {
+        for (it = bound_contexts[i]; it != NULL; it = it->next) {
+            int j;
+
+            MouseBinding *b = it->data;
+            for (j = 0; j < NUM_MOUSEACTION; ++j)
+                if (b->action[j] != NULL)
+                    action_free(b->action[j]);
+            g_free(b);
+        }
+        g_slist_free(bound_contexts[i]);
     }
     }
-    g_slist_free(data);
 }
 
 }
 
-static void fire_button(MouseAction a, GQuark context, Client *c, guint state,
+static void fire_button(MouseAction a, Context context, Client *c, guint state,
                         guint button)
 {
     GSList *it;
     MouseBinding *b;
 
                         guint button)
 {
     GSList *it;
     MouseBinding *b;
 
-    for (it = g_datalist_id_get_data(&bound_contexts, context);
-         it != NULL; it = it->next) {
+    for (it = bound_contexts[context]; it != NULL; it = it->next) {
         b = it->data;
         if (b->state == state && b->button == button)
             break;
         b = it->data;
         if (b->state == state && b->button == button)
             break;
@@ -116,7 +132,7 @@ static void fire_button(MouseAction a, GQuark context, Client *c, guint state,
    clicked, Corner_TopLeft if a good default if there is no client 
    Returns True or False for if a binding existed for the action or not.
 */
    clicked, Corner_TopLeft if a good default if there is no client 
    Returns True or False for if a binding existed for the action or not.
 */
-static gboolean fire_motion(MouseAction a, GQuark context, Client *c,
+static gboolean fire_motion(MouseAction a, Context context, Client *c,
                             guint state, guint button, int cx, int cy,
                             int cw, int ch, int dx, int dy,
                             gboolean final, Corner corner)
                             guint state, guint button, int cx, int cy,
                             int cw, int ch, int dx, int dy,
                             gboolean final, Corner corner)
@@ -124,8 +140,7 @@ static gboolean fire_motion(MouseAction a, GQuark context, Client *c,
     GSList *it;
     MouseBinding *b;
 
     GSList *it;
     MouseBinding *b;
 
-    for (it = g_datalist_id_get_data(&bound_contexts, context);
-         it != NULL; it = it->next) {
+    for (it = bound_contexts[context]; it != NULL; it = it->next) {
         b = it->data;
         if (b->state == state && b->button == button)
                break;
         b = it->data;
         if (b->state == state && b->button == button)
                break;
@@ -161,7 +176,8 @@ static gboolean fire_motion(MouseAction a, GQuark context, Client *c,
                 break;
             }
             b->action[a]->data.resize.final = final;
                 break;
             }
             b->action[a]->data.resize.final = final;
-        }
+        } else
+            g_assert_not_reached();
         b->action[a]->func(&b->action[a]->data);
         return TRUE;
     }
         b->action[a]->func(&b->action[a]->data);
         return TRUE;
     }
@@ -187,13 +203,13 @@ static void event(ObEvent *e, void *foo)
 {
     static Time ltime;
     static int px, py, cx, cy, cw, ch, dx, dy;
 {
     static Time ltime;
     static int px, py, cx, cy, cw, ch, dx, dy;
-    static guint button = 0, lbutton = 0;
+    static guint button = 0, state = 0, lbutton = 0;
     static gboolean drag = FALSE, drag_used = FALSE;
     static Corner corner = Corner_TopLeft;
     gboolean click = FALSE;
     gboolean dclick = FALSE;
     static gboolean drag = FALSE, drag_used = FALSE;
     static Corner corner = Corner_TopLeft;
     gboolean click = FALSE;
     gboolean dclick = FALSE;
-    GQuark context;
-
+    Context context;
+    
     switch (e->type) {
     case Event_Client_Mapped:
         grab_for_client(e->data.c.client, TRUE);
     switch (e->type) {
     case Event_Client_Mapped:
         grab_for_client(e->data.c.client, TRUE);
@@ -208,22 +224,30 @@ static void event(ObEvent *e, void *foo)
             if (e->data.x.client != NULL) {
                 cx = e->data.x.client->frame->area.x;
                 cy = e->data.x.client->frame->area.y;
             if (e->data.x.client != NULL) {
                 cx = e->data.x.client->frame->area.x;
                 cy = e->data.x.client->frame->area.y;
-                cw = e->data.x.client->frame->area.width;
-                ch = e->data.x.client->frame->area.height;
+                /* use the client size because the frame can be differently
+                   sized (shaded windows) and we want this based on the clients
+                   size */
+                cw = e->data.x.client->area.width + 
+                    e->data.x.client->frame->size.left +
+                    e->data.x.client->frame->size.right;
+                ch = e->data.x.client->area.height +
+                    e->data.x.client->frame->size.top +
+                    e->data.x.client->frame->size.bottom;
                 px = e->data.x.e->xbutton.x_root;
                 py = e->data.x.e->xbutton.y_root;
                 corner = pick_corner(px, py, cx, cy, cw, ch);
             }
             button = e->data.x.e->xbutton.button;
                 px = e->data.x.e->xbutton.x_root;
                 py = e->data.x.e->xbutton.y_root;
                 corner = pick_corner(px, py, cx, cy, cw, ch);
             }
             button = e->data.x.e->xbutton.button;
+            state = e->data.x.e->xbutton.state;
         }
         }
-        context = engine_get_context(e->data.x.client,
-                                     e->data.x.e->xbutton.window);
+        context = frame_context(e->data.x.client->frame,
+                                e->data.x.e->xbutton.window);
 
         fire_button(MouseAction_Press, context,
                     e->data.x.client, e->data.x.e->xbutton.state,
                     e->data.x.e->xbutton.button);
 
 
         fire_button(MouseAction_Press, context,
                     e->data.x.client, e->data.x.e->xbutton.state,
                     e->data.x.e->xbutton.button);
 
-        if (context == g_quark_try_string("client")) {
+        if (context == Context_Client) {
             /* Replay the event, so it goes to the client*/
             XAllowEvents(ob_display, ReplayPointer, event_lasttime);
             /* Fall through to the release case! */
             /* Replay the event, so it goes to the client*/
             XAllowEvents(ob_display, ReplayPointer, event_lasttime);
             /* Fall through to the release case! */
@@ -231,16 +255,15 @@ static void event(ObEvent *e, void *foo)
             break;
 
     case Event_X_ButtonRelease:
             break;
 
     case Event_X_ButtonRelease:
-        context = engine_get_context(e->data.x.client,
-                                     e->data.x.e->xbutton.window);
+        context = frame_context(e->data.x.client->frame,
+                                e->data.x.e->xbutton.window);
         if (e->data.x.e->xbutton.button == button) {
             /* end drags */
             if (drag_used) {
                 fire_motion(MouseAction_Motion, context,
         if (e->data.x.e->xbutton.button == button) {
             /* end drags */
             if (drag_used) {
                 fire_motion(MouseAction_Motion, context,
-                            e->data.x.client, e->data.x.e->xbutton.state,
-                            e->data.x.e->xbutton.button,
+                            e->data.x.client, state, button,
                             cx, cy, cw, ch, dx, dy, TRUE, corner);
                             cx, cy, cw, ch, dx, dy, TRUE, corner);
-                drag = FALSE;
+                drag = drag_used = FALSE;
                 
                 lbutton = 0;
             } else {
                 
                 lbutton = 0;
             } else {
@@ -257,7 +280,7 @@ static void event(ObEvent *e, void *foo)
                     click = TRUE;
                     /* double clicks happen if there were 2 in a row! */
                     if (lbutton == button &&
                     click = TRUE;
                     /* double clicks happen if there were 2 in a row! */
                     if (lbutton == button &&
-                        e->data.x.e->xbutton.time - 300 <= ltime) {
+                        e->data.x.e->xbutton.time - dclicktime <= ltime) {
                         dclick = TRUE;
                         lbutton = 0;
                     } else
                         dclick = TRUE;
                         lbutton = 0;
                     } else
@@ -267,6 +290,7 @@ static void event(ObEvent *e, void *foo)
             }
 
             button = 0;
             }
 
             button = 0;
+            state = 0;
             ltime = e->data.x.e->xbutton.time;
         }
         fire_button(MouseAction_Release, context,
             ltime = e->data.x.e->xbutton.time;
         }
         fire_button(MouseAction_Release, context,
@@ -287,15 +311,14 @@ static void event(ObEvent *e, void *foo)
             dx = e->data.x.e->xmotion.x_root - px;
             dy = e->data.x.e->xmotion.y_root - py;
             if (!drag &&
             dx = e->data.x.e->xmotion.x_root - px;
             dy = e->data.x.e->xmotion.y_root - py;
             if (!drag &&
-                (ABS(dx) >= drag_threshold || ABS(dy) >= drag_threshold))
+                (ABS(dx) >= threshold || ABS(dy) >= threshold))
                 drag = TRUE;
             if (drag) {
                 drag = TRUE;
             if (drag) {
-                context = engine_get_context(e->data.x.client,
-                                             e->data.x.e->xbutton.window);
+                context = frame_context(e->data.x.client->frame,
+                                        e->data.x.e->xbutton.window);
                 drag_used = fire_motion(MouseAction_Motion, context,
                                         e->data.x.client,
                 drag_used = fire_motion(MouseAction_Motion, context,
                                         e->data.x.client,
-                                        e->data.x.e->xmotion.state,
-                                        button, cx, cy, cw, ch, dx, dy,
+                                        state, button, cx, cy, cw, ch, dx, dy,
                                         FALSE, corner);
             }
         }
                                         FALSE, corner);
             }
         }
@@ -310,7 +333,7 @@ gboolean mbind(char *buttonstr, char *contextstr, MouseAction mact,
                Action *action)
 {
     guint state, button;
                Action *action)
 {
     guint state, button;
-    GQuark context;
+    Context context;
     MouseBinding *b;
     GSList *it;
 
     MouseBinding *b;
     GSList *it;
 
@@ -320,7 +343,7 @@ gboolean mbind(char *buttonstr, char *contextstr, MouseAction mact,
     }
 
     contextstr = g_ascii_strdown(contextstr, -1);
     }
 
     contextstr = g_ascii_strdown(contextstr, -1);
-    context = g_quark_try_string(contextstr);
+    context = frame_context_from_string(contextstr);
     if (!context) {
         g_warning("invalid context '%s'", contextstr);
         g_free(contextstr);
     if (!context) {
         g_warning("invalid context '%s'", contextstr);
         g_free(contextstr);
@@ -328,8 +351,7 @@ gboolean mbind(char *buttonstr, char *contextstr, MouseAction mact,
     }
     g_free(contextstr);
 
     }
     g_free(contextstr);
 
-    for (it = g_datalist_id_get_data(&bound_contexts, context);
-        it != NULL; it = it->next){
+    for (it = bound_contexts[context]; it != NULL; it = it->next){
        b = it->data;
        if (b->state == state && b->button == button) {
            /* already bound */
        b = it->data;
        if (b->state == state && b->button == button) {
            /* already bound */
@@ -349,8 +371,7 @@ gboolean mbind(char *buttonstr, char *contextstr, MouseAction mact,
     b->state = state;
     b->button = button;
     b->action[mact] = action;
     b->state = state;
     b->button = button;
     b->action[mact] = action;
-    g_datalist_id_set_data(&bound_contexts, context, 
-        g_slist_append(g_datalist_id_get_data(&bound_contexts, context), b));
+    bound_contexts[context] = g_slist_append(bound_contexts[context], b);
 
     grab_all_clients(TRUE);
 
 
     grab_all_clients(TRUE);
 
@@ -362,8 +383,6 @@ void plugin_startup()
     dispatch_register(Event_Client_Mapped | Event_Client_Destroy |
                       Event_X_ButtonPress | Event_X_ButtonRelease |
                       Event_X_MotionNotify, (EventHandler)event, NULL);
     dispatch_register(Event_Client_Mapped | Event_Client_Destroy |
                       Event_X_ButtonPress | Event_X_ButtonRelease |
                       Event_X_MotionNotify, (EventHandler)event, NULL);
-
-    mouserc_parse();
 }
 
 void plugin_shutdown()
 }
 
 void plugin_shutdown()
@@ -371,5 +390,5 @@ void plugin_shutdown()
     dispatch_register(0, (EventHandler)event, NULL);
 
     grab_all_clients(FALSE);
     dispatch_register(0, (EventHandler)event, NULL);
 
     grab_all_clients(FALSE);
-    g_datalist_foreach(&bound_contexts, foreach_clear, NULL);
+    clearall();
 }
 }
This page took 0.030466 seconds and 4 git commands to generate.