/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <X11/X.h>
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/shape.h>
#include <X11/cursorfont.h>
#include "dat.h"
#include "fns.h"
Display *dpy;
ScreenInfo *screens;
int initting;
XFontStruct *font;
char **myargv;
char *shell;
Bool shape;
int num_screens;
Atom exit_larswm;
Atom restart_larswm;
Atom bartext_larswm;
Atom wm_state;
Atom wm_change_state;
Atom wm_protocols;
Atom wm_delete;
Atom wm_colormaps;
void
usage (void)
{
fprintf (stderr, "%s\n", VERSION);
fprintf (stderr,
"usage: larswm [-display display] [-f file] [-defaults] [-v]\n");
exit (1);
}
int
main (int argc, char **argv)
{
int i;
int shape_event, dummy;
char rcname[512];
char *display_string = "";
char *rc_file;
rc_file = getenv ("HOME");
if (rc_file)
{
strncpy (rcname, rc_file, sizeof (rcname) - 11);
strcat (rcname, "/.larswmrc");
rc_file = rcname;
}
myargv = argv;
font = 0;
for (i = 1; i < argc; i++)
{
if (strcmp (argv[i], "-f") == 0 && i + 1 < argc)
{
rc_file = argv[++i];
}
else if (strcmp (argv[i], "-display") == 0 && i + 1 < argc)
{
display_string = argv[++i];
}
else if (strcmp (argv[i], "-defaults") == 0)
{
set_defaults ();
dump_prefs ();
exit (0);
}
else if (strcmp (argv[i], "-v") == 0)
{
fprintf (stderr, "%s\n", VERSION);
exit (0);
}
else
{
usage ();
}
}
shell = (char *) getenv ("SHELL");
if (shell == NULL)
shell = DEFSHELL;
dpy = XOpenDisplay (display_string);
if (dpy == 0)
fatal ("can not open display");
initting = 1;
XSetErrorHandler (handler);
exit_larswm = XInternAtom (dpy, "LARSWM_EXIT", False);
restart_larswm = XInternAtom (dpy, "LARSWM_RESTART", False);
bartext_larswm = XInternAtom (dpy, "LARSWM_BARTEXT", False);
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_colormaps = XInternAtom (dpy, "WM_COLORMAP_WINDOWS", False);
XrmInitialize ();
load_prefs (rc_file);
if (prefs.fname != 0)
{
if ((font = XLoadQueryFont (dpy, prefs.fname)) == 0)
fprintf (stderr, "larswm: warning: can't load font %s\n",
prefs.fname);
}
if (font == 0)
{
prefs.fname = "fixed";
if ((font = XLoadQueryFont (dpy, prefs.fname)) == 0)
fatal ("can not find fixed font");
}
shape = XShapeQueryExtension (dpy, &shape_event, &dummy);
num_screens = ScreenCount (dpy);
if (num_screens > MAXSCREENS)
{
fprintf (stderr, "larswm was compiled with support for %d screens.\n",
MAXSCREENS);
fprintf (stderr,
"please recompile with MAXSCREENS set to at least %d screens.\n",
num_screens);
exit (1);
}
screens = (ScreenInfo *) malloc (sizeof (ScreenInfo) * num_screens);
for (i = 0; i < num_screens; i++)
initscreen (&screens[i], i);
XSync (dpy, False);
initting = 0;
nofocus ();
for (i = 0; i < num_screens; i++)
scanwins (&screens[i]);
initkeys (0);
XSync (dpy, False);
mainloop (shape_event);
exit (0);
}
void
initscreen (ScreenInfo * s, int i)
{
char *ds, *colon, *dot1;
unsigned long mask;
XGCValues gv;
int t;
s->num = i;
s->root = RootWindow (dpy, i);
s->def_cmap = DefaultColormap (dpy, i);
s->min_cmaps = MinCmapsOfScreen (ScreenOfDisplay (dpy, i));
s->tile_height = s->res_height = DisplayHeight (dpy, s->num);
ds = DisplayString (dpy);
strcpy (s->display, "DISPLAY=");
strcat (s->display, ds);
colon = rindex (ds, ':');
if (colon && num_screens > 1)
{
colon = s->display + 8 + (colon - ds);
dot1 = index (colon, '.');
if (!dot1)
dot1 = colon + strlen (colon);
sprintf (dot1, ".%d", i);
}
/* hey, this is experimental software, it doesn't have to look pretty just yet. :) */
if (prefs.fgstr)
{
XColor color;
if (XAllocNamedColor
(dpy, DefaultColormap (dpy, s->num), prefs.fgstr, &color,
&color) == 0)
{
fprintf (stderr,
"XAllocNamedColor - allocation of fg color failed.\n");
s->black = BlackPixel (dpy, i);
}
else
{
s->black = color.pixel;
}
}
else
{
s->black = BlackPixel (dpy, i);
}
if (prefs.bgstr)
{
XColor color;
if (XAllocNamedColor
(dpy, DefaultColormap (dpy, s->num), prefs.bgstr, &color,
&color) == 0)
{
fprintf (stderr,
"XAllocNamedColor - allocation of bg color failed.\n");
s->white = WhitePixel (dpy, i);
}
else
{
s->white = color.pixel;
}
}
else
{
s->white = WhitePixel (dpy, i);
}
#ifdef THREE_D
{
XColor topcolor;
XColor botcolor;
XColor get_c;
get_c.pixel = s->white;
if ((get_c.pixel == WhitePixel (dpy, s->num)) ||
(get_c.pixel == BlackPixel (dpy, s->num)))
{
topcolor.red = L_TOP (L_OFF_R);
topcolor.green = L_TOP (L_OFF_G);
topcolor.blue = L_TOP (L_OFF_B);
botcolor.red = L_BOT (L_OFF_R);
botcolor.green = L_BOT (L_OFF_G);
botcolor.blue = L_BOT (L_OFF_B);
}
else
{
XQueryColor (dpy, s->def_cmap, &get_c);
topcolor.red = L_TOP (get_c.red);
topcolor.green = L_TOP (get_c.green);
topcolor.blue = L_TOP (get_c.blue);
botcolor.red = L_BOT (get_c.red);
botcolor.green = L_BOT (get_c.green);
botcolor.blue = L_BOT (get_c.blue);
}
XAllocColor (dpy, s->def_cmap, &topcolor);
XAllocColor (dpy, s->def_cmap, &botcolor);
s->topwhite = topcolor.pixel;
s->botwhite = botcolor.pixel;
gv.foreground = s->topwhite;
gv.line_width = 0;
mask = GCForeground | GCLineWidth;
s->topwhitegc = XCreateGC (dpy, s->root, mask, &gv);
gv.foreground = s->botwhite;
gv.line_width = 0;
mask = GCForeground | GCLineWidth;
s->botwhitegc = XCreateGC (dpy, s->root, mask, &gv);
get_c.pixel = s->black;
if ((get_c.pixel == WhitePixel (dpy, s->num)) ||
(get_c.pixel == BlackPixel (dpy, s->num)))
{
topcolor.red = L_TOP (L_ON_R);
topcolor.green = L_TOP (L_ON_G);
topcolor.blue = L_TOP (L_ON_B);
botcolor.red = L_BOT (L_ON_R);
botcolor.green = L_BOT (L_ON_G);
botcolor.blue = L_BOT (L_ON_B);
}
else
{
XQueryColor (dpy, s->def_cmap, &get_c);
topcolor.red = L_TOP (get_c.red);
topcolor.green = L_TOP (get_c.green);
topcolor.blue = L_TOP (get_c.blue);
botcolor.red = L_BOT (get_c.red);
botcolor.green = L_BOT (get_c.green);
botcolor.blue = L_BOT (get_c.blue);
}
XAllocColor (dpy, s->def_cmap, &topcolor);
XAllocColor (dpy, s->def_cmap, &botcolor);
s->topblack = topcolor.pixel;
s->botblack = botcolor.pixel;
gv.foreground = s->topblack;
gv.line_width = 0;
mask = GCForeground | GCLineWidth;
s->topblackgc = XCreateGC (dpy, s->root, mask, &gv);
gv.foreground = s->botblack;
gv.line_width = 0;
mask = GCForeground | GCLineWidth;
s->botblackgc = XCreateGC (dpy, s->root, mask, &gv);
}
#endif
gv.foreground = s->black ^ s->white;
gv.background = s->white;
gv.function = GXxor;
gv.line_width = 0;
gv.subwindow_mode = IncludeInferiors;
mask = GCForeground | GCBackground | GCFunction | GCLineWidth
| GCSubwindowMode;
if (font != 0)
{
gv.font = font->fid;
mask |= GCFont;
}
s->gc = XCreateGC (dpy, s->root, mask, &gv);
s->place = XCreateFontCursor (dpy, XC_top_left_corner);
s->sweep = XCreateFontCursor (dpy, XC_bottom_right_corner);
XSelectInput (dpy, s->root,
SubstructureRedirectMask | SubstructureNotifyMask |
ColormapChangeMask | PropertyChangeMask | ButtonPressMask |
ButtonReleaseMask);
XSync (dpy, False);
/* lars stuff */
s->desktop = 0;
for (t = 0; t < prefs.desktops; t++)
{
s->clickthru[t] = prefs.clickthru[s->num][t];
s->tile_resize[t] = prefs.tile_resize[s->num][t];
s->skip_focus[t] = prefs.skip_focus[s->num][t];
s->left_track_width[t] = prefs.left_track_width[s->num][t];
s->bigmr[t] = 1;
s->focused[t] = 0;
s->notilefocused[t] = 0;
s->notile_raised[t] = 0;
}
s->barwin =
XCreateSimpleWindow (dpy, s->root, BAR_X (s), BAR_Y (s), BAR_WIDTH (s),
BAR_HEIGHT, 0, s->black, s->white);
XSelectInput (dpy, s->barwin,
ExposureMask | ButtonPressMask | ButtonReleaseMask);
raise_tbar (s);
s->tile_height = BAR_Y (s);
s->res_height = BAR_Y (s);
}
ScreenInfo *
getscreen (Window w)
{
int i;
for (i = 0; i < num_screens; i++)
if (screens[i].root == w)
return &screens[i];
return 0;
}
void
sendcmessage (Window w, Atom a, long x, int isroot)
{
XEvent ev;
long mask;
memset (&ev, 0, sizeof (ev));
ev.xclient.type = ClientMessage;
ev.xclient.window = w;
ev.xclient.message_type = a;
ev.xclient.format = 32;
ev.xclient.data.l[0] = x;
ev.xclient.data.l[1] = CurrentTime;
mask = 0L;
if (isroot)
mask = SubstructureRedirectMask; /* magic! */
XSendEvent (dpy, w, False, mask, &ev);
}
void
sendconfig (Client * c)
{
XConfigureEvent ce;
ce.type = ConfigureNotify;
ce.event = c->window;
ce.window = c->window;
ce.x = c->x;
ce.y = c->y;
ce.width = c->dx;
ce.height = c->dy;
ce.border_width = c->border;
ce.above = None;
ce.override_redirect = 0;
XSendEvent (dpy, c->window, False, StructureNotifyMask, (XEvent *) & ce);
}
void
cleanup (void)
{
Client *c, *cc[2], *next;
XWindowChanges wc;
int i;
/* order of un-reparenting determines final stacking order... */
cc[0] = cc[1] = 0;
for (c = clients; c; c = next)
{
next = c->next;
i = normal (c);
c->next = cc[i];
cc[i] = c;
}
for (i = 0; i < 2; i++)
{
for (c = cc[i]; c; c = c->next)
{
if (!withdrawn (c))
{
gravitate (c, 1);
XReparentWindow (dpy, c->window, c->screen->root, c->x, c->y);
}
wc.border_width = c->border;
XConfigureWindow (dpy, c->window, CWBorderWidth, &wc);
}
}
XSetInputFocus (dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
for (i = 0; i < num_screens; i++)
cmapnofocus (&screens[i]);
XCloseDisplay (dpy);
}
syntax highlighted by Code2HTML, v. 0.9.1