JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
more readable loop. also fixes minor memleak
[spectrwm.git] / spectrwm.c
index 2a0f8a9..cf5304c 100644 (file)
@@ -124,10 +124,13 @@ static const char *buildstr = SPECTRWM_VERSION;
 #if defined(__OpenBSD__)
 #define xcb_icccm_wm_hints_t                   xcb_wm_hints_t
 #define xcb_icccm_get_wm_hints                 xcb_get_wm_hints
+#define xcb_icccm_get_wm_hints_reply           xcb_get_wm_hints_reply
 #define XCB_ICCCM_WM_HINT_X_URGENCY            XCB_WM_HINT_X_URGENCY
 #define XCB_ICCCM_WM_STATE_ICONIC              XCB_WM_STATE_ICONIC
 #define XCB_ICCCM_WM_STATE_WITHDRAWN           XCB_WM_STATE_WITHDRAWN
 #define XCB_ICCCM_WM_STATE_NORMAL              XCB_WM_STATE_NORMAL
+#define        xcb_icccm_get_wm_name                   xcb_get_wm_name
+#define xcb_icccm_get_wm_name_reply            xcb_get_wm_name_reply
 #define xcb_icccm_get_wm_transient_for         xcb_get_wm_transient_for
 #define xcb_icccm_get_wm_transient_for_reply   xcb_get_wm_transient_for_reply
 #endif
@@ -636,10 +639,24 @@ int                floating_toggle_win(struct ws_win *);
 void            constrain_window(struct ws_win *, struct swm_region *, int);
 void            update_window(struct ws_win *);
 void            spawn_select(struct swm_region *, union arg *, char *, int *);
-unsigned char  *get_win_name(xcb_window_t);
+char           *get_win_name(xcb_window_t);
 xcb_atom_t      get_atom_from_string(const char *);
 void           map_window_raised(xcb_window_t);
 void           do_sync(void);
+xcb_screen_t   *get_screen(int);
+
+xcb_screen_t *
+get_screen(int screen)
+{
+       xcb_screen_iterator_t i;
+
+       i = xcb_setup_roots_iterator(xcb_get_setup(conn));
+       for (; i.rem; --screen, xcb_screen_next(&i))
+               if (screen == 0)
+                       return (i.data);
+
+       return (NULL);
+}
 
 void
 do_sync(void)
@@ -686,29 +703,6 @@ get_atom_from_string(const char *str)
        return (XCB_ATOM_NONE);
 }
 
