about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--calmwm.c29
-rw-r--r--calmwm.h21
-rw-r--r--client.c45
-rw-r--r--conf.c28
-rw-r--r--cwmrc.56
-rw-r--r--menu.c7
-rw-r--r--mousefunc.c4
-rw-r--r--screen.c2
-rw-r--r--xevents.c8
-rw-r--r--xutil.c35
10 files changed, 100 insertions, 85 deletions
diff --git a/calmwm.c b/calmwm.c
index 1ee349e..929fb12 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -38,12 +38,6 @@
 char				**cwm_argv;
 Display				*X_Dpy;
 
-Cursor				 Cursor_default;
-Cursor				 Cursor_move;
-Cursor				 Cursor_normal;
-Cursor				 Cursor_question;
-Cursor				 Cursor_resize;
-
 struct screen_ctx_q		 Screenq = TAILQ_HEAD_INITIALIZER(Screenq);
 struct client_ctx_q		 Clientq = TAILQ_HEAD_INITIALIZER(Clientq);
 
@@ -52,11 +46,10 @@ struct conf			 Conf;
 char				*homedir;
 
 static void	sigchld_cb(int);
-static void	dpy_init(const char *);
 static int	x_errorhandler(Display *, XErrorEvent *);
-static int	x_wmerrorhandler(Display *, XErrorEvent *);
-static void	x_setup(void);
+static void	x_init(const char *);
 static void	x_teardown(void);
+static int	x_wmerrorhandler(Display *, XErrorEvent *);
 
 int
 main(int argc, char **argv)
@@ -109,15 +102,13 @@ main(int argc, char **argv)
 		conf_path = NULL;
 	}
 
-	dpy_init(display_name);
 
 	conf_init(&Conf);
 	if (conf_path && (parse_config(conf_path, &Conf) == -1))
 		warnx("config file %s has errors, not loading", conf_path);
 	free(conf_path);
 
-	xu_getatoms();
-	x_setup();
+	x_init(display_name);
 	xev_loop();
 	x_teardown();
 
@@ -125,7 +116,7 @@ main(int argc, char **argv)
 }
 
 static void
-dpy_init(const char *dpyname)
+x_init(const char *dpyname)
 {
 	int	i;
 
@@ -139,18 +130,10 @@ dpy_init(const char *dpyname)
 	XSetErrorHandler(x_errorhandler);
 
 	HasRandr = XRRQueryExtension(X_Dpy, &Randr_ev, &i);
-}
 
