"-misc-fixed-medium-r-*-*-*-*-*-*-*-*-*-*," \
"-*-*-*-r-*--*-*-*-*-*-*-*-*"
-#define PSC '/' /* path separator char */
-
char *bar_argv[] = { NULL, NULL };
int bar_pipe[2];
unsigned char bar_ext[SWM_BAR_MAX];
/* function prototypes */
void buttonpress(xcb_button_press_event_t *);
+void check_conn(void);
void clientmessage(xcb_client_message_event_t *);
int conf_load(char *, int);
void configurenotify(xcb_configure_notify_event_t *);
char *
expand_tilde(char *s)
{
- struct passwd *pwd;
- int i;
- char user[LOGIN_NAME_MAX];
+ struct passwd *ppwd;
+ int i, max;
+ char *user;
const char *sc = s;
char *result;
}
++s;
- for (i = 0; s[i] != PSC && s[i] != '\0'; ++i)
+
+ if ((max = sysconf(_SC_LOGIN_NAME_MAX)) == -1)
+ errx(1, "expand_tilde: sysconf");
+
+ if ((user = calloc(1, max + 1)) == NULL)
+ errx(1, "expand_tilde: calloc");
+
+ for (i = 0; s[i] != '/' && s[i] != '\0'; ++i)
user[i] = s[i];
user[i] = '\0';
s = &s[i];
- pwd = strlen(user) == 0 ? getpwuid(getuid()) : getpwnam(user);
- if (pwd == NULL)
+ ppwd = strlen(user) == 0 ? getpwuid(getuid()) : getpwnam(user);
+ if (ppwd == NULL)
result = strdup(sc);
else
- if (asprintf(&result, "%s%s", pwd->pw_dir, s) == -1)
+ if (asprintf(&result, "%s%s", ppwd->pw_dir, s) == -1)
result = NULL;
out:
if (result == NULL)
xcb_screen_t *
get_screen(int screen)
{
- xcb_screen_iterator_t i;
+ const xcb_setup_t *r;
+ xcb_screen_iterator_t iter;
- i = xcb_setup_roots_iterator(xcb_get_setup(conn));
- for (; i.rem; --screen, xcb_screen_next(&i))
+ if ((r = xcb_get_setup(conn)) == NULL) {
+ DNPRINTF(SWM_D_MISC, "get_screen: xcb_get_setup\n");
+ check_conn();
+ }
+
+ iter = xcb_setup_roots_iterator(r);
+ for (; iter.rem; --screen, xcb_screen_next(&iter))
if (screen == 0)
- return (i.data);
+ return (iter.data);
return (NULL);
}
sidx, num_screens);
sidx--;
- screen = get_screen(sidx);
+ if ((screen = get_screen(sidx)) == NULL)
+ errx(1, "ERROR: can't get screen %d.", sidx);
+
if (w < 1 || h < 1)
errx(1, "region %ux%u+%u+%u too small", w, h, x, y);
void
bar_setup(struct swm_region *r)
{
- char *font, *fontpos, *dup, *search;
+ char *font, *fontpos, *d, *search;
int count;
- xcb_screen_t *screen = get_screen(r->s->idx);
+ xcb_screen_t *screen;
uint32_t wa[3];
XRenderColor color;
+ if ((screen = get_screen(r->s->idx)) == NULL)
+ errx(1, "ERROR: can't get screen %d.", r->s->idx);
+
if (r->bar != NULL)
return;
err(1, "bar_setup: calloc: failed to allocate memory.");
if (bar_font == NULL) {
- if ((dup = strdup(bar_fonts)) == NULL)
+ if ((d = strdup(bar_fonts)) == NULL)
errx(1, "insufficient memory.");
- search = dup;
+ search = d;
while ((font = strsep(&search, ",")) != NULL) {
if (*font == '\0')
continue;
break;
}
}
- free(dup);
+ free(d);
}
if (bar_font == NULL)
xcb_create_pixmap(conn, screen->root_depth, r->bar->buffer, r->bar->id,
WIDTH(r->bar), HEIGHT(r->bar));
- xcb_randr_select_input(conn, r->bar->id,
- XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE);
+ if (xrandr_support)
+ xcb_randr_select_input(conn, r->bar->id,
+ XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE);
if (bar_enabled)
map_window_raised(r->bar->id);
{
char *cp, *class, *name;
int retval;
- unsigned long quirks;
+ unsigned long qrks;
/* suppress unused warning since var is needed */
(void)flags;
*cp = '\0';
class = selector;
name = cp + 1;
- if ((retval = parsequirks(value, &quirks)) == 0)
- setquirk(class, name, quirks);
+ if ((retval = parsequirks(value, &qrks)) == 0)
+ setquirk(class, name, qrks);
return (retval);
}
int
setlayout(char *selector, char *value, int flags)
{
- int ws_id, i, x, mg, ma, si, raise, f = 0;
+ int ws_id, i, x, mg, ma, si, ar, f = 0;
int st = SWM_V_STACK, num_screens;
char s[1024];
struct workspace *ws;
bzero(s, sizeof s);
if (sscanf(value, "ws[%d]:%d:%d:%d:%d:%1023c",
- &ws_id, &mg, &ma, &si, &raise, s) != 6)
+ &ws_id, &mg, &ma, &si, &ar, s) != 6)
errx(1, "invalid layout entry, should be 'ws[<idx>]:"
"<master_grow>:<master_add>:<stack_inc>:<always_raise>:"
"<type>'");
ws = (struct workspace *)&screens[i].ws;
ws[ws_id].cur_layout = &layouts[st];
- ws[ws_id].always_raise = raise;
+ ws[ws_id].always_raise = ar;
if (st == SWM_MAX_STACK)
continue;
FILE *config;
char *line, *cp, *optsub, *optval;
size_t linelen, lineno = 0;
- int wordlen, i, optind;
+ int wordlen, i, optidx;
struct config_option *opt;
DNPRINTF(SWM_D_CONF, "conf_load: begin\n");
filename, lineno);
goto out;
}
- optind = -1;
+ optidx = -1;
for (i = 0; i < LENGTH(configopt); i++) {
opt = &configopt[i];
if (!strncasecmp(cp, opt->optname, wordlen) &&
(int)strlen(opt->optname) == wordlen) {
- optind = i;
+ optidx = i;
break;
}
}
- if (optind == -1) {
+ if (optidx == -1) {
warnx("%s: line %zd: unknown option %.*s",
filename, lineno, wordlen, cp);
goto out;
/* get RHS value */
optval = strdup(cp);
/* call function to deal with it all */
- if (configopt[optind].func(optsub, optval,
- configopt[optind].funcflags) != 0)
+ if (configopt[optidx].func(optsub, optval,
+ configopt[optidx].funcflags) != 0)
errx(1, "%s: line %zd: invalid data for %s",
- filename, lineno, configopt[optind].optname);
+ filename, lineno, configopt[optidx].optname);
free(optval);
free(optsub);
free(line);
struct quirk *qp;
uint32_t event_mask, i;
xcb_icccm_get_wm_protocols_reply_t wpr;
- xcb_icccm_get_wm_class_reply_t tmpch;
if ((win = find_window(id)) != NULL)
return (win); /* already being managed */
if (xcb_icccm_get_wm_class_reply(conn,
xcb_icccm_get_wm_class(conn, win->id),
- &tmpch, NULL)) {
- win->ch.class_name = tmpch.class_name;
- win->ch.instance_name = tmpch.instance_name;
-
- xcb_icccm_get_wm_class_reply_wipe(&tmpch);
-
+ &win->ch, NULL)) {
DNPRINTF(SWM_D_CLASS, "manage_window: class: %s, name: %s\n",
win->ch.class_name, win->ch.instance_name);
if (win->wa)
free(win->wa);
+ xcb_icccm_get_wm_class_reply_wipe(&win->ch);
+
kill_refs(win);
/* paint memory */
void
leavenotify(xcb_leave_notify_event_t *e)
{
- struct ws_win *win;
DNPRINTF(SWM_D_FOCUS, "leavenotify: window: 0x%x, mode: %s(%d), "
"detail: %s(%d), root: 0x%x, subwindow: 0x%x, same_screen_focus: "
"%s, state: %d\n", e->event, get_notify_mode_label(e->mode),
xcb_flush(conn);
}
+void
+check_conn(void)
+{
+ int errcode = xcb_connection_has_error(conn);
+#ifdef XCB_CONN_ERROR
+ char *s;
+ switch (errcode) {
+ case XCB_CONN_ERROR:
+ s = "Socket error, pipe error or other stream error.";
+ break;
+ case XCB_CONN_CLOSED_EXT_NOTSUPPORTED:
+ s = "Extension not supported.";
+ break;
+ case XCB_CONN_CLOSED_MEM_INSUFFICIENT:
+ s = "Insufficient memory.";
+ break;
+ case XCB_CONN_CLOSED_REQ_LEN_EXCEED:
+ s = "Request length was exceeded.";
+ break;
+ case XCB_CONN_CLOSED_PARSE_ERR:
+ s = "Error parsing display string.";
+ break;
+ default:
+ s = "Unknown error.";
+ }
+ if (errcode)
+ errx(errcode, "X CONNECTION ERROR: %s", s);
+#else
+ if (errcode)
+ errx(errcode, "X CONNECTION ERROR");
+#endif
+}
+
int
enable_wm(void)
{
/* this causes an error if some other window manager is running */
num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
for (i = 0; i < num_screens; i++) {
- sc = get_screen(i);
+ if ((sc = get_screen(i)) == NULL)
+ errx(1, "ERROR: can't get screen %d.", i);
DNPRINTF(SWM_D_INIT, "enable_wm: screen %d, root: 0x%x\n",
i, sc->root);
wac = xcb_change_window_attributes_checked(conn, sc->root,
xcb_randr_get_crtc_info_cookie_t cic;
xcb_randr_get_crtc_info_reply_t *cir = NULL;
xcb_randr_crtc_t *crtc;
- xcb_screen_t *screen = get_screen(i);
+ xcb_screen_t *screen;
+
+ if ((screen = get_screen(i)) == NULL)
+ errx(1, "ERROR: can't get screen %d.", i);
num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
if (i >= num_screens)
struct workspace *ws;
uint32_t gcv[1], wa[1];
const xcb_query_extension_reply_t *qep;
+ xcb_screen_t *screen;
xcb_cursor_t cursor;
xcb_font_t cursor_font;
xcb_randr_query_version_cookie_t c;
/* initial Xrandr setup */
xrandr_support = 0;
- c = xcb_randr_query_version(conn, 1, 1);
- r = xcb_randr_query_version_reply(conn, c, NULL);
- if (r) {
- if (r->major_version >= 1)
- xrandr_support = 1;
- free(r);
- }
qep = xcb_get_extension_data(conn, &xcb_randr_id);
- xrandr_eventbase = qep->first_event;
+ if (qep->present) {
+ c = xcb_randr_query_version(conn, 1, 1);
+ r = xcb_randr_query_version_reply(conn, c, NULL);
+ if (r) {
+ if (r->major_version >= 1) {
+ xrandr_support = 1;
+ xrandr_eventbase = qep->first_event;
+ }
+ free(r);
+ }
+ }
cursor_font = xcb_generate_id(conn);
xcb_open_font(conn, cursor_font, strlen("cursor"), "cursor");
screens[i].idx = i;
TAILQ_INIT(&screens[i].rl);
TAILQ_INIT(&screens[i].orl);
- screens[i].root = get_screen(i)->root;
+ if ((screen = get_screen(i)) == NULL)
+ errx(1, "ERROR: can't get screen %d.", i);
+ screens[i].root = screen->root;
/* set default colors */
setscreencolor("red", i + 1, SWM_S_COLOR_FOCUS);