-int
-get_property(Window id, Atom atom, long count, Atom type, unsigned long *nitems,
-    unsigned long *nbytes, unsigned char **data)
-{
-       int                     format, status;
-       unsigned long           *nbytes_ret, *nitems_ret;
-       unsigned long           nbytes_tmp, nitems_tmp;
-       Atom                    real;
-
-       nbytes_ret = nbytes != NULL ? nbytes : &nbytes_tmp;
-       nitems_ret = nitems != NULL ? nitems : &nitems_tmp;
-
-       status = XGetWindowProperty(display, id, atom, 0L, count, False, type,
-           &real, &format, nitems_ret, nbytes_ret, data);
-
-       if (status != Success)
-               return (False);
-       if (real != type)
-               return (False);
-
-       return (True);
-}
-
 void
 update_iconic(struct ws_win *win, int newv)
 {
@@ -1387,6 +1381,7 @@ custom_region(char *val)
 {
        unsigned int                    sidx, x, y, w, h;
        int                             num_screens;
+       xcb_screen_t                    *screen;
 
        num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
        if (sscanf(val, "screen[%u]:%ux%u+%u+%u", &sidx, &w, &h, &x, &y) != 5)
@@ -1397,16 +1392,17 @@ custom_region(char *val)
                    sidx, num_screens);
        sidx--;
 
+       screen = get_screen(sidx);
        if (w < 1 || h < 1)
                errx(1, "region %ux%u+%u+%u too small", w, h, x, y);
 
-       if (x > DisplayWidth(display, sidx) ||
-           y > DisplayHeight(display, sidx) ||
-           w + x > DisplayWidth(display, sidx) ||
-           h + y > DisplayHeight(display, sidx)) {
+       if (x > screen->width_in_pixels ||
+           y > screen->height_in_pixels ||
+           w + x > screen->width_in_pixels ||
+           h + y > screen->height_in_pixels) {
                warnx("ignoring region %ux%u+%u+%u - not within screen "
                    "boundaries (%ux%u)", w, h, x, y,
-                   DisplayWidth(display, sidx), DisplayHeight(display, sidx));
+                   screen->width_in_pixels, screen->height_in_pixels);
                return;
        }
 
@@ -1523,15 +1519,15 @@ bar_window_float(char *s, size_t sz, struct swm_region *r)
 void
 bar_window_name(char *s, size_t sz, struct swm_region *r)
 {
-       unsigned char           *title;
+       char            *title;
 
        if (r == NULL || r->ws == NULL || r->ws->focus == NULL)
                return;
        if ((title = get_win_name(r->ws->focus->id)) == NULL)
                return;
 
-       strlcat(s, (char *)title, sz);
-       XFree(title);
+       strlcat(s, title, sz);
+       free(title);
 }
 
 int            urgent[SWM_WS_MAX];
@@ -1924,6 +1920,7 @@ bar_setup(struct swm_region *r)
        char                    **missing_charsets;
        int                     num_missing_charsets = 0;
        int                     i;
+       xcb_screen_t            *screen = get_screen(r->s->idx);
 
        if (bar_fs) {
                XFreeFontSet(display, bar_fs);
@@ -1975,7 +1972,7 @@ bar_setup(struct swm_region *r)
            r->s->c[SWM_S_COLOR_BAR].color);
 
        r->bar->buffer = XCreatePixmap(display, r->bar->id, WIDTH(r->bar),
-           HEIGHT(r->bar), DefaultDepth(display, r->s->idx));
+           HEIGHT(r->bar), screen->root_depth);
 
        xcb_randr_select_input(conn, r->bar->id,
                XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE);
@@ -2243,11 +2240,11 @@ fake_keypress(struct ws_win *win, xcb_keysym_t keysym, uint16_t modifiers)
        event.state = modifiers;
 
        event.response_type = XCB_KEY_PRESS;
