diff options
| author | Dana Jansens <danakj@orodu.net> | 2003-08-12 07:26:16 +0000 |
|---|---|---|
| committer | Dana Jansens <danakj@orodu.net> | 2003-08-12 07:26:16 +0000 |
| commit | c90da6da781932c2d178bfb7e39ec1d5003543b7 (patch) | |
| tree | e9ed8a17f574701880fe73fcfbd872cdb4868c4d /plugins/mouse/mouse.c | |
| parent | cb49f853c9b62c4403eb562d39f52c51da292c4f (diff) | |
move the keyboard and mouse plugins into the kernel for mucho sexiness.
make workspace changing a grabbed/interactive process like focus cycling is, with the popup and all.
this is some hot shit.
Diffstat (limited to 'plugins/mouse/mouse.c')
| -rw-r--r-- | plugins/mouse/mouse.c | 456 |
1 files changed, 0 insertions, 456 deletions
diff --git a/plugins/mouse/mouse.c b/plugins/mouse/mouse.c deleted file mode 100644 index 913a2e4a..00000000 --- a/plugins/mouse/mouse.c +++ /dev/null @@ -1,456 +0,0 @@ -#include "kernel/openbox.h" -#include "kernel/dispatch.h" -#include "kernel/action.h" -#include "kernel/event.h" -#include "kernel/client.h" -#include "kernel/prop.h" -#include "kernel/grab.h" -#include "kernel/frame.h" -#include "parser/parse.h" -#include "translate.h" -#include "mouse.h" -#include <glib.h> - -static int threshold; -static int dclicktime; -/* - -<context name="Titlebar"> - <mousebind button="Left" action="Press"> - <action name="Raise"></action> - </mousebind> -</context> - -*/ - -static void parse_xml(xmlDocPtr doc, xmlNodePtr node, void *d) -{ - xmlNodePtr n, nbut, nact; - char *buttonstr; - char *contextstr; - MouseAction mact; - Action *action; - - node = node->xmlChildrenNode; - - if ((n = parse_find_node("dragThreshold", node))) - threshold = parse_int(doc, n); - if ((n = parse_find_node("doubleClickTime", node))) - dclicktime = parse_int(doc, n); - - n = parse_find_node("context", node); - while (n) { - if (!parse_attr_string("name", n, &contextstr)) - goto next_n; - nbut = parse_find_node("mousebind", n->xmlChildrenNode); - while (nbut) { - if (!parse_attr_string("button", nbut, &buttonstr)) - goto next_nbut; - if (parse_attr_contains("press", nbut, "action")) - mact = MouseAction_Press; - else if (parse_attr_contains("release", nbut, "action")) - mact = MouseAction_Release; - else if (parse_attr_contains("click", nbut, "action")) - mact = MouseAction_Click; - else if (parse_attr_contains("doubleclick", nbut,"action")) - mact = MouseAction_DClick; - else if (parse_attr_contains("drag", nbut, "action")) - mact = MouseAction_Motion; - else - goto next_nbut; - nact = parse_find_node("action", nbut->xmlChildrenNode); - while (nact) { - if ((action = action_parse(doc, nact))) { - /* validate that its okay for a mouse binding*/ - if (mact == MouseAction_Motion) { - if (action->func != action_moveresize || - action->data.moveresize.corner == - prop_atoms.net_wm_moveresize_move_keyboard || - action->data.moveresize.corner == - prop_atoms.net_wm_moveresize_size_keyboard) { - action_free(action); - action = NULL; - } - } else { - if (action->func == action_moveresize && - action->data.moveresize.corner != - prop_atoms.net_wm_moveresize_move_keyboard && - action->data.moveresize.corner != - prop_atoms.net_wm_moveresize_size_keyboard) { - action_free(action); - action = NULL; - } - } - if (action) - mbind(buttonstr, contextstr, mact, action); - } - nact = parse_find_node("action", nact->next); - } - g_free(buttonstr); - next_nbut: - nbut = parse_find_node("mousebind", nbut->next); - } - g_free(contextstr); - next_n: - n = parse_find_node("context", n->next); - } -} - -void plugin_setup_config() -{ - threshold = 3; - dclicktime = 200; - parse_register("mouse", parse_xml, NULL); -} - -/* Array of GSList*s of PointerBinding*s. */ -static GSList *bound_contexts[OB_FRAME_NUM_CONTEXTS]; - -static void grab_for_client(ObClient *client, gboolean grab) -{ - int i; - GSList *it; - - for (i = 0; i < OB_FRAME_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 == OB_FRAME_CONTEXT_FRAME) { - win = client->frame->window; - mode = GrabModeAsync; - mask = ButtonPressMask | ButtonMotionMask | ButtonReleaseMask; - } else if (i == OB_FRAME_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_full(b->button, b->state, win, mask, mode, None); - else - ungrab_button(b->button, b->state, win); - } -} - -static void grab_all_clients(gboolean grab) -{ - GList *it; - - for (it = client_list; it != NULL; it = it->next) - grab_for_client(it->data, grab); -} - -static void clearall() -{ - int i; - GSList *it; - - for(i = 0; i < OB_FRAME_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) { - GSList *it; - for (it = b->actions[j]; it; it = it->next) { - action_free(it->data); - } - g_slist_free(b->actions[j]); - } - g_free(b); - } - g_slist_free(bound_contexts[i]); - } -} - -static void fire_button(MouseAction a, ObFrameContext context, - ObClient *c, guint state, - guint button, int x, int y) -{ - GSList *it; - MouseBinding *b; - - for (it = bound_contexts[context]; it != NULL; it = it->next) { - b = it->data; - if (b->state == state && b->button == button) - break; - } - /* if not bound, then nothing to do! */ - if (it == NULL) return; - - for (it = b->actions[a]; it; it = it->next) { - Action *act = it->data; - if (act->func != NULL) { - act->data.any.c = c; - - g_assert(act->func != action_moveresize); - - if (act->func == action_showmenu) { - act->data.showmenu.x = x; - act->data.showmenu.y = y; - } - - act->func(&act->data); - } - } -} - -static void fire_motion(MouseAction a, ObFrameContext context, ObClient *c, - guint state, guint button, int x_root, int y_root, - guint32 corner) -{ - GSList *it; - MouseBinding *b; - - for (it = bound_contexts[context]; it != NULL; it = it->next) { - b = it->data; - if (b->state == state && b->button == button) - break; - } - /* if not bound, then nothing to do! */ - if (it == NULL) return; - - for (it = b->actions[a]; it; it = it->next) { - Action *act = it->data; - if (act->func != NULL) { - act->data.any.c = c; - - if (act->func == action_moveresize) { - act->data.moveresize.x = x_root; - act->data.moveresize.y = y_root; - act->data.moveresize.button = button; - if (!(act->data.moveresize.corner == - prop_atoms.net_wm_moveresize_move || - act->data.moveresize.corner == - prop_atoms.net_wm_moveresize_move_keyboard || - act->data.moveresize.corner == - prop_atoms.net_wm_moveresize_size_keyboard)) - act->data.moveresize.corner = corner; - } else - g_assert_not_reached(); - - act->func(&act->data); - } - } -} - -static guint32 pick_corner(int x, int y, int cx, int cy, int cw, int ch) -{ - if (x - cx < cw / 2) { - if (y - cy < ch / 2) - return prop_atoms.net_wm_moveresize_size_topleft; - else - return prop_atoms.net_wm_moveresize_size_bottomleft; - } else { - if (y - cy < ch / 2) - return prop_atoms.net_wm_moveresize_size_topright; - else - return prop_atoms.net_wm_moveresize_size_bottomright; - } -} - -static void event(ObEvent *e, void *foo) -{ - static Time ltime; - static guint button = 0, state = 0, lbutton = 0; - static Window lwindow = None; - static int px, py; - gboolean click = FALSE; - gboolean dclick = FALSE; - ObFrameContext context; - - switch (e->type) { - case Event_Client_Mapped: - grab_for_client(e->data.c.client, TRUE); - break; - - case Event_Client_Destroy: - grab_for_client(e->data.c.client, FALSE); - break; - - case Event_X_ButtonPress: - context = frame_context(e->data.x.client, - e->data.x.e->xbutton.window); - - px = e->data.x.e->xbutton.x_root; - py = e->data.x.e->xbutton.y_root; - button = e->data.x.e->xbutton.button; - state = e->data.x.e->xbutton.state; - - fire_button(MouseAction_Press, context, - e->data.x.client, e->data.x.e->xbutton.state, - e->data.x.e->xbutton.button, - e->data.x.e->xbutton.x_root, e->data.x.e->xbutton.y_root); - - if (context == OB_FRAME_CONTEXT_CLIENT) { - /* Replay the event, so it goes to the client*/ - XAllowEvents(ob_display, ReplayPointer, event_lasttime); - /* Fall through to the release case! */ - } else - break; - - case Event_X_ButtonRelease: - context = frame_context(e->data.x.client, - e->data.x.e->xbutton.window); - if (e->data.x.e->xbutton.button == button) { - /* clicks are only valid if its released over the window */ - int junk1, junk2; - Window wjunk; - guint ujunk, b, w, h; - XGetGeometry(ob_display, e->data.x.e->xbutton.window, - &wjunk, &junk1, &junk2, &w, &h, &b, &ujunk); - if (e->data.x.e->xbutton.x >= (signed)-b && - e->data.x.e->xbutton.y >= (signed)-b && - e->data.x.e->xbutton.x < (signed)(w+b) && - e->data.x.e->xbutton.y < (signed)(h+b)) { - click = TRUE; - /* double clicks happen if there were 2 in a row! */ - if (lbutton == button && - lwindow == e->data.x.e->xbutton.window && - e->data.x.e->xbutton.time - dclicktime <= ltime) { - dclick = TRUE; - lbutton = 0; - } else { - lbutton = button; - lwindow = e->data.x.e->xbutton.window; - } - } else { - lbutton = 0; - lwindow = None; - } - - button = 0; - state = 0; - ltime = e->data.x.e->xbutton.time; - } - fire_button(MouseAction_Release, context, - e->data.x.client, e->data.x.e->xbutton.state, - e->data.x.e->xbutton.button, - e->data.x.e->xbutton.x_root, e->data.x.e->xbutton.y_root); - if (click) - fire_button(MouseAction_Click, context, - e->data.x.client, e->data.x.e->xbutton.state, - e->data.x.e->xbutton.button, - e->data.x.e->xbutton.x_root, - e->data.x.e->xbutton.y_root); - if (dclick) - fire_button(MouseAction_DClick, context, - e->data.x.client, e->data.x.e->xbutton.state, - e->data.x.e->xbutton.button, - e->data.x.e->xbutton.x_root, - e->data.x.e->xbutton.y_root); - break; - - case Event_X_MotionNotify: - if (button) { - if (ABS(e->data.x.e->xmotion.x_root - px) >= threshold || - ABS(e->data.x.e->xmotion.y_root - py) >= threshold) { - guint32 corner; - - context = frame_context(e->data.x.client, - e->data.x.e->xmotion.window); - - /* You can't drag on buttons */ - if (context == OB_FRAME_CONTEXT_MAXIMIZE || - context == OB_FRAME_CONTEXT_ALLDESKTOPS || - context == OB_FRAME_CONTEXT_SHADE || - context == OB_FRAME_CONTEXT_ICONIFY || - context == OB_FRAME_CONTEXT_ICON || - context == OB_FRAME_CONTEXT_CLOSE) - break; - - if (!e->data.x.client) - corner = prop_atoms.net_wm_moveresize_size_bottomright; - else - corner = - pick_corner(e->data.x.e->xmotion.x_root, - e->data.x.e->xmotion.y_root, - e->data.x.client->frame->area.x, - e->data.x.client->frame->area.y, - /* use the client size because the frame - can be differently sized (shaded - windows) and we want this based on the - clients size */ - e->data.x.client->area.width + - e->data.x.client->frame->size.left + - e->data.x.client->frame->size.right, - e->data.x.client->area.height + - e->data.x.client->frame->size.top + - e->data.x.client->frame->size.bottom); - fire_motion(MouseAction_Motion, context, - e->data.x.client, state, button, px, py, corner); - button = 0; - state = 0; - } - } - break; - - default: - g_assert_not_reached(); - } -} - -gboolean mbind(char *buttonstr, char *contextstr, MouseAction mact, - Action *action) -{ - guint state, button; - ObFrameContext context; - MouseBinding *b; - GSList *it; - - if (!translate_button(buttonstr, &state, &button)) { - g_warning("invalid button '%s'", buttonstr); - return FALSE; - } - - contextstr = g_ascii_strdown(contextstr, -1); - context = frame_context_from_string(contextstr); - if (!context) { - g_warning("invalid context '%s'", contextstr); - g_free(contextstr); - return FALSE; - } - g_free(contextstr); - - for (it = bound_contexts[context]; it != NULL; it = it->next){ - b = it->data; - if (b->state == state && b->button == button) { - b->actions[mact] = g_slist_append(b->actions[mact], action); - return TRUE; - } - } - - grab_all_clients(FALSE); - - /* add the binding */ - b = g_new0(MouseBinding, 1); - b->state = state; - b->button = button; - b->actions[mact] = g_slist_append(NULL, action); - bound_contexts[context] = g_slist_append(bound_contexts[context], b); - - grab_all_clients(TRUE); - - return TRUE; -} - -void plugin_startup() -{ - dispatch_register(Event_Client_Mapped | Event_Client_Destroy | - Event_X_ButtonPress | Event_X_ButtonRelease | - Event_X_MotionNotify, (EventHandler)event, NULL); -} - -void plugin_shutdown() -{ - dispatch_register(0, (EventHandler)event, NULL); - - grab_all_clients(FALSE); - clearall(); -} |
