X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=6e88cdd0ece3f161de141d45a437b5a9b8c9008f;hb=25360b61720c1fc74f2bd5051f08e1212df77c9b;hp=e4f2cce9246ea1f7427eb8164f09f1d485f9847f;hpb=413ba7b518382e9f5a726988e98fc86f6a94528b;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index e4f2cce..6e88cdd 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -329,8 +329,6 @@ double dialog_ratio = 0.6; "-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]; @@ -651,6 +649,7 @@ struct ewmh_hint { /* 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 *); @@ -702,9 +701,9 @@ void update_window(struct ws_win *); 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; @@ -717,16 +716,23 @@ expand_tilde(char *s) } ++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) @@ -753,12 +759,18 @@ parse_rgb(const char *rgb, uint16_t *rr, uint16_t *gg, uint16_t *bb) 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); } @@ -997,7 +1009,7 @@ ewmh_update_actions(struct ws_win *win) #define _NET_WM_STATE_TOGGLE 2 /* toggle property */ void -ewmh_update_win_state(struct ws_win *win, long state, long action) +ewmh_update_win_state(struct ws_win *win, xcb_atom_t state, long action) { unsigned int mask = 0; unsigned int changed = 0; @@ -1342,7 +1354,9 @@ custom_region(char *val) 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); @@ -1894,12 +1908,15 @@ bar_refresh(void) 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; @@ -1907,9 +1924,9 @@ bar_setup(struct swm_region *r) 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; @@ -1938,7 +1955,7 @@ bar_setup(struct swm_region *r) break; } } - free(dup); + free(d); } if (bar_font == NULL) @@ -1975,8 +1992,9 @@ bar_setup(struct swm_region *r) 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); @@ -5762,7 +5780,7 @@ setconfquirk(char *selector, char *value, int flags) { char *cp, *class, *name; int retval; - unsigned long quirks; + unsigned long qrks; /* suppress unused warning since var is needed */ (void)flags; @@ -5774,8 +5792,8 @@ setconfquirk(char *selector, char *value, int 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); } @@ -6121,7 +6139,7 @@ setautorun(char *selector, char *value, int flags) 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; @@ -6135,7 +6153,7 @@ setlayout(char *selector, char *value, int flags) 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[]:" "::::" "'"); @@ -6165,7 +6183,7 @@ setlayout(char *selector, char *value, int flags) 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; @@ -6261,7 +6279,7 @@ conf_load(char *filename, int keymapping) 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"); @@ -6297,16 +6315,16 @@ conf_load(char *filename, int keymapping) 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; @@ -6345,10 +6363,10 @@ conf_load(char *filename, int keymapping) /* 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); @@ -6507,7 +6525,6 @@ manage_window(xcb_window_t id) 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 */ @@ -6673,12 +6690,7 @@ manage_window(xcb_window_t id) 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); @@ -6761,6 +6773,8 @@ free_window(struct ws_win *win) if (win->wa) free(win->wa); + xcb_icccm_get_wm_class_reply_wipe(&win->ch); + kill_refs(win); /* paint memory */ @@ -7157,7 +7171,6 @@ enternotify(xcb_enter_notify_event_t *e) 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), @@ -7394,6 +7407,39 @@ clientmessage(xcb_client_message_event_t *e) 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) { @@ -7406,7 +7452,8 @@ 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, @@ -7511,7 +7558,10 @@ scan_xrandr(int i) 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) @@ -7679,6 +7729,7 @@ setup_screens(void) 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; @@ -7692,15 +7743,18 @@ setup_screens(void) /* 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"); @@ -7716,7 +7770,9 @@ setup_screens(void) 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);