-       xcb_send_event(conn, win->id, True,
+       xcb_send_event(conn, True, win->id,
                 XCB_EVENT_MASK_KEY_PRESS, (char *)&event);
 
        event.response_type = XCB_KEY_RELEASE;
-       xcb_send_event(conn, win->id, True,
+       xcb_send_event(conn, True, win->id,
                XCB_EVENT_MASK_KEY_RELEASE, (char *)&event);
        xcb_flush(conn);
 
@@ -3732,29 +3729,27 @@ iconify(struct swm_region *r, union arg *args)
        focus(r, &a);
 }
 
-unsigned char *
+char *
 get_win_name(xcb_window_t win)
 {
-       unsigned char           *prop = NULL;
-       unsigned long           nbytes, nitems;
-
-       /* try _NET_WM_NAME first */
-       if (get_property(win, a_netwmname, 0L, a_utf8_string, NULL, &nbytes,
-           &prop)) {
-               XFree(prop);
-               if (get_property(win, a_netwmname, nbytes, a_utf8_string,
-                   &nitems, NULL, &prop))
-                       return (prop);
+       char                            *name = NULL;
+       xcb_get_property_cookie_t       c;
+       xcb_get_text_property_reply_t   r;
+
+       c = xcb_icccm_get_wm_name(conn, win);
+       if (xcb_icccm_get_wm_name_reply(conn, c, &r, NULL)) {
+               name = malloc(r.name_len + 1);
+               if (!name) {
+                       xcb_get_text_property_reply_wipe(&r);
+                       return (NULL);
+               }
+               memcpy(name, r.name, r.name_len);
+               name[r.name_len] = '\0';
        }
 
-       /* fallback to WM_NAME */
-       if (!get_property(win, a_wmname, 0L, a_string, NULL, &nbytes, &prop))
-               return (NULL);
-       XFree(prop);
-       if (get_property(win, a_wmname, nbytes, a_string, &nitems, NULL, &prop))
-               return (prop);
+       xcb_get_text_property_reply_wipe(&r);
 
-       return (NULL);
+       return (name);
 }
 
 void
@@ -3762,7 +3757,7 @@ uniconify(struct swm_region *r, union arg *args)
 {
        struct ws_win           *win;
        FILE                    *lfile;
-       unsigned char           *name;
+       char                    *name;
        int                     count = 0;
 
        DNPRINTF(SWM_D_MISC, "uniconify\n");
@@ -3799,7 +3794,7 @@ uniconify(struct swm_region *r, union arg *args)
                if (name == NULL)
                        continue;
                fprintf(lfile, "%s.%u\n", name, win->id);
-               XFree(name);
+               free(name);
        }
 
        fclose(lfile);
@@ -3943,7 +3938,7 @@ search_win(struct swm_region *r, union arg *args)
 void
 search_resp_uniconify(char *resp, unsigned long len)
 {
-       unsigned char           *name;
+       char                    *name;
        struct ws_win           *win;
        char                    *s;
 
@@ -3956,10 +3951,10 @@ search_resp_uniconify(char *resp, unsigned long len)
                if (name == NULL)
                        continue;
                if (asprintf(&s, "%s.%u", name, win->id) == -1) {
-                       XFree(name);
+                       free(name);
                        continue;
                }
-               XFree(name);
+               free(name);
                if (strncmp(s, resp, len) == 0) {
                        /* XXX this should be a callback to generalize */
                        update_iconic(win, 0);
@@ -7301,16 +7296,17 @@ void
 scan_xrandr(int i)
 {
 #ifdef SWM_XRR_HAS_CRTC
-       int                     c;
-       int                     ncrtc = 0;
+       int                                             c;
+       int                                             ncrtc = 0;
 #endif /* SWM_XRR_HAS_CRTC */
-       struct swm_region       *r;
-       int                     num_screens;
+       struct swm_region                               *r;
+       int                                             num_screens;
        xcb_randr_get_screen_resources_current_cookie_t src;
        xcb_randr_get_screen_resources_current_reply_t  *srr;
-       xcb_randr_get_crtc_info_cookie_t        cic;
-       xcb_randr_get_crtc_info_reply_t         *cir = NULL;
-       xcb_randr_crtc_t        *crtc;
+       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);
 
        num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
        if (i >= num_screens)
@@ -7332,37 +7328,40 @@ scan_xrandr(int i)
                        screens[i].root);
                srr = xcb_randr_get_screen_resources_current_reply(conn, src,
                        NULL);
-               if (srr == NULL)
+               if (srr == NULL) {
                        new_region(&screens[i], 0, 0,
-                           DisplayWidth(display, i),
-                           DisplayHeight(display, i));
-               else
+                           screen->width_in_pixels,
+                           screen->height_in_pixels);
+                       return;
+               } else
                        ncrtc = srr->num_crtcs;
                for (c = 0; c < ncrtc; c++) {
                        crtc = xcb_randr_get_screen_resources_current_crtcs(srr);
                        cic = xcb_randr_get_crtc_info(conn, crtc[c],
                                XCB_CURRENT_TIME);
                        cir = xcb_randr_get_crtc_info_reply(conn, cic, NULL);
-                       if (cir && cir->num_outputs == 0)
+                       if (cir == NULL)
                                continue;
+                       if (cir->num_outputs == 0) {
+                               free(cir);
+                               continue;
+                       }
 
-                       if (cir == NULL || cir->mode == 0)
+                       if (cir->mode == 0)
                                new_region(&screens[i], 0, 0,
-                                   DisplayWidth(display, i),
-                                   DisplayHeight(display, i));
+                                   screen->width_in_pixels,
+                                   screen->height_in_pixels);
                        else
                                new_region(&screens[i],
                                    cir->x, cir->y, cir->width, cir->height);
-               }
-               if (srr)
-                       free(srr);
-               if (cir)
                        free(cir);
+               }
+               free(srr);
        } else
 #endif /* SWM_XRR_HAS_CRTC */
        {
-               new_region(&screens[i], 0, 0, DisplayWidth(display, i),
-                   DisplayHeight(display, i));
+               new_region(&screens[i], 0, 0, screen->width_in_pixels,
+                   screen->height_in_pixels);
        }
 }