/* Copyright (c) 1994-1996 David Hogan, see README for licence details */ #include #include #include #include #include #include #include #include #include #include #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); }