-static void
-x_setup(void)
-{
-	int			 i;
+	xu_getatoms();
 
-	Cursor_default = XCreateFontCursor(X_Dpy, XC_X_cursor);
-	Cursor_move = XCreateFontCursor(X_Dpy, XC_fleur);
-	Cursor_normal = XCreateFontCursor(X_Dpy, XC_left_ptr);
-	Cursor_question = XCreateFontCursor(X_Dpy, XC_question_arrow);
-	Cursor_resize = XCreateFontCursor(X_Dpy, XC_bottom_right_corner);
+	conf_cursor(&Conf);
 
 	for (i = 0; i < ScreenCount(X_Dpy); i++)
 		screen_init(i);
diff --git a/calmwm.h b/calmwm.h
index d5119b1..3e40b88 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -97,6 +97,15 @@ union arg {
 	int	 i;
 };
 
+enum cursor_font {
+	CF_DEFAULT,
+	CF_MOVE,
+	CF_NORMAL,
+	CF_QUESTION,
+	CF_RESIZE,
+	CF_NITEMS
+};
+
 enum color {
 	CWM_COLOR_BORDER_ACTIVE,
 	CWM_COLOR_BORDER_INACTIVE,
@@ -306,6 +315,7 @@ struct conf {
 	char			 known_hosts[MAXPATHLEN];
 #define	CONF_FONT			"sans-serif:pixelsize=14:bold"
 	char			*font;
+	Cursor			 cursor[CF_NITEMS];
 };
 
 /* MWM hints */
@@ -323,6 +333,7 @@ struct mwm_hints {
 __dead void		 usage(void);
 
 void			 client_applysizehints(struct client_ctx *);
+void			 client_config(struct client_ctx *);
 struct client_ctx	*client_current(void);
 void			 client_cycle(struct screen_ctx *, int);
 void			 client_cycle_leave(struct screen_ctx *,
@@ -339,6 +350,7 @@ void			 client_leave(struct client_ctx *);
 void			 client_lower(struct client_ctx *);
 void			 client_map(struct client_ctx *);
 void			 client_maximize(struct client_ctx *);
+void			 client_msg(struct client_ctx *, Atom);
 void			 client_move(struct client_ctx *);
 struct client_ctx	*client_init(Window, struct screen_ctx *, int);
 void			 client_ptrsave(struct client_ctx *);
@@ -447,6 +459,7 @@ void			 conf_bindname(struct conf *, char *, char *);
 void			 conf_clear(struct conf *);
 void			 conf_client(struct client_ctx *);
 void			 conf_cmd_add(struct conf *, char *, char *);
+void			 conf_cursor(struct conf *);
 void			 conf_grab_kbd(Window);
 void			 conf_grab_mouse(Window);
 void			 conf_init(struct conf *);
@@ -458,7 +471,6 @@ void			 xev_loop(void);
 
 void			 xu_btn_grab(Window, int, u_int);
 void			 xu_btn_ungrab(Window, int, u_int);
-void			 xu_configure(struct client_ctx *);
 void			 xu_getatoms(void);
 int			 xu_getprop(Window, Atom, Atom, long, u_char **);
 int			 xu_get_wm_state(Window, int *);
@@ -469,7 +481,6 @@ int			 xu_ptr_grab(Window, u_int, Cursor);
 int			 xu_ptr_regrab(u_int, Cursor);
 void			 xu_ptr_setpos(Window, int, int);
 void			 xu_ptr_ungrab(void);
-void			 xu_sendmsg(Window, Atom, Atom);
 void			 xu_set_wm_state(Window win, int);
 void			 xu_xft_draw(struct screen_ctx *, const char *,
 			     int, int, int);
@@ -510,12 +521,6 @@ int			 xasprintf(char **, const char *, ...)
 /* Externs */
 extern Display				*X_Dpy;
 
-extern Cursor				 Cursor_default;
-extern Cursor				 Cursor_move;
-extern Cursor				 Cursor_normal;
-extern Cursor				 Cursor_question;
-extern Cursor				 Cursor_resize;
-
 extern struct screen_ctx_q		 Screenq;
 extern struct client_ctx_q		 Clientq;
 extern struct conf			 Conf;
diff --git a/client.c b/client.c
index cfa253b..da943ea 100644
--- a/client.c
+++ b/client.c
@@ -123,7 +123,7 @@ client_init(Window win, struct screen_ctx *sc, int mapped)
 	client_transient(cc);
 
 	/* Notify client of its configuration. */
-	xu_configure(cc);
+	client_config(cc);
 
 	(state == IconicState) ? client_hide(cc) : client_unhide(cc);
 
@@ -400,14 +400,14 @@ client_resize(struct client_ctx *cc, int reset)
 
 	XMoveResizeWindow(X_Dpy, cc->win, cc->geom.x,
 	    cc->geom.y, cc->geom.w, cc->geom.h);
-	xu_configure(cc);
+	client_config(cc);
 }
 
 void
 client_move(struct client_ctx *cc)
 {
 	XMoveWindow(X_Dpy, cc->win, cc->geom.x, cc->geom.y);
-	xu_configure(cc);
+	client_config(cc);
 }
 
 void
@@ -423,6 +423,26 @@ client_raise(struct client_ctx *cc)
 }
 
 void
+client_config(struct client_ctx *cc)
+{
+	XConfigureEvent	 cn;
+
+	bzero(&cn, sizeof(cn));
+	cn.type = ConfigureNotify;
+	cn.event = cc->win;
+	cn.window = cc->win;
+	cn.x = cc->geom.x;
+	cn.y = cc->geom.y;
+	cn.width = cc->geom.w;
+	cn.height = cc->geom.h;
+	cn.border_width = cc->bwidth;
+	cn.above = None;
+	cn.override_redirect = 0;
+
+	XSendEvent(X_Dpy, cc->win, False, StructureNotifyMask, (XEvent *)&cn);
+}
+
+void
 client_ptrwarp(struct client_ctx *cc)
 {
 	int	 x = cc->ptr.x, y = cc->ptr.y;
@@ -519,11 +539,26 @@ client_wm_protocols(struct client_ctx *cc)
 }
 
 void
+client_msg(struct client_ctx *cc, Atom proto)
+{
+	XClientMessageEvent	 cm;
+
+	bzero(&cm, sizeof(cm));
+	cm.type = ClientMessage;
+	cm.window = cc->win;
+	cm.message_type = cwmh[WM_PROTOCOLS].atom;
+	cm.format = 32;
+	cm.data.l[0] = proto;
+	cm.data.l[1] = CurrentTime;
+
+	XSendEvent(X_Dpy, cc->win, False, NoEventMask, (XEvent *)&cm);
+}
+
+void
 client_send_delete(struct client_ctx *cc)
 {
 	if (cc->xproto & _WM_DELETE_WINDOW)
-		xu_sendmsg(cc->win,
-		    cwmh[WM_PROTOCOLS].atom, cwmh[WM_DELETE_WINDOW].atom);
+		client_msg(cc, cwmh[WM_DELETE_WINDOW].atom);
 	else
 		XKillClient(X_Dpy, cc->win);
 }
diff --git a/conf.c b/conf.c
index 7c4f77d..c6cc3bd 100644
--- a/conf.c
+++ b/conf.c
@@ -121,7 +121,7 @@ conf_screen(struct screen_ctx *sc)
 		}
 	}
 	if (i == CWM_COLOR_MAX)
