main.c
changeset 75 f08271b7cb20
parent 74 5370ef170cc9
child 76 4bd49f404f10
equal deleted inserted replaced
74:5370ef170cc9 75:f08271b7cb20
    41 
    41 
    42 DC dc = {0};
    42 DC dc = {0};
    43 Client *clients = NULL;
    43 Client *clients = NULL;
    44 Client *sel = NULL;
    44 Client *sel = NULL;
    45 
    45 
    46 static Bool other_wm_running;
    46 static Bool otherwm;
    47 static const char version[] =
    47 static const char version[] =
    48 	"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
    48 	"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
    49 static int (*x_xerror) (Display *, XErrorEvent *);
    49 static int (*xerrorxlib)(Display *, XErrorEvent *);
    50 
    50 
    51 static void
    51 static void
    52 usage() {	error("usage: dwm [-v]\n"); }
    52 usage() {	eprint("usage: dwm [-v]\n"); }
    53 
    53 
    54 static void
    54 static void
    55 scan_wins()
    55 scan()
    56 {
    56 {
    57 	unsigned int i, num;
    57 	unsigned int i, num;
    58 	Window *wins;
    58 	Window *wins;
    59 	XWindowAttributes wa;
    59 	XWindowAttributes wa;
    60 	Window d1, d2;
    60 	Window d1, d2;
    71 	}
    71 	}
    72 	if(wins)
    72 	if(wins)
    73 		XFree(wins);
    73 		XFree(wins);
    74 }
    74 }
    75 
    75 
       
    76 static void
       
    77 cleanup()
       
    78 {
       
    79 	while(sel) {
       
    80 		resize(sel, True);
       
    81 		unmanage(sel);
       
    82 	}
       
    83 	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
       
    84 }
       
    85 
       
    86 void
       
    87 quit(Arg *arg)
       
    88 {
       
    89 	running = False;
       
    90 }
       
    91 
    76 static int
    92 static int
    77 win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
    93 win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
    78 {
    94 {
    79 	Atom real;
    95 	Atom real;
    80 	int format;
    96 	int format;
    92 	}
   108 	}
    93 	return res;
   109 	return res;
    94 }
   110 }
    95 
   111 
    96 int
   112 int
    97 proto(Window w)
   113 getproto(Window w)
    98 {
   114 {
    99 	unsigned char *protocols;
   115 	unsigned char *protocols;
   100 	long res;
   116 	long res;
   101 	int protos = 0;
   117 	int protos = 0;
   102 	int i;
   118 	int i;
   127 	XSendEvent(dpy, w, False, NoEventMask, &e);
   143 	XSendEvent(dpy, w, False, NoEventMask, &e);
   128 	XFlush(dpy);
   144 	XFlush(dpy);
   129 }
   145 }
   130 
   146 
   131 /*
   147 /*
       
   148  * Startup Error handler to check if another window manager
       
   149  * is already running.
       
   150  */
       
   151 static int
       
   152 xerrorstart(Display *dsply, XErrorEvent *ee)
       
   153 {
       
   154 	otherwm = True;
       
   155 	return -1;
       
   156 }
       
   157 
       
   158 /*
   132  * There's no way to check accesses to destroyed windows, thus
   159  * There's no way to check accesses to destroyed windows, thus
   133  * those cases are ignored (especially on UnmapNotify's).
   160  * those cases are ignored (especially on UnmapNotify's).
   134  * Other types of errors call Xlib's default error handler, which
   161  * Other types of errors call Xlib's default error handler, which
   135  * calls exit().
   162  * calls exit().
   136  */
   163  */
   137 int
   164 int
   138 xerror(Display *dpy, XErrorEvent *error)
   165 xerror(Display *dpy, XErrorEvent *ee)
   139 {
   166 {
   140 	if(error->error_code == BadWindow
   167 	if(ee->error_code == BadWindow
   141 			|| (error->request_code == X_SetInputFocus
   168 			|| (ee->request_code == X_SetInputFocus
   142 				&& error->error_code == BadMatch)
   169 				&& ee->error_code == BadMatch)
   143 			|| (error->request_code == X_PolyText8
   170 			|| (ee->request_code == X_PolyText8
   144 				&& error->error_code == BadDrawable)
   171 				&& ee->error_code == BadDrawable)
   145 			|| (error->request_code == X_PolyFillRectangle
   172 			|| (ee->request_code == X_PolyFillRectangle
   146 				&& error->error_code == BadDrawable)
   173 				&& ee->error_code == BadDrawable)
   147 			|| (error->request_code == X_PolySegment
   174 			|| (ee->request_code == X_PolySegment
   148 				&& error->error_code == BadDrawable)
   175 				&& ee->error_code == BadDrawable)
   149 			|| (error->request_code == X_ConfigureWindow
   176 			|| (ee->request_code == X_ConfigureWindow
   150 				&& error->error_code == BadMatch)
   177 				&& ee->error_code == BadMatch)
   151 			|| (error->request_code == X_GrabKey
   178 			|| (ee->request_code == X_GrabKey
   152 				&& error->error_code == BadAccess))
   179 				&& ee->error_code == BadAccess))
   153 		return 0;
   180 		return 0;
   154 	fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
   181 	fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
   155 			error->request_code, error->error_code);
   182 			ee->request_code, ee->error_code);
   156 	return x_xerror(dpy, error); /* may call exit() */
   183 	return xerrorxlib(dpy, ee); /* may call exit() */
   157 }
       
   158 
       
   159 /*
       
   160  * Startup Error handler to check if another window manager
       
   161  * is already running.
       
   162  */
       
   163 static int
       
   164 startup_xerror(Display *dpy, XErrorEvent *error)
       
   165 {
       
   166 	other_wm_running = True;
       
   167 	return -1;
       
   168 }
       
   169 
       
   170 static void
       
   171 cleanup()
       
   172 {
       
   173 	while(sel) {
       
   174 		resize(sel, True);
       
   175 		unmanage(sel);
       
   176 	}
       
   177 	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
       
   178 }
       
   179 
       
   180 void
       
   181 quit(Arg *arg)
       
   182 {
       
   183 	running = False;
       
   184 }
   184 }
   185 
   185 
   186 int
   186 int
   187 main(int argc, char *argv[])
   187 main(int argc, char *argv[])
   188 {
   188 {
   206 		}
   206 		}
   207 	}
   207 	}
   208 
   208 
   209 	dpy = XOpenDisplay(0);
   209 	dpy = XOpenDisplay(0);
   210 	if(!dpy)
   210 	if(!dpy)
   211 		error("dwm: cannot connect X server\n");
   211 		eprint("dwm: cannot connect X server\n");
   212 
   212 
   213 	screen = DefaultScreen(dpy);
   213 	screen = DefaultScreen(dpy);
   214 	root = RootWindow(dpy, screen);
   214 	root = RootWindow(dpy, screen);
   215 
   215 
   216 	/* check if another WM is already running */
   216 	/* check if another WM is already running */
   217 	other_wm_running = False;
   217 	otherwm = False;
   218 	XSetErrorHandler(startup_xerror);
   218 	XSetErrorHandler(xerrorstart);
   219 	/* this causes an error if some other WM is running */
   219 	/* this causes an error if some other WM is running */
   220 	XSelectInput(dpy, root, SubstructureRedirectMask);
   220 	XSelectInput(dpy, root, SubstructureRedirectMask);
   221 	XFlush(dpy);
   221 	XFlush(dpy);
   222 
   222 
   223 	if(other_wm_running)
   223 	if(otherwm)
   224 		error("dwm: another window manager is already running\n");
   224 		eprint("dwm: another window manager is already running\n");
   225 
   225 
   226 	XSetErrorHandler(0);
   226 	XSetErrorHandler(0);
   227 	x_xerror = XSetErrorHandler(xerror);
   227 	xerrorxlib = XSetErrorHandler(xerror);
   228 
   228 
   229 	/* init atoms */
   229 	/* init atoms */
   230 	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
   230 	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
   231 	wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
   231 	wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
   232 	net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
   232 	net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
   276 	wa.cursor = cursor[CurNormal];
   276 	wa.cursor = cursor[CurNormal];
   277 
   277 
   278 	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
   278 	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
   279 
   279 
   280 	strcpy(stext, "dwm-"VERSION);
   280 	strcpy(stext, "dwm-"VERSION);
   281 	scan_wins();
   281 	scan();
   282 
   282 
   283 	/* main event loop, reads status text from stdin as well */
   283 	/* main event loop, reads status text from stdin as well */
   284 Mainloop:
   284 Mainloop:
   285 	while(running) {
   285 	while(running) {
   286 		FD_ZERO(&rd);
   286 		FD_ZERO(&rd);
   290 
   290 
   291 		i = select(ConnectionNumber(dpy) + 1, &rd, 0, 0, 0);
   291 		i = select(ConnectionNumber(dpy) + 1, &rd, 0, 0, 0);
   292 		if(i == -1 && errno == EINTR)
   292 		if(i == -1 && errno == EINTR)
   293 			continue;
   293 			continue;
   294 		if(i < 0)
   294 		if(i < 0)
   295 			error("select failed\n");
   295 			eprint("select failed\n");
   296 		else if(i > 0) {
   296 		else if(i > 0) {
   297 			if(FD_ISSET(ConnectionNumber(dpy), &rd)) {
   297 			if(FD_ISSET(ConnectionNumber(dpy), &rd)) {
   298 				while(XPending(dpy)) {
   298 				while(XPending(dpy)) {
   299 					XNextEvent(dpy, &ev);
   299 					XNextEvent(dpy, &ev);
   300 					if(handler[ev.type])
   300 					if(handler[ev.type])