summaryrefslogtreecommitdiff
path: root/c/event.c
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-03-21 07:54:23 +0000
committerDana Jansens <danakj@orodu.net>2003-03-21 07:54:23 +0000
commita648c05a7a2608e7e909317f5afe8427a0ea0d68 (patch)
tree9a8355e87192adeec50ee7eaff227decc8af8ffd /c/event.c
parent474f689132d906a553bdc695d3c179652cbe8c53 (diff)
kill the c dir
Diffstat (limited to 'c/event.c')
-rw-r--r--c/event.c593
1 files changed, 0 insertions, 593 deletions
diff --git a/c/event.c b/c/event.c
deleted file mode 100644
index 32d87348..00000000
--- a/c/event.c
+++ /dev/null
@@ -1,593 +0,0 @@
-#include "openbox.h"
-#include "client.h"
-#include "xerror.h"
-#include "prop.h"
-#include "screen.h"
-#include "frame.h"
-#include "focus.h"
-#include "hooks.h"
-#include "stacking.h"
-#include "kbind.h"
-#include "mbind.h"
-
-#include <X11/Xlib.h>
-#include <X11/keysym.h>
-#include <X11/Xatom.h>
-
-static void event_process(XEvent *e);
-static void event_handle_root(XEvent *e);
-static void event_handle_client(Client *c, XEvent *e);
-
-Time event_lasttime = 0;
-
-/*! A list of all possible combinations of keyboard lock masks */
-static unsigned int mask_list[8];
-/*! The value of the mask for the NumLock modifier */
-static unsigned int NumLockMask;
-/*! The value of the mask for the ScrollLock modifier */
-static unsigned int ScrollLockMask;
-/*! The key codes for the modifier keys */
-static XModifierKeymap *modmap;
-/*! Table of the constant modifier masks */
-static const int mask_table[] = {
- ShiftMask, LockMask, ControlMask, Mod1Mask,
- Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
-};
-static int mask_table_size;
-
-void event_startup()
-{
- mask_table_size = sizeof(mask_table) / sizeof(mask_table[0]);
-
- /* get lock masks that are defined by the display (not constant) */
- modmap = XGetModifierMapping(ob_display);
- g_assert(modmap);
- if (modmap && modmap->max_keypermod > 0) {
- size_t cnt;
- const size_t size = mask_table_size * modmap->max_keypermod;
- /* get the values of the keyboard lock modifiers
- Note: Caps lock is not retrieved the same way as Scroll and Num
- lock since it doesn't need to be. */
- const KeyCode num_lock = XKeysymToKeycode(ob_display, XK_Num_Lock);
- const KeyCode scroll_lock = XKeysymToKeycode(ob_display,
- XK_Scroll_Lock);
-
- for (cnt = 0; cnt < size; ++cnt) {
- if (! modmap->modifiermap[cnt]) continue;
-
- if (num_lock == modmap->modifiermap[cnt])
- NumLockMask = mask_table[cnt / modmap->max_keypermod];
- if (scroll_lock == modmap->modifiermap[cnt])
- ScrollLockMask = mask_table[cnt / modmap->max_keypermod];
- }
- }
-
- mask_list[0] = 0;
- mask_list[1] = LockMask;
- mask_list[2] = NumLockMask;
- mask_list[3] = LockMask | NumLockMask;
- mask_list[4] = ScrollLockMask;
- mask_list[5] = ScrollLockMask | LockMask;
- mask_list[6] = ScrollLockMask | NumLockMask;
- mask_list[7] = ScrollLockMask | LockMask | NumLockMask;
-}
-
-void event_shutdown()
-{
- XFreeModifiermap(modmap);
-}
-
-void event_loop()
-{
- fd_set selset;
- XEvent e;
- int x_fd;
-
- while (TRUE) {
- /*
- There are slightly different event retrieval semantics here for
- local (or high bandwidth) versus remote (or low bandwidth)
- connections to the display/Xserver.
- */
- if (ob_remote) {
- if (!XPending(ob_display))
- break;
- } else {
- /*
- This XSync allows for far more compression of events, which
- makes things like Motion events perform far far better. Since
- it also means network traffic for every event instead of every
- X events (where X is the number retrieved at a time), it
- probably should not be used for setups where Openbox is
- running on a remote/low bandwidth display/Xserver.
- */
- XSync(ob_display, FALSE);
- if (!XEventsQueued(ob_display, QueuedAlready))
- break;
- }
- XNextEvent(ob_display, &e);
-
- event_process(&e);
- }
-
- x_fd = ConnectionNumber(ob_display);
- FD_ZERO(&selset);
- FD_SET(x_fd, &selset);
- select(x_fd + 1, &selset, NULL, NULL, NULL);
-}
-
-void event_process(XEvent *e)
-{
- XEvent ce;
- KeyCode *kp;
- Window window;
- int i, k;
- Client *client;
- GQuark context;
- static guint motion_button = 0;
-
- /* pick a window */
- switch (e->type) {
- case UnmapNotify:
- window = e->xunmap.window;
- break;
- case DestroyNotify:
- window = e->xdestroywindow.window;
- break;
- case ConfigureRequest:
- window = e->xconfigurerequest.window;
- break;
- default:
- window = e->xany.window;
- }
-
- /* grab the lasttime and hack up the state */
- switch (e->type) {
- case ButtonPress:
- case ButtonRelease:
- event_lasttime = e->xbutton.time;
- e->xbutton.state &= ~(LockMask | NumLockMask | ScrollLockMask);
- /* kill off the Button1Mask etc, only want the modifiers */
- e->xbutton.state &= (ControlMask | ShiftMask | Mod1Mask |
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
- break;
- case KeyPress:
- event_lasttime = e->xkey.time;
- e->xkey.state &= ~(LockMask | NumLockMask | ScrollLockMask);
- /* kill off the Button1Mask etc, only want the modifiers */
- e->xkey.state &= (ControlMask | ShiftMask | Mod1Mask |
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
- /* add to the state the mask of the modifier being pressed, if it is
- a modifier key being pressed (this is a little ugly..) */
-/* I'm commenting this out cuz i don't want "C-Control_L" being returned. */
-/* kp = modmap->modifiermap;*/
-/* for (i = 0; i < mask_table_size; ++i) {*/
-/* for (k = 0; k < modmap->max_keypermod; ++k) {*/
-/* if (*kp == e->xkey.keycode) {*/ /* found the keycode */
- /* add the mask for it */
-/* e->xkey.state |= mask_table[i];*/
- /* cause the first loop to break; */
-/* i = mask_table_size;*/
-/* break;*/ /* get outta here! */
-/* }*/
-/* ++kp;*/
-/* }*/
-/* }*/
-
- break;
- case KeyRelease:
- event_lasttime = e->xkey.time;
- e->xkey.state &= ~(LockMask | NumLockMask | ScrollLockMask);
- /* kill off the Button1Mask etc, only want the modifiers */
- e->xkey.state &= (ControlMask | ShiftMask | Mod1Mask |
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
- /* remove from the state the mask of the modifier being released, if
- it is a modifier key being released (this is a little ugly..) */
- kp = modmap->modifiermap;
- for (i = 0; i < mask_table_size; ++i) {
- for (k = 0; k < modmap->max_keypermod; ++k) {
- if (*kp == e->xkey.keycode) { /* found the keycode */
- /* remove the mask for it */
- e->xkey.state &= ~mask_table[i];
- /* cause the first loop to break; */
- i = mask_table_size;
- break; /* get outta here! */
- }
- ++kp;
- }
- }
- break;
- case MotionNotify:
- event_lasttime = e->xmotion.time;
- e->xmotion.state &= ~(LockMask | NumLockMask | ScrollLockMask);
- /* kill off the Button1Mask etc, only want the modifiers */
- e->xmotion.state &= (ControlMask | ShiftMask | Mod1Mask |
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
- /* compress events */
- while (XCheckTypedWindowEvent(ob_display, window, e->type, &ce)) {
- e->xmotion.x_root = ce.xmotion.x_root;
- e->xmotion.y_root = ce.xmotion.y_root;
- }
- break;
- case PropertyNotify:
- event_lasttime = e->xproperty.time;
- break;
- case FocusIn:
- case FocusOut:
- if (e->xfocus.mode == NotifyGrab)
- /*|| e.xfocus.mode == NotifyUngrab ||*/
-
- /* From Metacity, from WindowMaker, ignore all funky pointer
- root events. Its commented out cuz I don't think we need this
- at all. If problems arise we can look into it */
- /*e.xfocus.detail > NotifyNonlinearVirtual) */
- return; /* skip me! */
- if (e->type == FocusOut) {
- /* FocusOut events just make us look for FocusIn events. They
- are mostly ignored otherwise. */
- XEvent fi;
- if (XCheckTypedEvent(ob_display, FocusIn, &fi)) {
- event_process(&fi);
- /* dont unfocus the window we just focused! */
- if (fi.xfocus.window == e->xfocus.window)
- return;
- }
- }
- break;
- case EnterNotify:
- case LeaveNotify:
- event_lasttime = e->xcrossing.time;
- if (e->xcrossing.mode != NotifyNormal)
- return; /* skip me! */
- break;
- }
-
- client = g_hash_table_lookup(client_map, (gpointer)window);
- if (client) {
- event_handle_client(client, e);
- } else if (window == ob_root)
- event_handle_root(e);
- else if (e->type == ConfigureRequest) {
- /* unhandled configure requests must be used to configure the
- window directly */
- XWindowChanges xwc;
-
- xwc.x = e->xconfigurerequest.x;
- xwc.y = e->xconfigurerequest.y;
- xwc.width = e->xconfigurerequest.width;
- xwc.height = e->xconfigurerequest.height;
- xwc.border_width = e->xconfigurerequest.border_width;
- xwc.sibling = e->xconfigurerequest.above;
- xwc.stack_mode = e->xconfigurerequest.detail;
-
- g_message("Proxying configure event for 0x%lx\n", window);
-
- /* we are not to be held responsible if someone sends us an
- invalid request! */
- xerror_set_ignore(TRUE);
- XConfigureWindow(ob_display, window,
- e->xconfigurerequest.value_mask, &xwc);
- xerror_set_ignore(FALSE);
- }
-
- /* dispatch Crossing, Pointer and Key events to the hooks */
- switch(e->type) {
- case EnterNotify:
- context = frame_get_context(client, window);
- LOGICALHOOK(EnterWindow, context, client);
- break;
- case LeaveNotify:
- context = frame_get_context(client, window);
- LOGICALHOOK(LeaveWindow, context, client);
- break;
- case ButtonPress:
- if (!motion_button) motion_button = e->xbutton.button;
- context = frame_get_context(client, window);
- mbind_fire(e->xbutton.state, e->xbutton.button, context,
- Pointer_Press, client, e->xbutton.x_root,
- e->xbutton.y_root);
- break;
- case ButtonRelease:
- if (motion_button == e->xbutton.button) motion_button = 0;
- context = frame_get_context(client, window);
- mbind_fire(e->xbutton.state, e->xbutton.button, context,
- Pointer_Release, client, e->xbutton.x_root,
- e->xbutton.y_root);
- break;
- case MotionNotify:
- context = frame_get_context(client, window);
- mbind_fire(e->xkey.state, motion_button, context, Pointer_Motion,
- client, e->xmotion.x_root, e->xmotion.y_root);
- break;
- case KeyPress:
- kbind_fire(e->xkey.state, e->xkey.keycode, TRUE);
- break;
- case KeyRelease:
- kbind_fire(e->xkey.state, e->xkey.keycode, FALSE);
- break;
- }
-}
-
-static void event_handle_root(XEvent *e)
-{
- Atom msgtype;
-
- switch(e->type) {
- case MapRequest:
- g_message("MapRequest on root");
- client_manage(e->xmap.window);
- break;
- case ClientMessage:
- if (e->xclient.format != 32) break;
-
- msgtype = e->xclient.message_type;
- if (msgtype == prop_atoms.net_current_desktop) {
- unsigned int d = e->xclient.data.l[0];
- if (d <= screen_num_desktops)
- screen_set_desktop(d);
- } else if (msgtype == prop_atoms.net_number_of_desktops) {
- unsigned int d = e->xclient.data.l[0];
- if (d > 0)
- screen_set_num_desktops(d);
- } else if (msgtype == prop_atoms.net_showing_desktop) {
- screen_show_desktop(e->xclient.data.l[0] != 0);
- }
- break;
- case PropertyNotify:
- if (e->xproperty.atom == prop_atoms.net_desktop_names)
- screen_update_desktop_names();
- else if (e->xproperty.atom == prop_atoms.net_desktop_layout)
- screen_update_layout();
- break;
- }
-}
-
-static void event_handle_client(Client *client, XEvent *e)
-{
- XEvent ce;
- Atom msgtype;
-
- switch (e->type) {
- case FocusIn:
- client->focused = TRUE;
- frame_adjust_focus(client->frame);
-
- /* focus state can affect the stacking layer */
- client_calc_layer(client);
-
- focus_set_client(client);
- break;
- case FocusOut:
- client->focused = FALSE;
- frame_adjust_focus(client->frame);
-
- /* focus state can affect the stacking layer */
- client_calc_layer(client);
-
- if (focus_client == client)
- focus_set_client(NULL);
- break;
- case ConfigureRequest:
- g_message("ConfigureRequest for window %lx", client->window);
- /* compress these */
- while (XCheckTypedWindowEvent(ob_display, client->window,
- ConfigureRequest, &ce)) {
- /* XXX if this causes bad things.. we can compress config req's
- with the same mask. */
- e->xconfigurerequest.value_mask |=
- ce.xconfigurerequest.value_mask;
- if (ce.xconfigurerequest.value_mask & CWX)
- e->xconfigurerequest.x = ce.xconfigurerequest.x;
- if (ce.xconfigurerequest.value_mask & CWY)
- e->xconfigurerequest.y = ce.xconfigurerequest.y;
- if (ce.xconfigurerequest.value_mask & CWWidth)
- e->xconfigurerequest.width = ce.xconfigurerequest.width;
- if (ce.xconfigurerequest.value_mask & CWHeight)
- e->xconfigurerequest.height = ce.xconfigurerequest.height;
- if (ce.xconfigurerequest.value_mask & CWBorderWidth)
- e->xconfigurerequest.border_width =
- ce.xconfigurerequest.border_width;
- if (ce.xconfigurerequest.value_mask & CWStackMode)
- e->xconfigurerequest.detail = ce.xconfigurerequest.detail;
- }
-
- /* if we are iconic (or shaded (fvwm does this)) ignore the event */
- if (client->iconic || client->shaded) return;
-
- if (e->xconfigurerequest.value_mask & CWBorderWidth)
- client->border_width = e->xconfigurerequest.border_width;
-
- /* resize, then move, as specified in the EWMH section 7.7 */
- if (e->xconfigurerequest.value_mask & (CWWidth | CWHeight |
- CWX | CWY)) {
- int x, y, w, h;
- Corner corner;
-
- x = (e->xconfigurerequest.value_mask & CWX) ?
- e->xconfigurerequest.x : client->area.x;
- y = (e->xconfigurerequest.value_mask & CWY) ?
- e->xconfigurerequest.y : client->area.y;
- w = (e->xconfigurerequest.value_mask & CWWidth) ?
- e->xconfigurerequest.width : client->area.width;
- h = (e->xconfigurerequest.value_mask & CWHeight) ?
- e->xconfigurerequest.height : client->area.height;
-
- switch (client->gravity) {
- case NorthEastGravity:
- case EastGravity:
- corner = Corner_TopRight;
- break;
- case SouthWestGravity:
- case SouthGravity:
- corner = Corner_BottomLeft;
- break;
- case SouthEastGravity:
- corner = Corner_BottomRight;
- break;
- default: /* NorthWest, Static, etc */
- corner = Corner_TopLeft;
- }
-
- client_configure(client, corner, x, y, w, h, FALSE, FALSE);
- }
-
- if (e->xconfigurerequest.value_mask & CWStackMode) {
- switch (e->xconfigurerequest.detail) {
- case Below:
- case BottomIf:
- stacking_lower(client);
- break;
-
- case Above:
- case TopIf:
- default:
- stacking_raise(client);
- break;
- }
- }
- break;
- case UnmapNotify:
- if (client->ignore_unmaps) {
- client->ignore_unmaps--;
- break;
- }
- g_message("UnmapNotify for %lx", client->window);
- client_unmanage(client);
- break;
- case DestroyNotify:
- g_message("DestroyNotify for %lx", client->window);
- client_unmanage(client);
- break;
- case ReparentNotify:
- /* this is when the client is first taken captive in the frame */
- if (e->xreparent.parent == client->frame->plate) break;
-
- /*
- This event is quite rare and is usually handled in unmapHandler.
- However, if the window is unmapped when the reparent event occurs,
- the window manager never sees it because an unmap event is not sent
- to an already unmapped window.
- */
-
- /* we don't want the reparent event, put it back on the stack for the
- X server to deal with after we unmanage the window */
- XPutBackEvent(ob_display, e);
-
- client_unmanage(client);
- break;
- case MapRequest:
- /* we shouldn't be able to get this unless we're iconic */
- g_assert(client->iconic);
-
- LOGICALHOOK(RequestActivate, g_quark_try_string("client"), client);
- break;
- case ClientMessage:
- /* validate cuz we query stuff off the client here */
- if (!client_validate(client)) break;
-
- if (e->xclient.format != 32) return;
-
- msgtype = e->xclient.message_type;
- if (msgtype == prop_atoms.wm_change_state) {
- /* compress changes into a single change */
- while (XCheckTypedWindowEvent(ob_display, e->type,
- client->window, &ce)) {
- /* XXX: it would be nice to compress ALL messages of a
- type, not just messages in a row without other
- message types between. */
- if (ce.xclient.message_type != msgtype) {
- XPutBackEvent(ob_display, &ce);
- break;
- }
- e->xclient = ce.xclient;
- }
- client_set_wm_state(client, e->xclient.data.l[0]);
- } else if (msgtype == prop_atoms.net_wm_desktop) {
- /* compress changes into a single change */
- while (XCheckTypedWindowEvent(ob_display, e->type,
- client->window, &ce)) {
- /* XXX: it would be nice to compress ALL messages of a
- type, not just messages in a row without other
- message types between. */
- if (ce.xclient.message_type != msgtype) {
- XPutBackEvent(ob_display, &ce);
- break;
- }
- e->xclient = ce.xclient;
- }
- client_set_desktop(client, e->xclient.data.l[0]);
- } else if (msgtype == prop_atoms.net_wm_state) {
- /* can't compress these */
- g_message("net_wm_state %s %ld %ld for 0x%lx\n",
- (e->xclient.data.l[0] == 0 ? "Remove" :
- e->xclient.data.l[0] == 1 ? "Add" :
- e->xclient.data.l[0] == 2 ? "Toggle" : "INVALID"),
- e->xclient.data.l[1], e->xclient.data.l[2],
- client->window);
- client_set_state(client, e->xclient.data.l[0],
- e->xclient.data.l[1], e->xclient.data.l[2]);
- } else if (msgtype == prop_atoms.net_close_window) {
- g_message("net_close_window for 0x%lx\n", client->window);
- client_close(client);
- } else if (msgtype == prop_atoms.net_active_window) {
- g_message("net_active_window for 0x%lx\n", client->window);
- if (screen_showing_desktop)
- screen_show_desktop(FALSE);
- if (client->iconic)
- client_iconify(client, FALSE, TRUE);
- else if (!client->frame->visible)
- /* if its not visible for other reasons, then don't mess
- with it */
- return;
- LOGICALHOOK(RequestActivate, g_quark_try_string("client"), client);
- }
- break;
- case PropertyNotify:
- /* validate cuz we query stuff off the client here */
- if (!client_validate(client)) break;
-
- /* compress changes to a single property into a single change */
- while (XCheckTypedWindowEvent(ob_display, e->type,
- client->window, &ce)) {
- /* XXX: it would be nice to compress ALL changes to a property,
- not just changes in a row without other props between. */
- if (ce.xproperty.atom != e->xproperty.atom) {
- XPutBackEvent(ob_display, &ce);
- break;
- }
- }
-
- msgtype = e->xproperty.atom;
- if (msgtype == XA_WM_NORMAL_HINTS) {
- client_update_normal_hints(client);
- /* normal hints can make a window non-resizable */
- client_setup_decor_and_functions(client);
- } else if (msgtype == XA_WM_HINTS)
- client_update_wmhints(client);
- else if (msgtype == XA_WM_TRANSIENT_FOR) {
- client_update_transient_for(client);
- client_get_type(client);
- /* type may have changed, so update the layer */
- client_calc_layer(client);
- client_setup_decor_and_functions(client);
- }
- else if (msgtype == prop_atoms.net_wm_name ||
- msgtype == prop_atoms.wm_name)
- client_update_title(client);
- else if (msgtype == prop_atoms.net_wm_icon_name ||
- msgtype == prop_atoms.wm_icon_name)
- client_update_icon_title(client);
- else if (msgtype == prop_atoms.wm_class)
- client_update_class(client);
- else if (msgtype == prop_atoms.wm_protocols) {
- client_update_protocols(client);
- client_setup_decor_and_functions(client);
- }
- else if (msgtype == prop_atoms.net_wm_strut)
- client_update_strut(client);
- else if (msgtype == prop_atoms.net_wm_icon)
- client_update_icons(client);
- else if (msgtype == prop_atoms.kwm_win_icon)
- client_update_kwm_icon(client);
- }
-}