-		return;
+		goto out;
 
 	xu_xorcolor(sc->xftcolor[CWM_COLOR_MENU_BG],
 		    sc->xftcolor[CWM_COLOR_MENU_FG], &xc);
@@ -129,7 +129,7 @@ conf_screen(struct screen_ctx *sc)
 	if (!XftColorAllocValue(X_Dpy, sc->visual, sc->colormap,
 	    &xc.color, &sc->xftcolor[CWM_COLOR_MENU_FONT_SEL]))
 		warnx("XftColorAllocValue: '%s'", Conf.color[i]);
-
+out:
 	sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
 	    Conf.bwidth,
 	    sc->xftcolor[CWM_COLOR_MENU_FG].pixel,
@@ -545,7 +545,9 @@ static struct {
 	{ "menu_cmd", mousefunc_menu_cmd, MOUSEBIND_CTX_ROOT },
 };
 
-static unsigned int mouse_btns[] = { Button1, Button2, Button3 };
+static unsigned int mouse_btns[] = {
+	Button1, Button2, Button3, Button4, Button5
+};
 
 int
 conf_mousebind(struct conf *c, char *name, char *binding)
@@ -571,7 +573,7 @@ conf_mousebind(struct conf *c, char *name, char *binding)
 	} else
 		substring = name;
 
-	button = strtonum(substring, 1, 3, &errstr);
+	button = strtonum(substring, 1, 5, &errstr);
 	if (errstr)
 		warnx("button number is %s: %s", errstr, substring);
 
@@ -623,6 +625,23 @@ conf_mouseunbind(struct conf *c, struct mousebinding *unbind)
 	}
 }
 
+static int cursor_binds[CF_NITEMS] = {
+	XC_X_cursor,		/* CF_DEFAULT */
+	XC_fleur,		/* CF_MOVE */
+	XC_left_ptr,		/* CF_NORMAL */
+	XC_question_arrow,	/* CF_QUESTION */
+	XC_bottom_right_corner,	/* CF_RESIZE */
+};
+
+void
+conf_cursor(struct conf *c)
+{
+	u_int	 i;
+
+	for (i = 0; i < nitems(cursor_binds); i++)
+		c->cursor[i] = XCreateFontCursor(X_Dpy, cursor_binds[i]);
+}
+
 void
 conf_grab_mouse(Window win)
 {
@@ -645,4 +664,3 @@ conf_grab_kbd(Window win)
 	TAILQ_FOREACH(kb, &Conf.keybindingq, entry)
 		xu_key_grab(win, kb->modmask, kb->keysym);
 }
-
diff --git a/cwmrc.5 b/cwmrc.5
index b475d5e..68803ad 100644
--- a/cwmrc.5
+++ b/cwmrc.5
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: December 17 2012 $
+.Dd $Mdocdate: January 8 2013 $
 .Dt CWMRC 5
 .Os
 .Sh NAME
@@ -206,6 +206,10 @@ Left mouse button.
 Middle mouse button.
 .It 3
 Right mouse button.
+.It 4
+Scroll up mouse button.
+.It 5
+Scroll down mouse button.
 .El
 .Pp
 The
diff --git a/menu.c b/menu.c
index d610945..6277595 100644
--- a/menu.c
+++ b/menu.c
@@ -122,7 +122,8 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
 	XSelectInput(X_Dpy, sc->menuwin, evmask);
 	XMapRaised(X_Dpy, sc->menuwin);
 
