main.c
changeset 333 827f8f6c9e97
parent 329 cea0c98495bc
child 339 5c874c619287
equal deleted inserted replaced
332:c5bea7c0231b 333:827f8f6c9e97
    12 #include <sys/select.h>
    12 #include <sys/select.h>
    13 #include <X11/cursorfont.h>
    13 #include <X11/cursorfont.h>
    14 #include <X11/keysym.h>
    14 #include <X11/keysym.h>
    15 #include <X11/Xatom.h>
    15 #include <X11/Xatom.h>
    16 #include <X11/Xproto.h>
    16 #include <X11/Xproto.h>
    17 
       
    18 /* static */
       
    19 
       
    20 static int (*xerrorxlib)(Display *, XErrorEvent *);
       
    21 static Bool otherwm, readin;
       
    22 
       
    23 static void
       
    24 cleanup()
       
    25 {
       
    26 	close(STDIN_FILENO);
       
    27 	while(sel) {
       
    28 		resize(sel, True, TopLeft);
       
    29 		unmanage(sel);
       
    30 	}
       
    31 	if(dc.font.set)
       
    32 		XFreeFontSet(dpy, dc.font.set);
       
    33 	else
       
    34 		XFreeFont(dpy, dc.font.xfont);
       
    35 	XUngrabKey(dpy, AnyKey, AnyModifier, root);
       
    36 	XFreePixmap(dpy, dc.drawable);
       
    37 	XFreeGC(dpy, dc.gc);
       
    38 	XDestroyWindow(dpy, barwin);
       
    39 	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
       
    40 	XSync(dpy, False);
       
    41 }
       
    42 
       
    43 static void
       
    44 scan()
       
    45 {
       
    46 	unsigned int i, num;
       
    47 	Window *wins, d1, d2;
       
    48 	XWindowAttributes wa;
       
    49 
       
    50 	wins = NULL;
       
    51 	if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
       
    52 		for(i = 0; i < num; i++) {
       
    53 			if(!XGetWindowAttributes(dpy, wins[i], &wa))
       
    54 				continue;
       
    55 			if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
       
    56 				continue;
       
    57 			if(wa.map_state == IsViewable)
       
    58 				manage(wins[i], &wa);
       
    59 		}
       
    60 	}
       
    61 	if(wins)
       
    62 		XFree(wins);
       
    63 }
       
    64 
       
    65 /*
       
    66  * Startup Error handler to check if another window manager
       
    67  * is already running.
       
    68  */
       
    69 static int
       
    70 xerrorstart(Display *dsply, XErrorEvent *ee)
       
    71 {
       
    72 	otherwm = True;
       
    73 	return -1;
       
    74 }
       
    75 
    17 
    76 /* extern */
    18 /* extern */
    77 
    19 
    78 char stext[1024];
    20 char stext[1024];
    79 Bool *seltag;
    21 Bool *seltag;
    87 Cursor cursor[CurLast];
    29 Cursor cursor[CurLast];
    88 Display *dpy;
    30 Display *dpy;
    89 DC dc = {0};
    31 DC dc = {0};
    90 Window root, barwin;
    32 Window root, barwin;
    91 
    33 
       
    34 /* static */
       
    35 
       
    36 static int (*xerrorxlib)(Display *, XErrorEvent *);
       
    37 static Bool otherwm, readin;
       
    38 
       
    39 static void
       
    40 cleanup()
       
    41 {
       
    42 	close(STDIN_FILENO);
       
    43 	while(sel) {
       
    44 		resize(sel, True, TopLeft);
       
    45 		unmanage(sel);
       
    46 	}
       
    47 	if(dc.font.set)
       
    48 		XFreeFontSet(dpy, dc.font.set);
       
    49 	else
       
    50 		XFreeFont(dpy, dc.font.xfont);
       
    51 	XUngrabKey(dpy, AnyKey, AnyModifier, root);
       
    52 	XFreePixmap(dpy, dc.drawable);
       
    53 	XFreeGC(dpy, dc.gc);
       
    54 	XDestroyWindow(dpy, barwin);
       
    55 	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
       
    56 	XSync(dpy, False);
       
    57 }
       
    58 
       
    59 static void
       
    60 scan()
       
    61 {
       
    62 	unsigned int i, num;
       
    63 	Window *wins, d1, d2;
       
    64 	XWindowAttributes wa;
       
    65 
       
    66 	wins = NULL;
       
    67 	if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
       
    68 		for(i = 0; i < num; i++) {
       
    69 			if(!XGetWindowAttributes(dpy, wins[i], &wa))
       
    70 				continue;
       
    71 			if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
       
    72 				continue;
       
    73 			if(wa.map_state == IsViewable)
       
    74 				manage(wins[i], &wa);
       
    75 		}
       
    76 	}
       
    77 	if(wins)
       
    78 		XFree(wins);
       
    79 }
       
    80 
       
    81 static void
       
    82 setup()
       
    83 {
       
    84 	int i, j;
       
    85 	unsigned int mask;
       
    86 	Window w;
       
    87 	XModifierKeymap *modmap;
       
    88 	XSetWindowAttributes wa;
       
    89 
       
    90 	/* init atoms */
       
    91 	wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
       
    92 	wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
       
    93 	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
       
    94 	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
       
    95 	XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
       
    96 			PropModeReplace, (unsigned char *) netatom, NetLast);
       
    97 
       
    98 	/* init cursors */
       
    99 	cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
       
   100 	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
       
   101 	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
       
   102 
       
   103 	modmap = XGetModifierMapping(dpy);
       
   104 	for (i = 0; i < 8; i++) {
       
   105 		for (j = 0; j < modmap->max_keypermod; j++) {
       
   106 			if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock))
       
   107 				numlockmask = (1 << i);
       
   108 		}
       
   109 	}
       
   110 	XFree(modmap);
       
   111 
       
   112 	wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | EnterWindowMask | LeaveWindowMask;
       
   113 	wa.cursor = cursor[CurNormal];
       
   114 	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
       
   115 
       
   116 	grabkeys();
       
   117 	initrregs();
       
   118 
       
   119 	for(ntags = 0; tags[ntags]; ntags++);
       
   120 	seltag = emallocz(sizeof(Bool) * ntags);
       
   121 	seltag[0] = True;
       
   122 
       
   123 	/* style */
       
   124 	dc.bg = getcolor(BGCOLOR);
       
   125 	dc.fg = getcolor(FGCOLOR);
       
   126 	dc.border = getcolor(BORDERCOLOR);
       
   127 	setfont(FONT);
       
   128 
       
   129 	sx = sy = 0;
       
   130 	sw = DisplayWidth(dpy, screen);
       
   131 	sh = DisplayHeight(dpy, screen);
       
   132 	mw = (sw * MASTERW) / 100;
       
   133 
       
   134 	bx = by = 0;
       
   135 	bw = sw;
       
   136 	dc.h = bh = dc.font.height + 4;
       
   137 	wa.override_redirect = 1;
       
   138 	wa.background_pixmap = ParentRelative;
       
   139 	wa.event_mask = ButtonPressMask | ExposureMask;
       
   140 	barwin = XCreateWindow(dpy, root, bx, by, bw, bh, 0, DefaultDepth(dpy, screen),
       
   141 			CopyFromParent, DefaultVisual(dpy, screen),
       
   142 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
       
   143 	XDefineCursor(dpy, barwin, cursor[CurNormal]);
       
   144 	XMapRaised(dpy, barwin);
       
   145 
       
   146 	dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
       
   147 	dc.gc = XCreateGC(dpy, root, 0, 0);
       
   148 
       
   149 	issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
       
   150 
       
   151 	strcpy(stext, "dwm-"VERSION);
       
   152 }
       
   153 
       
   154 /*
       
   155  * Startup Error handler to check if another window manager
       
   156  * is already running.
       
   157  */
       
   158 static int
       
   159 xerrorstart(Display *dsply, XErrorEvent *ee)
       
   160 {
       
   161 	otherwm = True;
       
   162 	return -1;
       
   163 }
       
   164 
       
   165 /* extern */
       
   166 
    92 int
   167 int
    93 getproto(Window w)
   168 getproto(Window w)
    94 {
   169 {
    95 	int i, format, protos, status;
   170 	int i, format, protos, status;
    96 	unsigned long extra, res;
   171 	unsigned long extra, res;
   151 }
   226 }
   152 
   227 
   153 int
   228 int
   154 main(int argc, char *argv[])
   229 main(int argc, char *argv[])
   155 {
   230 {
   156 	int i, j, xfd;
   231 	int r, xfd;
   157 	unsigned int mask;
       
   158 	fd_set rd;
   232 	fd_set rd;
   159 	Window w;
       
   160 	XModifierKeymap *modmap;
       
   161 	XSetWindowAttributes wa;
       
   162 
   233 
   163 	if(argc == 2 && !strncmp("-v", argv[1], 3)) {
   234 	if(argc == 2 && !strncmp("-v", argv[1], 3)) {
   164 		fputs("dwm-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout);
   235 		fputs("dwm-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout);
   165 		exit(EXIT_SUCCESS);
   236 		exit(EXIT_SUCCESS);
   166 	}
   237 	}
   187 	XSync(dpy, False);
   258 	XSync(dpy, False);
   188 	XSetErrorHandler(NULL);
   259 	XSetErrorHandler(NULL);
   189 	xerrorxlib = XSetErrorHandler(xerror);
   260 	xerrorxlib = XSetErrorHandler(xerror);
   190 	XSync(dpy, False);
   261 	XSync(dpy, False);
   191 
   262 
   192 	/* init atoms */
   263 	setup();
   193 	wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
       
   194 	wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
       
   195 	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
       
   196 	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
       
   197 	XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
       
   198 			PropModeReplace, (unsigned char *) netatom, NetLast);
       
   199 
       
   200 	/* init cursors */
       
   201 	cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
       
   202 	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
       
   203 	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
       
   204 
       
   205 	modmap = XGetModifierMapping(dpy);
       
   206 	for (i = 0; i < 8; i++) {
       
   207 		for (j = 0; j < modmap->max_keypermod; j++) {
       
   208 			if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock))
       
   209 				numlockmask = (1 << i);
       
   210 		}
       
   211 	}
       
   212 	XFree(modmap);
       
   213 
       
   214 	wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | EnterWindowMask | LeaveWindowMask;
       
   215 	wa.cursor = cursor[CurNormal];
       
   216 	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
       
   217 
       
   218 	grabkeys();
       
   219 	initrregs();
       
   220 
       
   221 	for(ntags = 0; tags[ntags]; ntags++);
       
   222 	seltag = emallocz(sizeof(Bool) * ntags);
       
   223 	seltag[0] = True;
       
   224 
       
   225 	/* style */
       
   226 	dc.bg = getcolor(BGCOLOR);
       
   227 	dc.fg = getcolor(FGCOLOR);
       
   228 	dc.border = getcolor(BORDERCOLOR);
       
   229 	setfont(FONT);
       
   230 
       
   231 	sx = sy = 0;
       
   232 	sw = DisplayWidth(dpy, screen);
       
   233 	sh = DisplayHeight(dpy, screen);
       
   234 	mw = (sw * MASTERW) / 100;
       
   235 
       
   236 	bx = by = 0;
       
   237 	bw = sw;
       
   238 	dc.h = bh = dc.font.height + 4;
       
   239 	wa.override_redirect = 1;
       
   240 	wa.background_pixmap = ParentRelative;
       
   241 	wa.event_mask = ButtonPressMask | ExposureMask;
       
   242 	barwin = XCreateWindow(dpy, root, bx, by, bw, bh, 0, DefaultDepth(dpy, screen),
       
   243 			CopyFromParent, DefaultVisual(dpy, screen),
       
   244 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
       
   245 	XDefineCursor(dpy, barwin, cursor[CurNormal]);
       
   246 	XMapRaised(dpy, barwin);
       
   247 
       
   248 	dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
       
   249 	dc.gc = XCreateGC(dpy, root, 0, 0);
       
   250 
       
   251 	strcpy(stext, "dwm-"VERSION);
       
   252 	drawstatus();
   264 	drawstatus();
   253 
       
   254 	issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
       
   255 
       
   256 	scan();
   265 	scan();
   257 
   266 
   258 	/* main event loop, also reads status text from stdin */
   267 	/* main event loop, also reads status text from stdin */
   259 	XSync(dpy, False);
   268 	XSync(dpy, False);
   260 	procevent();
   269 	procevent();
   262 	while(running) {
   271 	while(running) {
   263 		FD_ZERO(&rd);
   272 		FD_ZERO(&rd);
   264 		if(readin)
   273 		if(readin)
   265 			FD_SET(STDIN_FILENO, &rd);
   274 			FD_SET(STDIN_FILENO, &rd);
   266 		FD_SET(xfd, &rd);
   275 		FD_SET(xfd, &rd);
   267 		i = select(xfd + 1, &rd, NULL, NULL, NULL);
   276 		r = select(xfd + 1, &rd, NULL, NULL, NULL);
   268 		if((i == -1) && (errno == EINTR))
   277 		if((r == -1) && (errno == EINTR))
   269 			continue;
   278 			continue;
   270 		if(i > 0) {
   279 		if(r > 0) {
   271 			if(readin && FD_ISSET(STDIN_FILENO, &rd)) {
   280 			if(readin && FD_ISSET(STDIN_FILENO, &rd)) {
   272 				readin = NULL != fgets(stext, sizeof(stext), stdin);
   281 				readin = NULL != fgets(stext, sizeof(stext), stdin);
   273 				if(readin)
   282 				if(readin)
   274 					stext[strlen(stext) - 1] = 0;
   283 					stext[strlen(stext) - 1] = 0;
   275 				else 
   284 				else 
   276 					strcpy(stext, "broken pipe");
   285 					strcpy(stext, "broken pipe");
   277 				drawstatus();
   286 				drawstatus();
   278 			}
   287 			}
   279 		}
   288 		}
   280 		else if(i < 0)
   289 		else if(r < 0)
   281 			eprint("select failed\n");
   290 			eprint("select failed\n");
   282 		procevent();
   291 		procevent();
   283 	}
   292 	}
   284 	cleanup();
   293 	cleanup();
   285 	XCloseDisplay(dpy);
   294 	XCloseDisplay(dpy);