summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..313d7fc
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2000 Shawn Betts
+ *
+ * This program 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.
+ *
+ * This program 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/Xproto.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include "ratpoison.h"
+
+static void init_screen (screen_info *s, int screen_num);
+
+Atom wm_state;
+Atom wm_change_state;
+Atom wm_protocols;
+Atom wm_delete;
+Atom wm_take_focus;
+Atom wm_colormaps;
+
+Atom rp_restart;
+
+screen_info *screens;
+int num_screens;
+Display *dpy;
+int exit_signal = 0; /* Set by the signal handler. if this
+ is set, quit. */
+static XFontStruct *font;
+
+char **myargv;
+
+void
+sighandler ()
+{
+ fprintf (stderr, "ratpoison: Agg! I've been SHOT!\n");
+ clean_up ();
+ exit (EXIT_FAILURE);
+}
+
+void
+hup_handler ()
+{
+ /* This doesn't seem to restart more than once for some reason...*/
+
+ fprintf (stderr, "ratpoison: Restarting with a fresh plate.\n");
+ clean_up ();
+ execvp(myargv[0], myargv);
+}
+
+void
+alrm_handler ()
+{
+ int i;
+
+#ifdef DEBUG
+ printf ("alarm recieved.\n");
+#endif
+
+ /* FIXME: should only hide 1 bar, but we hide them all. */
+ for (i=0; i<num_screens; i++)
+ {
+ hide_bar (&screens[i]);
+ }
+ XSync (dpy, False);
+}
+
+int
+handler (Display *d, XErrorEvent *e)
+{
+ char error_msg[100];
+
+ if (e->request_code == X_ChangeWindowAttributes && e->error_code == BadAccess) {
+ fprintf(stderr, "ratpoison: There can be only ONE.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ XGetErrorText (d, e->error_code, error_msg, sizeof (error_msg));
+ fprintf (stderr, "ratpoison: %s!\n", error_msg);
+
+ return 0;
+ // exit (EXIT_FAILURE);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ myargv = argv;
+
+ if (!(dpy = XOpenDisplay (NULL)))
+ {
+ fprintf (stderr, "Can't open display\n");
+ return EXIT_FAILURE;
+ }
+
+ /* Setup signal handlers. */
+ XSetErrorHandler(handler);
+ if (signal (SIGALRM, alrm_handler) == SIG_IGN) signal (SIGALRM, SIG_IGN);
+ if (signal (SIGTERM, sighandler) == SIG_IGN) signal (SIGTERM, SIG_IGN);
+ if (signal (SIGINT, sighandler) == SIG_IGN) signal (SIGINT, SIG_IGN);
+ if (signal (SIGHUP, hup_handler) == SIG_IGN)
+ {
+ printf ("Ignoring HUP.\n");
+ signal (SIGHUP, SIG_IGN);
+ }
+
+ init_numbers ();
+ init_window_list ();
+
+ font = XLoadQueryFont (dpy, FONT_NAME);
+ if (font == NULL)
+ {
+ fprintf (stderr, "ratpoison: Cannot load font %s.\n", FONT_NAME);
+ exit (EXIT_FAILURE);
+ }
+
+ num_screens = ScreenCount (dpy);
+ if ((screens = (screen_info *)malloc (sizeof (screen_info) * num_screens)) == NULL)
+ {
+ fprintf (stderr, "ratpoison:main.c:Out of memory!\n");
+ exit (EXIT_FAILURE);
+ }
+
+ printf ("%d screens.\n", num_screens);
+
+ /* Initialize the screens */
+ for (i=0; i<num_screens; i++)
+ {
+ init_screen (&screens[i], i);
+ }
+
+ /* Set our Atoms */
+ wm_state = XInternAtom(dpy, "WM_STATE", False);
+ wm_change_state = XInternAtom(dpy, "WM_CHANGE_STATE", False);
+ wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
+ wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+ wm_take_focus = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
+ wm_colormaps = XInternAtom(dpy, "WM_COLORMAP_WINDOWS", False);
+
+ rp_restart = XInternAtom (dpy, "RP_RESTART", False);
+
+ XSync (dpy, False);
+
+ /* Set an initial window as active. */
+ rp_current_window = rp_window_head;
+ set_active_window (rp_current_window);
+
+ handle_events ();
+
+ return EXIT_SUCCESS;
+}
+
+static void
+init_screen (screen_info *s, int screen_num)
+{
+ XColor fg_color, bg_color, bold_color, junk;
+ XGCValues gv;
+
+ s->screen_num = screen_num;
+ s->root = RootWindow (dpy, screen_num);
+ s->def_cmap = DefaultColormap (dpy, screen_num);
+ s->font = font;
+ XGetWindowAttributes (dpy, s->root, &s->root_attr);
+
+ /* Get our program bar colors */
+ if (!XAllocNamedColor (dpy, s->def_cmap, BAR_FG_COLOR, &fg_color, &junk))
+ {
+ fprintf (stderr, "Unknown color '%s'\n", BAR_FG_COLOR);
+ }
+
+ if (!XAllocNamedColor (dpy, s->def_cmap, BAR_BG_COLOR, &bg_color, &junk))
+ {
+ fprintf (stderr, "Unknown color '%s'\n", BAR_BG_COLOR);
+ }
+
+ if (!XAllocNamedColor (dpy, s->def_cmap, BAR_BOLD_COLOR, &bold_color, &junk))
+ {
+ fprintf (stderr, "Unknown color '%s'\n", BAR_BOLD_COLOR);
+ }
+
+ /* Setup the GC for drawing the font. */
+ gv.foreground = fg_color.pixel;
+ gv.background = bg_color.pixel;
+ gv.function = GXcopy;
+ gv.line_width = 1;
+ gv.subwindow_mode = IncludeInferiors;
+ gv.font = font->fid;
+ s->normal_gc = XCreateGC(dpy, s->root,
+ GCForeground | GCBackground | GCFunction
+ | GCLineWidth | GCSubwindowMode | GCFont,
+ &gv);
+ gv.foreground = bold_color.pixel;
+ s->bold_gc = XCreateGC(dpy, s->root,
+ GCForeground | GCBackground | GCFunction
+ | GCLineWidth | GCSubwindowMode | GCFont,
+ &gv);
+
+ XSelectInput(dpy, s->root,
+ PropertyChangeMask | ColormapChangeMask
+ | SubstructureRedirectMask | KeyPressMask
+ | SubstructureNotifyMask );
+ XSync (dpy, 0);
+
+ /* Create the program bar window. */
+ s->bar_is_raised = 0;
+ s->bar_window = XCreateSimpleWindow (dpy, s->root, 0, 0,
+ 1, 1, 1, fg_color.pixel, bg_color.pixel);
+ XSelectInput (dpy, s->bar_window, StructureNotifyMask);
+
+ /* Setup the window that will recieve all keystrokes once the prefix
+ key has been pressed. */
+ s->key_window = XCreateSimpleWindow (dpy, s->root, 0, 0, 1, 1, 0, WhitePixel (dpy, 0), BlackPixel (dpy, 0));
+ XSelectInput (dpy, s->key_window, KeyPressMask);
+ XMapWindow (dpy, s->key_window);
+
+ /* Create the input window. */
+ s->input_window = XCreateSimpleWindow (dpy, s->root, 0, 0,
+ 1, 1, 1, fg_color.pixel, bg_color.pixel);
+ XSelectInput (dpy, s->input_window, KeyPressMask);
+ scanwins (s);
+}
+
+void
+clean_up ()
+{
+ XSetInputFocus (dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
+ XCloseDisplay (dpy);
+}
+
+/* Given a root window, return the screen_info struct */
+screen_info *
+find_screen (Window w)
+{
+ int i;
+
+ for (i=0; i<num_screens; i++)
+ if (screens[i].root == w) return &screens[i];
+
+ return NULL;
+}