summaryrefslogtreecommitdiff
path: root/src/events.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/events.c')
-rw-r--r--src/events.c1012
1 files changed, 0 insertions, 1012 deletions
diff --git a/src/events.c b/src/events.c
deleted file mode 100644
index 37bfc01..0000000
--- a/src/events.c
+++ /dev/null
@@ -1,1012 +0,0 @@
-/* Ratpoison X events
- * Copyright (C) 2000, 2001, 2002, 2003, 2004 Shawn Betts <sabetts@vcn.bc.ca>
- *
- * This file is part of ratpoison.
- *
- * ratpoison is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * ratpoison is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307 USA
- */
-
-#include <X11/X.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-#include <X11/Xmd.h> /* for CARD32. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-
-#include "ratpoison.h"
-
-/* The event currently being processed. Mostly used in functions from
- action.c which need to forward events to other windows. */
-XEvent rp_current_event;
-
-/* RAISED is non zero if a raised message should be used 0 for a map message. */
-void
-show_rudeness_msg (rp_window *win, int raised)
-{
- rp_group *g = groups_find_group_by_window (win);
- rp_window_elem *elem = group_find_window (&g->mapped_windows, win);
- if (g == rp_current_group)
- {
- if (win->transient)
- marked_message_printf (0, 0, raised ? MESSAGE_RAISE_TRANSIENT:MESSAGE_MAP_TRANSIENT,
- elem->number, window_name (win));
- else
- marked_message_printf (0, 0, raised ? MESSAGE_RAISE_WINDOW:MESSAGE_MAP_WINDOW,
- elem->number, window_name (win));
- }
- else
- {
- if (win->transient)
- marked_message_printf (0, 0, raised ? MESSAGE_RAISE_TRANSIENT_GROUP:MESSAGE_MAP_TRANSIENT_GROUP,
- elem->number, window_name (win), g->name);
- else
- marked_message_printf (0, 0, raised ? MESSAGE_RAISE_WINDOW_GROUP:MESSAGE_MAP_WINDOW_GROUP,
- elem->number, window_name (win), g->name);
- }
-}
-
-static void
-new_window (XCreateWindowEvent *e)
-{
- rp_window *win;
- rp_screen *s;
-
- if (e->override_redirect)
- return;
-
- win = find_window (e->window);
-
- /* In Xinerama mode, all windows have the same root, so check
- * all Xinerama screens
- */
- if (rp_have_xinerama)
- {
- /* New windows belong to the current screen */
- s = &screens[rp_current_screen];
- }
- else
- {
- s = find_screen (e->parent);
- }
- if (is_rp_window_for_screen(e->window, s)) return;
-
- if (s && win == NULL
- && e->window != s->key_window
- && e->window != s->bar_window
- && e->window != s->input_window
- && e->window != s->frame_window
- && e->window != s->help_window)
- {
- win = add_to_window_list (s, e->window);
- update_window_information (win);
- }
-}
-
-static void
-unmap_notify (XEvent *ev)
-{
- rp_frame *frame;
- rp_window *win;
-
- /* ignore SubstructureNotify unmaps. */
- if(ev->xunmap.event != ev->xunmap.window
- && ev->xunmap.send_event != True)
- return;
-
- /* FIXME: Should we only look in the mapped window list? */
- win = find_window_in_list (ev->xunmap.window, &rp_mapped_window);
-
- if (win == NULL)
- return;
-
- switch (win->state)
- {
- case IconicState:
- PRINT_DEBUG (("Withdrawing iconized window '%s'\n", window_name (win)));
- if (ev->xunmap.send_event) withdraw_window (win);
- break;
- case NormalState:
- PRINT_DEBUG (("Withdrawing normal window '%s'\n", window_name (win)));
- /* If the window was inside a frame, fill the frame with another
- window. */
- frame = find_windows_frame (win);
- if (frame)
- {
- cleanup_frame (frame);
- if (frame->number == win->scr->current_frame
- && current_screen() == win->scr)
- set_active_frame (frame, 0);
- /* Since we may have switched windows, call the hook. */
- if (frame->win_number != EMPTY)
- hook_run (&rp_switch_win_hook);
- }
-
- withdraw_window (win);
- break;
- }
-
- update_window_names (win->scr, defaults.window_fmt);
-}
-
-static void
-map_request (XEvent *ev)
-{
- rp_window *win;
-
- win = find_window (ev->xmap.window);
- if (win == NULL)
- {
- PRINT_DEBUG (("Map request from an unknown window.\n"));
- XMapWindow (dpy, ev->xmap.window);
- return;
- }
-
- PRINT_DEBUG (("Map request from a managed window\n"));
-
- switch (win->state)
- {
- case WithdrawnState:
- if (unmanaged_window (win->w))
- {
- PRINT_DEBUG (("Mapping Unmanaged Window\n"));
- XMapWindow (dpy, win->w);
- break;
- }
- else
- {
- PRINT_DEBUG (("Mapping Withdrawn Window\n"));
- map_window (win);
- break;
- }
- break;
- case IconicState:
- PRINT_DEBUG (("Mapping Iconic window\n"));
- if (win->last_access == 0)
- {
- /* Depending on the rudeness level, actually map the
- window. */
- if ((rp_honour_transient_map && win->transient)
- || (rp_honour_normal_map && !win->transient))
- set_active_window (win);
- }
- else
- {
- /* Depending on the rudeness level, actually map the
- window. */
- if ((rp_honour_transient_raise && win->transient)
- || (rp_honour_normal_raise && !win->transient))
- set_active_window (win);
- else
- show_rudeness_msg (win, 1);
- }
- break;
- }
-}
-
-static void
-destroy_window (XDestroyWindowEvent *ev)
-{
- rp_window *win;
-
- win = find_window (ev->window);
- if (win == NULL) return;
-
- ignore_badwindow++;
-
- /* If, somehow, the window is not withdrawn before it is destroyed,
- perform the necessary steps to withdraw the window before it is
- unmanaged. */
- if (win->state == IconicState)
- {
- PRINT_DEBUG (("Destroying Iconic Window (%s)\n", window_name (win)));
- withdraw_window (win);
- }
- else if (win->state == NormalState)
- {
- rp_frame *frame;
-
- PRINT_DEBUG (("Destroying Normal Window (%s)\n", window_name (win)));
- frame = find_windows_frame (win);
- if (frame)
- {
- cleanup_frame (frame);
- if (frame->number == win->scr->current_frame
- && current_screen() == win->scr)
- set_active_frame (frame, 0);
- /* Since we may have switched windows, call the hook. */
- if (frame->win_number != EMPTY)
- hook_run (&rp_switch_win_hook);
- }
- withdraw_window (win);
- }
-
- /* Now that the window is guaranteed to be in the unmapped window
- list, we can safely stop managing it. */
- unmanage (win);
- ignore_badwindow--;
-}
-
-static void
-configure_request (XConfigureRequestEvent *e)
-{
- XWindowChanges changes;
- rp_window *win;
-
- win = find_window (e->window);
-
- if (win)
- {
- if (e->value_mask & CWStackMode)
- {
- if (e->detail == Above && win->state != WithdrawnState)
- {
- /* Depending on the rudeness level, actually map the
- window. */
- if ((rp_honour_transient_raise && win->transient)
- || (rp_honour_normal_raise && !win->transient))
- {
- if (win->state == IconicState)
- set_active_window (win);
- else if (find_windows_frame (win))
- goto_window (win);
- }
- else if (current_window() != win)
- {
- show_rudeness_msg (win, 1);
- }
-
- }
-
- PRINT_DEBUG(("request CWStackMode %d\n", e->detail));
- }
-
- PRINT_DEBUG (("'%s' window size: %d %d %d %d %d\n", window_name (win),
- win->x, win->y, win->width, win->height, win->border));
-
- /* Collect the changes to be granted. */
- if (e->value_mask & CWBorderWidth)
- {
- changes.border_width = e->border_width;
- win->border = e->border_width;
- PRINT_DEBUG(("request CWBorderWidth %d\n", e->border_width));
- }
-
- if (e->value_mask & CWWidth)
- {
- changes.width = e->width;
- win->width = e->width;
- PRINT_DEBUG(("request CWWidth %d\n", e->width));
- }
-
- if (e->value_mask & CWHeight)
- {
- changes.height = e->height;
- win->height = e->height;
- PRINT_DEBUG(("request CWHeight %d\n", e->height));
- }
-
- if (e->value_mask & CWX)
- {
- changes.x = e->x;
- win->x = e->x;
- PRINT_DEBUG(("request CWX %d\n", e->x));
- }
-
- if (e->value_mask & CWY)
- {
- changes.y = e->y;
- win->y = e->y;
- PRINT_DEBUG(("request CWY %d\n", e->y));
- }
-
- if (e->value_mask & (CWX|CWY|CWBorderWidth|CWWidth|CWHeight))
- {
- /* Grant the request, then immediately maximize it. */
- XConfigureWindow (dpy, win->w,
- e->value_mask & (CWX|CWY|CWBorderWidth|CWWidth|CWHeight),
- &changes);
- XSync(dpy, False);
- if (win->state == NormalState)
- maximize (win);
- }
- }
- else
- {
- /* Its an unmanaged window, so give it what it wants. But don't
- change the stack mode.*/
- if (e->value_mask & CWX) changes.x = e->x;
- if (e->value_mask & CWY) changes.x = e->x;
- if (e->value_mask & CWWidth) changes.x = e->x;
- if (e->value_mask & CWHeight) changes.x = e->x;
- if (e->value_mask & CWBorderWidth) changes.x = e->x;
- XConfigureWindow (dpy, e->window,
- e->value_mask & (CWX|CWY|CWBorderWidth|CWWidth|CWHeight),
- &changes);
- }
-}
-
-static void
-client_msg (XClientMessageEvent *ev)
-{
- PRINT_DEBUG (("Received client message.\n"));
-
- if (ev->message_type == wm_change_state)
- {
- rp_window *win;
-
- PRINT_DEBUG (("WM_CHANGE_STATE\n"));
-
- win = find_window (ev->window);
- if (win == NULL) return;
- if (ev->format == 32 && ev->data.l[0] == IconicState)
- {
- /* FIXME: This means clients can hide themselves without the
- user's intervention. This is bad, but Emacs is the only
- program I know of that iconifies itself and this is
- generally from the user pressing C-z. */
- PRINT_DEBUG (("Iconify Request.\n"));
- if (win->state == NormalState)
- {
- rp_window *w = find_window_other(win->scr);
-
- if (w)
- set_active_window (w);
- else
- blank_frame (screen_get_frame (win->scr, win->scr->current_frame));
- }
- }
- else
- {
- PRINT_ERROR (("Non-standard WM_CHANGE_STATE format\n"));
- }
- }
-}
-
-static void
-handle_key (KeySym ks, unsigned int mod, rp_screen *s)
-{
- rp_action *key_action;
- rp_keymap *map = find_keymap (defaults.top_kmap);
-
- if (map == NULL)
- {
- PRINT_ERROR (("Unable to find %s keymap\n", defaults.top_kmap));
- return;
- }
-
- PRINT_DEBUG (("handling key...\n"));
-
- /* All functions hide the program bar and the frame indicator. */
- if (defaults.bar_timeout > 0) hide_bar (s);
- hide_frame_indicator();
-
- /* Disable any alarm that was going to go off. */
- alarm (0);
- alarm_signalled = 0;
-
- /* Call the top level key pressed hook. */
- hook_run (&rp_key_hook);
-
- PRINT_DEBUG (("handle_key\n"));
-
- /* Read a key and execute the command associated with it on the
- default keymap. Ignore the key if it doesn't have a binding. */
- if ((key_action = find_keybinding (ks, x11_mask_to_rp_mask (mod), map)))
- {
- cmdret *result;
-
- PRINT_DEBUG(("%s\n", key_action->data));
-
- result = command (1, key_action->data);
-
- if (result)
- {
- if (result->output)
- message (result->output);
- cmdret_free (result);
- }
- }
- else
- {
- PRINT_DEBUG(("Impossible: No matching key"));
- }
-}
-
-static void
-key_press (XEvent *ev)
-{
- rp_screen *s;
- unsigned int modifier;
- KeySym ks;
-
- if (rp_have_xinerama)
- s = current_screen();
- else
- s = find_screen (ev->xkey.root);
-
- if (!s) return;
-
-#ifdef HIDE_MOUSE
- XWarpPointer (dpy, None, s->root, 0, 0, 0, 0, s->left + s->width - 2, s->top + s->height - 2);
-#endif
-
- modifier = ev->xkey.state;
- cook_keycode ( &ev->xkey, &ks, &modifier, NULL, 0, 1);
-
- handle_key (ks, modifier, s);
-}
-
-/* Read a command off the window and execute it. Some commands return
- text. This text is passed back using the RP_COMMAND_RESULT
- Atom. The client will wait for this property change so something
- must be returned. */
-static cmdret *
-execute_remote_command (Window w)
-{
- int status;
- cmdret *ret;
- Atom type_ret;
- int format_ret;
- unsigned long nitems;
- unsigned long bytes_after;
- unsigned char *req;
-
- status = XGetWindowProperty (dpy, w, rp_command,
- 0, 0, False, xa_string,
- &type_ret, &format_ret, &nitems, &bytes_after,
- &req);
-
- if (status != Success || req == NULL)
- {
- return cmdret_new (RET_FAILURE, "Couldn't get RP_COMMAND Property");
- }
-
- /* XGetWindowProperty always allocates one extra byte even if
- the property is zero length. */
- XFree (req);
-
- status = XGetWindowProperty (dpy, w, rp_command,
- 0, (bytes_after / 4) + (bytes_after % 4 ? 1 : 0),
- True, xa_string, &type_ret, &format_ret, &nitems,
- &bytes_after, &req);
-
- if (status != Success || req == NULL)
- {
- return cmdret_new (RET_FAILURE, "Couldn't get RP_COMMAND Property");
- }
-
- PRINT_DEBUG (("command: %s\n", req));
- ret = command (req[0], (char *)&req[1]);
- XFree (req);
-
- return ret;
-}
-
-/* Command requests are posted as a property change using the
- RP_COMMAND_REQUEST Atom on the root window. A Command request is a
- Window that holds the actual command as a property using the
- RP_COMMAND Atom. receive_command reads the list of Windows and
- executes their associated command. */
-static void
-receive_command (Window root)
-{
- cmdret *cmd_ret;
- char *result;
- Atom type_ret;
- int format_ret;
- unsigned long nitems;
- unsigned long bytes_after;
- unsigned char *prop_return;
- int offset;
-
- /* Init offset to 0. In the case where there is more than one window
- in the property, a partial read does not delete the property and
- we need to grab the next window by incementing offset to the
- offset of the next window. */
- offset = 0;
- do
- {
- int ret;
- int length;
- Window w;
-
- length = sizeof (Window) / 4 + (sizeof (Window) % 4 ?1:0);
- ret = XGetWindowProperty (dpy, root,
- rp_command_request,
- offset, length,
- True, XA_WINDOW, &type_ret, &format_ret,
- &nitems,
- &bytes_after, &prop_return);
-
- /* Update the offset to point to the next window (if there is
- another one). */
- offset += length;
-
- if (ret != Success)
- {
- PRINT_ERROR (("XGetWindowProperty Failed\n"));
- if (prop_return)
- XFree (prop_return);
- break;
- }
-
- /* If there was no window, then we're done. */
- if (prop_return == NULL)
- {
- PRINT_DEBUG (("No property to read\n"));
- break;
- }
-
- /* We grabbed a window, so now read the command stored in
- this window and execute it. */
- w = *(Window *)prop_return;
- XFree (prop_return);
- cmd_ret = execute_remote_command (w);
-
- /* notify the client of any text that was returned by the
- command. see communications.c:receive_command_result() */
- if (cmd_ret->output)
- result = xsprintf ("%c%s", cmd_ret->success ? '1':'0', cmd_ret->output);
- else if (!cmd_ret->success)
- result = xstrdup("0");
- else
- result = NULL;
-
- if (result)
- XChangeProperty (dpy, w, rp_command_result, xa_string,
- 8, PropModeReplace, (unsigned char *)result, strlen (result));
- else
- XChangeProperty (dpy, w, rp_command_result, xa_string,
- 8, PropModeReplace, NULL, 0);
- free (result);
- cmdret_free (cmd_ret);
- } while (bytes_after > 0);
-}
-
-static void
-property_notify (XEvent *ev)
-{
- rp_window *win;
-
- PRINT_DEBUG (("atom: %ld\n", ev->xproperty.atom));
-
- if (ev->xproperty.atom == rp_command_request
- && is_a_root_window (ev->xproperty.window)
- && ev->xproperty.state == PropertyNewValue)
- {
- PRINT_DEBUG (("ratpoison command\n"));
- receive_command(ev->xproperty.window);
- }
-
- win = find_window (ev->xproperty.window);
-
- if (win)
- {
- if (ev->xproperty.atom == _net_wm_pid)
- {
- struct rp_child_info *child_info;
-
- PRINT_DEBUG (("updating _NET_WM_PID\n"));
- child_info = get_child_info(win->w);
- if (child_info && !child_info->window_mapped)
- {
- if (child_info->frame)
- {
- PRINT_DEBUG (("frame=%p\n", child_info->frame));
- win->intended_frame_number = child_info->frame->number;
- /* Only map the first window in the launch frame. */
- child_info->window_mapped = 1;
- }
- /* TODO: also adopt group information? */
- }
- } else
- switch (ev->xproperty.atom)
- {
- case XA_WM_NAME:
- PRINT_DEBUG (("updating window name\n"));
- if (update_window_name (win)) {
- update_window_names (win->scr, defaults.window_fmt);
- hook_run (&rp_title_changed_hook);
- }
- break;
-
- case XA_WM_NORMAL_HINTS:
- PRINT_DEBUG (("updating window normal hints\n"));
- update_normal_hints (win);
- if (win->state == NormalState)
- maximize (win);
- break;
-
- case XA_WM_TRANSIENT_FOR:
- PRINT_DEBUG (("Transient for\n"));
- win->transient = XGetTransientForHint (dpy, win->w, &win->transient_for);
- break;
-
- default:
- PRINT_DEBUG (("Unhandled property notify event: %ld\n", ev->xproperty.atom));
- break;
- }
- }
-}
-
-static void
-colormap_notify (XEvent *ev)
-{
- rp_window *win;
-
- win = find_window (ev->xcolormap.window);
-
- if (win != NULL)
- {
- XWindowAttributes attr;
-
- /* SDL sets the colormap just before destroying the window, so
- ignore BadWindow errors. */
- ignore_badwindow++;
-
- XGetWindowAttributes (dpy, win->w, &attr);
- win->colormap = attr.colormap;
-
- if (win == current_window()
- && !current_screen()->bar_is_raised)
- {
- XInstallColormap (dpy, win->colormap);
- }
-
- ignore_badwindow--;
- }
-}
-
-static void
-focus_change (XFocusChangeEvent *ev)
-{
- rp_window *win;
-
- /* We're only interested in the NotifyGrab mode */
- if (ev->mode != NotifyGrab) return;
-
- win = find_window (ev->window);
-
- if (win != NULL)
- {
- PRINT_DEBUG (("Re-grabbing prefix key\n"));
- grab_top_level_keys (win->w);
- }
-}
-
-static void
-mapping_notify (XMappingEvent *ev)
-{
- ungrab_keys_all_wins();
-
- switch (ev->request)
- {
- case MappingModifier:
- update_modifier_map();
- /* This is meant to fall through. */
- case MappingKeyboard:
- XRefreshKeyboardMapping (ev);
- break;
- }
-
- grab_keys_all_wins();
-}
-
-static void
-configure_notify (XConfigureEvent *ev)
-{
- rp_screen *s;
-
- s = find_screen(ev->window);
- if (s != NULL)
- /* This is a root window of a screen,
- * look if its width or height changed: */
- screen_update(s,ev->width,ev->height);
-}
-
-/* This is called whan an application has requested the
- selection. Copied from rxvt. */
-static void
-selection_request (XSelectionRequestEvent *rq)
-{
- XEvent ev;
- CARD32 target_list[4];
- Atom target;
- static Atom xa_targets = None;
- static Atom xa_text = None; /* XXX */
- XTextProperty ct;
- XICCEncodingStyle style;
- char *cl[4];
-
- if (xa_text == None)
- xa_text = XInternAtom(dpy, "TEXT", False);
- if (xa_targets == None)
- xa_targets = XInternAtom(dpy, "TARGETS", False);
-
- ev.xselection.type = SelectionNotify;
- ev.xselection.property = None;
- ev.xselection.display = rq->display;
- ev.xselection.requestor = rq->requestor;
- ev.xselection.selection = rq->selection;
- ev.xselection.target = rq->target;
- ev.xselection.time = rq->time;
-
- if (rq->target == xa_targets) {
- target_list[0] = (CARD32) xa_targets;
- target_list[1] = (CARD32) xa_string;
- target_list[2] = (CARD32) xa_text;
- target_list[3] = (CARD32) xa_compound_text;
- XChangeProperty(dpy, rq->requestor, rq->property, rq->target,
- (8 * sizeof(target_list[0])), PropModeReplace,
- (unsigned char *)target_list,
- (sizeof(target_list) / sizeof(target_list[0])));
- ev.xselection.property = rq->property;
- } else if (rq->target == xa_string
- || rq->target == xa_compound_text
- || rq->target == xa_text) {
- if (rq->target == xa_string) {
- style = XStringStyle;
- target = xa_string;
- } else {
- target = xa_compound_text;
- style = (rq->target == xa_compound_text) ? XCompoundTextStyle
- : XStdICCTextStyle;
- }
- cl[0] = selection.text;
- XmbTextListToTextProperty(dpy, cl, 1, style, &ct);
- XChangeProperty(dpy, rq->requestor, rq->property,
- target, 8, PropModeReplace,
- ct.value, ct.nitems);
- ev.xselection.property = rq->property;
- }
- XSendEvent(dpy, rq->requestor, False, 0, &ev);
-}
-
-static void
-selection_clear (void)
-{
- if (selection.text)
- free (selection.text);
- selection.text = NULL;
- selection.len = 0;
-}
-
-/* Given an event, call the correct function to handle it. */
-static void
-delegate_event (XEvent *ev)
-{
- switch (ev->type)
- {
- case ConfigureRequest:
- PRINT_DEBUG (("--- Handling ConfigureRequest ---\n"));
- configure_request (&ev->xconfigurerequest);
- break;
-
- case CreateNotify:
- PRINT_DEBUG (("--- Handling CreateNotify ---\n"));
- new_window (&ev->xcreatewindow);
- break;
-
- case DestroyNotify:
- PRINT_DEBUG (("--- Handling DestroyNotify ---\n"));
- destroy_window (&ev->xdestroywindow);
- break;
-
- case ClientMessage:
- PRINT_DEBUG (("--- Handling ClientMessage ---\n"));
- client_msg (&ev->xclient);
- break;
-
- case ColormapNotify:
- PRINT_DEBUG (("--- Handling ColormapNotify ---\n"));
- colormap_notify (ev);
- break;
-
- case PropertyNotify:
- PRINT_DEBUG (("--- Handling PropertyNotify ---\n"));
- property_notify (ev);
- break;
-
- case MapRequest:
- PRINT_DEBUG (("--- Handling MapRequest ---\n"));
- map_request (ev);
- break;
-
- case KeyPress:
- PRINT_DEBUG (("--- Handling KeyPress ---\n"));
- key_press (ev);
- break;
-
- case UnmapNotify:
- PRINT_DEBUG (("--- Handling UnmapNotify ---\n"));
- unmap_notify (ev);
- break;
-
- case FocusOut:
- PRINT_DEBUG (("--- Handling FocusOut ---\n"));
- focus_change (&ev->xfocus);
- break;
-
- case FocusIn:
- PRINT_DEBUG (("--- Handling FocusIn ---\n"));
- focus_change (&ev->xfocus);
- break;
-
- case MappingNotify:
- PRINT_DEBUG (("--- Handling MappingNotify ---\n"));
- mapping_notify( &ev->xmapping );
- break;
-
- case SelectionRequest:
- selection_request(&ev->xselectionrequest);
- break;
-
- case SelectionClear:
- selection_clear();
- break;
-
- case ConfigureNotify:
- PRINT_DEBUG (("--- Handling ConfigureNotify ---\n"));
- configure_notify( &ev->xconfigure );
- break;
-
- case MapNotify:
- case Expose:
- case MotionNotify:
- case KeyRelease:
- case ReparentNotify:
- case EnterNotify:
- case SelectionNotify:
- case CirculateRequest:
- /* Ignore these events. */
- break;
-
- default:
- PRINT_DEBUG (("--- Unknown event %d ---\n",- ev->type));
- }
-}
-
-static void
-handle_signals (void)
-{
- /* An alarm means we need to hide the popup windows. */
- if (alarm_signalled > 0)
- {
- int i;
-
- PRINT_DEBUG (("Alarm received.\n"));
-
- /* Only hide the bar if it times out. */
- if (defaults.bar_timeout > 0)
- for (i=0; i<num_screens; i++)
- hide_bar (&screens[i]);
-
- hide_frame_indicator();
- alarm_signalled = 0;
- }
-
- if (chld_signalled > 0)
- {
- rp_child_info *cur;
- struct list_head *iter, *tmp;
-
- /* Report and remove terminated processes. */
- list_for_each_safe_entry (cur, iter, tmp, &rp_children, node)
- {
- if (cur->terminated)
- {
- /* Report any child that didn't return 0. */
- if (cur->status != 0)
- marked_message_printf (0,0, "/bin/sh -c \"%s\" finished (%d)",
- cur->cmd, cur->status);
- list_del (&cur->node);
- free (cur->cmd);
- free (cur);
- }
- }
-
- chld_signalled = 0;
- }
-
- if (rp_exec_newwm)
- {
- int i;
-
- PRINT_DEBUG (("Switching to %s\n", rp_exec_newwm));
-
- putenv(current_screen()->display_string);
- unhide_all_windows();
- XSync(dpy, False);
- for (i=0; i<num_screens; i++)
- {
- deactivate_screen(&screens[i]);
- }
- execlp(rp_exec_newwm, rp_exec_newwm, NULL);
-
- /* Failed. Clean up. */
- PRINT_ERROR (("exec %s ", rp_exec_newwm));
- perror(" failed");
- free (rp_exec_newwm);
- rp_exec_newwm = NULL;
- for (i=0; i<num_screens; i++)
- {
- activate_screen(&screens[i]);
- }
- }
-
- if (hup_signalled > 0)
- {
- PRINT_DEBUG (("Restarting\n"));
- hook_run (&rp_restart_hook);
- clean_up ();
- execvp(myargv[0], myargv);
- }
-
- if (kill_signalled > 0)
- {
- PRINT_DEBUG (("Exiting\n"));
- hook_run (&rp_quit_hook);
- clean_up ();
- exit (EXIT_SUCCESS);
- }
-
- /* Report any X11 errors that have occurred. */
- if (rp_error_msg)
- {
- marked_message_printf (0, 6, "ERROR: %s", rp_error_msg);
- free (rp_error_msg);
- rp_error_msg = NULL;
- }
-}
-
-/* The main loop. */
-void
-listen_for_events (void)
-{
- int x_fd;
- fd_set fds;
-
- x_fd = ConnectionNumber (dpy);
- FD_ZERO (&fds);
-
- /* Loop forever. */
- for (;;)
- {
- handle_signals ();
-
- /* Handle the next event. */
- FD_SET (x_fd, &fds);
- XFlush(dpy);
-
- if (QLength (dpy) > 0
- || select(x_fd+1, &fds, NULL, NULL, NULL) == 1)
- {
- XNextEvent (dpy, &rp_current_event);
- delegate_event (&rp_current_event);
- XSync(dpy, False);
- }
- }
-}