-	if (xu_ptr_grab(sc->menuwin, MENUGRABMASK, Cursor_question) < 0) {
+	if (xu_ptr_grab(sc->menuwin, MENUGRABMASK,
+	    Conf.cursor[CF_QUESTION]) < 0) {
 		XUnmapWindow(X_Dpy, sc->menuwin);
 		return (NULL);
 	}
@@ -472,10 +473,10 @@ menu_handle_move(XEvent *e, struct menu_ctx *mc, struct menu_q *resultq)
 	if (mc->prev != -1)
 		menu_draw_entry(mc, resultq, mc->prev, 0);
 	if (mc->entry != -1) {
-		(void)xu_ptr_regrab(MENUGRABMASK, Cursor_normal);
+		(void)xu_ptr_regrab(MENUGRABMASK, Conf.cursor[CF_NORMAL]);
 		menu_draw_entry(mc, resultq, mc->entry, 1);
 	} else
-		(void)xu_ptr_regrab(MENUGRABMASK, Cursor_default);
+		(void)xu_ptr_regrab(MENUGRABMASK, Conf.cursor[CF_DEFAULT]);
 
 	if (mc->hasprompt)
 		menu_draw_entry(mc, resultq, 1, 1);
diff --git a/mousefunc.c b/mousefunc.c
index 9305633..158a791 100644
--- a/mousefunc.c
+++ b/mousefunc.c
@@ -81,7 +81,7 @@ mousefunc_window_resize(struct client_ctx *cc, void *arg)
 	client_raise(cc);
 	client_ptrsave(cc);
 
-	if (xu_ptr_grab(cc->win, MOUSEMASK, Cursor_resize) < 0)
+	if (xu_ptr_grab(cc->win, MOUSEMASK, Conf.cursor[CF_RESIZE]) < 0)
 		return;
 
 	xu_ptr_setpos(cc->win, cc->geom.w, cc->geom.h);
@@ -137,7 +137,7 @@ mousefunc_window_move(struct client_ctx *cc, void *arg)
 	if (cc->flags & CLIENT_FREEZE)
 		return;
 
-	if (xu_ptr_grab(cc->win, MOUSEMASK, Cursor_move) < 0)
+	if (xu_ptr_grab(cc->win, MOUSEMASK, Conf.cursor[CF_MOVE]) < 0)
 		return;
 
 	xu_ptr_getpos(cc->win, &px, &py);
diff --git a/screen.c b/screen.c
index 14e7608..e006374 100644
--- a/screen.c
+++ b/screen.c
@@ -57,7 +57,7 @@ screen_init(int which)
 
 	group_init(sc);
 
-	rootattr.cursor = Cursor_normal;
+	rootattr.cursor = Conf.cursor[CF_NORMAL];
 	rootattr.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|
 	    PropertyChangeMask|EnterWindowMask|LeaveWindowMask|
 	    ColormapChangeMask|BUTTONMASK;
diff --git a/xevents.c b/xevents.c
index 9c42737..8ad036b 100644
--- a/xevents.c
+++ b/xevents.c
@@ -150,7 +150,11 @@ xev_handle_configurerequest(XEvent *ee)
 		if (e->value_mask & CWY)
 			cc->geom.y = e->y;
 		if (e->value_mask & CWBorderWidth)
-			wc.border_width = e->border_width;
+			cc->bwidth = e->border_width;
+		if (e->value_mask & CWSibling)
+			wc.sibling = e->above;
+		if (e->value_mask & CWStackMode)
+			wc.stack_mode = e->detail;
 
 		if (cc->geom.x == 0 && cc->geom.w >= sc->view.w)
 			cc->geom.x -= cc->bwidth;
@@ -165,7 +169,7 @@ xev_handle_configurerequest(XEvent *ee)
 		wc.border_width = cc->bwidth;
 
 		XConfigureWindow(X_Dpy, cc->win, e->value_mask, &wc);
-		xu_configure(cc);
+		client_config(cc);
 	} else {
 		/* let it do what it wants, it'll be ours when we map it. */
 		wc.x = e->x;
diff --git a/xutil.c b/xutil.c
index df5fc4f..7145683 100644
--- a/xutil.c
+++ b/xutil.c
@@ -105,41 +105,6 @@ xu_key_grab(Window win, u_int mask, KeySym keysym)
 		    True, GrabModeAsync, GrabModeAsync);
 }
 
-void
-xu_configure(struct client_ctx *cc)
-{
-	XConfigureEvent	 ce;
-
-	ce.type = ConfigureNotify;
-	ce.event = cc->win;
-	ce.window = cc->win;
-	ce.x = cc->geom.x;
-	ce.y = cc->geom.y;
-	ce.width = cc->geom.w;
-	ce.height = cc->geom.h;
-	ce.border_width = cc->bwidth;
-	ce.above = None;
-	ce.override_redirect = 0;
-
-	XSendEvent(X_Dpy, cc->win, False, StructureNotifyMask, (XEvent *)&ce);
-}
-
-void
-xu_sendmsg(Window win, Atom type, Atom atm)
-{
-	XClientMessageEvent	 e;
-
-	bzero(&e, sizeof(e));
-	e.type = ClientMessage;
-	e.window = win;
-	e.message_type = type;
-	e.format = 32;
-	e.data.l[0] = atm;
-	e.data.l[1] = CurrentTime;
-
-	XSendEvent(X_Dpy, win, False, 0L, (XEvent *)&e);
-}
-
 int
 xu_getprop(Window win, Atom atm, Atom type, long len, u_char **p)
 {