X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=0765bf908f39696a5214bf9491373dd071e7eee1;hb=acb9e292b97dd372eddb99c8ee3b93787bd94796;hp=b02b919814b4a432dbd39bd648fd18167e3e8203;hpb=fdefc1887cdf3f05d2453a31cc07bccd77b22d48;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index b02b919..0765bf9 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -92,6 +92,8 @@ #include #include #include +#include +#include #include #include #include @@ -122,18 +124,35 @@ static const char *buildstr = SPECTRWM_VERSION; #endif #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_SIZE_HINT_P_MIN_SIZE XCB_SIZE_HINT_P_MIN_SIZE +#define XCB_ICCCM_SIZE_HINT_P_MAX_SIZE XCB_SIZE_HINT_P_MAX_SIZE +#define XCB_ICCCM_SIZE_HINT_P_RESIZE_INC XCB_SIZE_HINT_P_RESIZE_INC #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_text_property_reply_t xcb_get_text_property_reply_t +#define xcb_icccm_get_text_property_reply_wipe xcb_get_text_property_reply_wipe +#define xcb_icccm_get_wm_class xcb_get_wm_class +#define xcb_icccm_get_wm_class_reply xcb_get_wm_class_reply +#define xcb_icccm_get_wm_class_reply_t xcb_get_wm_class_reply_t +#define xcb_icccm_get_wm_class_reply_wipe xcb_get_wm_class_reply_wipe +#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_get_wm_name xcb_get_wm_name +#define xcb_icccm_get_wm_name_reply xcb_get_wm_name_reply +#define xcb_icccm_get_wm_normal_hints xcb_get_wm_normal_hints +#define xcb_icccm_get_wm_normal_hints_reply xcb_get_wm_normal_hints_reply +#define xcb_icccm_get_wm_protocols xcb_get_wm_protocols +#define xcb_icccm_get_wm_protocols_reply xcb_get_wm_protocols_reply +#define xcb_icccm_get_wm_protocols_reply_t xcb_get_wm_protocols_reply_t +#define xcb_icccm_get_wm_protocols_reply_wipe xcb_get_wm_protocols_reply_wipe #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 +#define xcb_icccm_wm_hints_t xcb_wm_hints_t #endif -/*#define SWM_DEBUG*/ +#define SWM_DEBUG #ifdef SWM_DEBUG #define DPRINTF(x...) do { if (swm_debug) fprintf(stderr, x); } while (0) #define DNPRINTF(n,x...) do { if (swm_debug & n) fprintf(stderr, x); } while (0) @@ -191,13 +210,13 @@ u_int32_t swm_debug = 0 #define BORDER(w) (w->bordered ? border_width : 0) #define MAX_X(r) ((r)->g.x + (r)->g.w) #define MAX_Y(r) ((r)->g.y + (r)->g.h) -#define SH_MIN(w) (w)->sh_mask & PMinSize +#define SH_MIN(w) (w)->sh.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE #define SH_MIN_W(w) (w)->sh.min_width #define SH_MIN_H(w) (w)->sh.min_height -#define SH_MAX(w) (w)->sh_mask & PMaxSize +#define SH_MAX(w) (w)->sh.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE #define SH_MAX_W(w) (w)->sh.max_width #define SH_MAX_H(w) (w)->sh.max_height -#define SH_INC(w) (w)->sh_mask & PResizeInc +#define SH_INC(w) (w)->sh.flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC #define SH_INC_W(w) (w)->sh.width_inc #define SH_INC_H(w) (w)->sh.height_inc #define SWM_MAX_FONT_STEPS (3) @@ -237,6 +256,7 @@ int xrandr_eventbase; unsigned int numlockmask = 0; Display *display; xcb_connection_t *conn; +xcb_key_symbols_t *syms; int cycle_empty = 0; int cycle_visible = 0; @@ -256,7 +276,7 @@ struct search_window { TAILQ_ENTRY(search_window) entry; int idx; struct ws_win *win; - GC gc; + xcb_gcontext_t gc; xcb_window_t indicator; }; TAILQ_HEAD(search_winlist, search_window); @@ -290,12 +310,6 @@ double dialog_ratio = 0.6; "-misc-fixed-medium-r-*-*-*-*-*-*-*-*-*-*," \ "-*-*-*-r-*--*-*-*-*-*-*-*-*" -#ifdef X_HAVE_UTF8_STRING -#define DRAWSTRING(x...) Xutf8DrawString(x) -#else -#define DRAWSTRING(x...) XmbDrawString(x) -#endif - char *bar_argv[] = { NULL, NULL }; int bar_pipe[2]; unsigned char bar_ext[SWM_BAR_MAX]; @@ -378,7 +392,7 @@ struct ws_win { int floatmaxed; /* whether maxed by max_stack */ int floating; int manual; - int iconic; + int32_t iconic; int bordered; unsigned int ewmh_flags; int font_size_boundary[SWM_MAX_FONT_STEPS]; @@ -390,11 +404,10 @@ struct ws_win { unsigned long quirks; struct workspace *ws; /* always valid */ struct swm_screen *s; /* always valid, never changes */ - XWindowAttributes wa; - XSizeHints sh; - long sh_mask; - XClassHint ch; - XWMHints *hints; + xcb_get_geometry_reply_t *wa; + xcb_size_hints_t sh; + xcb_icccm_get_wm_class_reply_t ch; + xcb_icccm_wm_hints_t hints; }; TAILQ_HEAD(ws_win_list, ws_win); @@ -503,7 +516,7 @@ struct swm_screen { char *name; } c[SWM_S_COLOR_MAX]; - GC bar_gc; + xcb_gcontext_t bar_gc; }; struct swm_screen *screens; @@ -637,11 +650,28 @@ 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); +int parse_rgb(const char *, uint16_t *, uint16_t *, uint16_t *); +void event_handle(xcb_generic_event_t *); + +int +parse_rgb(const char *rgb, uint16_t *rr, uint16_t *gg, uint16_t *bb) +{ + unsigned int tmpr, tmpg, tmpb; + + if (sscanf(rgb, "rgb:%x/%x/%x", &tmpr, &tmpg, &tmpb) != 3) + return (-1); + + *rr = tmpr << 8; + *gg = tmpg << 8; + *bb = tmpb << 8; + + return (0); +} xcb_screen_t * get_screen(int screen) @@ -701,29 +731,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) { @@ -743,29 +750,28 @@ update_iconic(struct ws_win *win, int newv) xcb_delete_property(conn, win->id, iprop); } -int +int32_t get_iconic(struct ws_win *win) { - int32_t v = 0, *vtmp; + int32_t v = 0; xcb_atom_t iprop; - xcb_get_property_cookie_t pc; xcb_get_property_reply_t *pr = NULL; iprop = get_atom_from_string("_SWM_ICONIC"); if (iprop == XCB_ATOM_NONE) goto out; - pc = xcb_get_property(conn, False, win->id, iprop, XCB_ATOM_INTEGER, - 0, 1); - pr = xcb_get_property_reply(conn, pc, NULL); + pr = xcb_get_property_reply(conn, + xcb_get_property(conn, False, win->id, iprop, XCB_ATOM_INTEGER, + 0, 1), + NULL); if (!pr) goto out; if (pr->type != XCB_ATOM_INTEGER || pr->format != 32) goto out; - vtmp = xcb_get_property_value(pr); - v = *vtmp; + v = *((int32_t *)xcb_get_property_value(pr)); out: - if (pr != NULL) + if (pr) free(pr); return (v); } @@ -1026,10 +1032,10 @@ ewmh_get_win_state(struct ws_win *win) states = xcb_get_property_value(r); n = xcb_get_property_value_length(r); - free(r); - for (i = 0; i < n; i++) ewmh_update_win_state(win, states[i], _NET_WM_STATE_ADD); + + free(r); } /* events */ @@ -1146,22 +1152,6 @@ geteventname(XEvent *e) return (name); } -char * -xrandr_geteventname(XEvent *e) -{ - char *name = NULL; - - switch(e->type - xrandr_eventbase) { - case RRScreenChangeNotify: - name = "RRScreenChangeNotify"; - break; - default: - name = "Unknown"; - } - - return (name); -} - void dumpwins(struct swm_region *r, union arg *args) { @@ -1214,40 +1204,21 @@ dumpwins(struct swm_region *r, union arg *args) } #endif /* SWM_DEBUG */ -void expose(XEvent *); -void keypress(XEvent *); -void buttonpress(XEvent *); -void configurerequest(XEvent *); -void configurenotify(XEvent *); -void destroynotify(XEvent *); -void enternotify(XEvent *); -void focusevent(XEvent *); -void mapnotify(XEvent *); -void mappingnotify(XEvent *); -void maprequest(XEvent *); -void propertynotify(XEvent *); -void unmapnotify(XEvent *); -void visibilitynotify(XEvent *); -void clientmessage(XEvent *); - -void (*handler[LASTEvent])(XEvent *) = { - [Expose] = expose, - [KeyPress] = keypress, - [ButtonPress] = buttonpress, - [ConfigureRequest] = configurerequest, - [ConfigureNotify] = configurenotify, - [DestroyNotify] = destroynotify, - [EnterNotify] = enternotify, - [FocusIn] = focusevent, - [FocusOut] = focusevent, - [MapNotify] = mapnotify, - [MappingNotify] = mappingnotify, - [MapRequest] = maprequest, - [PropertyNotify] = propertynotify, - [UnmapNotify] = unmapnotify, - [VisibilityNotify] = visibilitynotify, - [ClientMessage] = clientmessage, -}; +void expose(xcb_expose_event_t *); +void keypress(xcb_key_press_event_t *); +void buttonpress(xcb_button_press_event_t *); +void configurerequest(xcb_configure_request_event_t *); +void configurenotify(xcb_configure_notify_event_t *); +void destroynotify(xcb_destroy_notify_event_t *); +void enternotify(xcb_enter_notify_event_t *); +void mapnotify(xcb_map_notify_event_t *); +void mappingnotify(xcb_mapping_notify_event_t *); +void maprequest(xcb_map_request_event_t *); +void propertynotify(xcb_property_notify_event_t *); +void unmapnotify(xcb_unmap_notify_event_t *); +void visibilitynotify(xcb_visibility_notify_event_t *); +void clientmessage(xcb_client_message_event_t *); +void screenchange(xcb_randr_screen_change_notify_event_t *); void sighdlr(int sig) @@ -1322,28 +1293,45 @@ name_to_color(const char *colorname) char cname[32] = "#"; xcb_screen_t *screen; xcb_colormap_t cmap; - xcb_alloc_named_color_cookie_t c; - xcb_alloc_named_color_reply_t *r; + xcb_alloc_color_reply_t *cr; + xcb_alloc_named_color_reply_t *nr; + uint16_t rr, gg, bb; - /* XXX - does not support rgb:/RR/GG/BB - * will need to use xcb_alloc_color - */ screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; cmap = screen->default_colormap; - c = xcb_alloc_named_color(conn, cmap, strlen(colorname), colorname); - r = xcb_alloc_named_color_reply(conn, c, NULL); - if (!r) { - strlcat(cname, colorname + 2, sizeof cname - 1); - c = xcb_alloc_named_color(conn, cmap, strlen(cname), - cname); - r = xcb_alloc_named_color_reply(conn, c, NULL); + /* color is in format rgb://rr/gg/bb */ + if (strncmp(colorname, "rgb:", 4) == 0) { + if (parse_rgb(colorname, &rr, &gg, &bb) == -1) + warnx("could not parse rgb %s", colorname); + else { + cr = xcb_alloc_color_reply(conn, + xcb_alloc_color(conn, cmap, rr, gg, bb), + NULL); + if (cr) { + result = cr->pixel; + free(cr); + } else + warnx("color '%s' not found", colorname); + } + } else { + nr = xcb_alloc_named_color_reply(conn, + xcb_alloc_named_color(conn, cmap, strlen(colorname), + colorname), + NULL); + if (!nr) { + strlcat(cname, colorname + 2, sizeof cname - 1); + nr = xcb_alloc_named_color_reply(conn, + xcb_alloc_named_color(conn, cmap, strlen(cname), + cname), + NULL); + } + if (nr) { + result = nr->pixel; + free(nr); + } else + warnx("color '%s' not found", colorname); } - if (r) { - result = r->pixel; - free(r); - } else - warnx("color '%s' not found", colorname); return (result); } @@ -1447,6 +1435,8 @@ bar_print(struct swm_region *r, const char *s) { int x = 0; size_t len; + xcb_rectangle_t rect; + uint32_t gcv[1]; XRectangle ibox, lbox; len = strlen(s); @@ -1467,21 +1457,29 @@ bar_print(struct swm_region *r, const char *s) if (x < SWM_BAR_OFFSET) x = SWM_BAR_OFFSET; + rect.x = 0; + rect.y = 0; + rect.width = WIDTH(r->bar); + rect.height = HEIGHT(r->bar); + /* clear back buffer */ - XSetForeground(display, r->s->bar_gc, r->s->c[SWM_S_COLOR_BAR].color); - XFillRectangle(display, r->bar->buffer, r->s->bar_gc, 0, 0, - WIDTH(r->bar), HEIGHT(r->bar)); + gcv[0] = r->s->c[SWM_S_COLOR_BAR].color; + xcb_change_gc(conn, r->s->bar_gc, XCB_GC_FOREGROUND, gcv); + xcb_poly_fill_rectangle(conn, r->bar->buffer, r->s->bar_gc, + sizeof(rect), &rect); /* draw back buffer */ - XSetForeground(display, r->s->bar_gc, - r->s->c[SWM_S_COLOR_BAR_FONT].color); - DRAWSTRING(display, r->bar->buffer, bar_fs, r->s->bar_gc, - x, (bar_fs_extents->max_logical_extent.height - lbox.height) / 2 - - lbox.y, s, len); + gcv[0] = r->s->c[SWM_S_COLOR_BAR].color; + xcb_change_gc(conn, r->s->bar_gc, XCB_GC_BACKGROUND, gcv); + gcv[0] = r->s->c[SWM_S_COLOR_BAR_FONT].color; + xcb_change_gc(conn, r->s->bar_gc, XCB_GC_FOREGROUND, gcv); + xcb_image_text_8(conn, len, r->bar->buffer, r->s->bar_gc, x, + (bar_fs_extents->max_logical_extent.height - lbox.height) / 2 - + lbox.y, s); /* blt */ - XCopyArea(display, r->bar->buffer, r->bar->id, r->s->bar_gc, 0, 0, - WIDTH(r->bar), HEIGHT(r->bar), 0, 0); + xcb_copy_area(conn, r->bar->buffer, r->bar->id, r->s->bar_gc, 0, 0, + 0, 0, WIDTH(r->bar), HEIGHT(r->bar)); } void @@ -1504,8 +1502,8 @@ bar_class_name(char *s, size_t sz, struct swm_region *r) { if (r == NULL || r->ws == NULL || r->ws->focus == NULL) return; - if (r->ws->focus->ch.res_class != NULL) - strlcat(s, r->ws->focus->ch.res_class, sz); + if (r->ws->focus->ch.class_name != NULL) + strlcat(s, r->ws->focus->ch.class_name, sz); } void @@ -1513,8 +1511,8 @@ bar_title_name(char *s, size_t sz, struct swm_region *r) { if (r == NULL || r->ws == NULL || r->ws->focus == NULL) return; - if (r->ws->focus->ch.res_name != NULL) - strlcat(s, r->ws->focus->ch.res_name, sz); + if (r->ws->focus->ch.instance_name != NULL) + strlcat(s, r->ws->focus->ch.instance_name, sz); } void @@ -1540,15 +1538,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]; @@ -1942,7 +1940,8 @@ bar_setup(struct swm_region *r) int num_missing_charsets = 0; int i; xcb_screen_t *screen = get_screen(r->s->idx); - + uint32_t wa[2]; + if (bar_fs) { XFreeFontSet(display, bar_fs); bar_fs = NULL; @@ -1987,13 +1986,18 @@ bar_setup(struct swm_region *r) WIDTH(r->bar) = WIDTH(r) - 2 * bar_border_width; HEIGHT(r->bar) = bar_height - 2 * bar_border_width; - r->bar->id = XCreateSimpleWindow(display, - r->s->root, X(r->bar), Y(r->bar), WIDTH(r->bar), HEIGHT(r->bar), - bar_border_width, r->s->c[SWM_S_COLOR_BAR_BORDER].color, - r->s->c[SWM_S_COLOR_BAR].color); + r->bar->id = xcb_generate_id(conn); + wa[0] = r->s->c[SWM_S_COLOR_BAR].color; + wa[1] = r->s->c[SWM_S_COLOR_BAR_BORDER].color; + xcb_create_window(conn, screen->root_depth, r->bar->id, r->s->root, + X(r->bar), Y(r->bar), WIDTH(r->bar), HEIGHT(r->bar), + bar_border_width, XCB_WINDOW_CLASS_INPUT_OUTPUT, + screen->root_visual, XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, + wa); - r->bar->buffer = XCreatePixmap(display, r->bar->id, WIDTH(r->bar), - HEIGHT(r->bar), screen->root_depth); + r->bar->buffer = xcb_generate_id(conn); + 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); @@ -2025,8 +2029,9 @@ void drain_enter_notify(void) { int i = 0; + XEvent cne; - while (xcb_poll_for_event(conn)) + while (XCheckMaskEvent(display, EnterWindowMask, &cne)) i++; DNPRINTF(SWM_D_EVENT, "drain_enter_notify: drained: %d\n", i); @@ -2099,7 +2104,7 @@ client_msg(struct ws_win *win, xcb_atom_t a) /* synthetic response to a ConfigureRequest when not making a change */ void -config_win(struct ws_win *win, XConfigureRequestEvent *ev) +config_win(struct ws_win *win, xcb_configure_request_event_t *ev) { xcb_configure_notify_event_t ce; @@ -2127,10 +2132,10 @@ config_win(struct ws_win *win, XConfigureRequestEvent *ev) ce.window = ev->window; /* make response appear more WM_SIZE_HINTS-compliant */ - if (win->sh_mask) + if (win->sh.flags) DNPRINTF(SWM_D_MISC, "config_win: hints: window: 0x%x," - " sh_mask: %ld, min: %d x %d, max: %d x %d, inc: " - "%d x %d\n", win->id, win->sh_mask, SH_MIN_W(win), + " sh.flags: %u, min: %d x %d, max: %d x %d, inc: " + "%d x %d\n", win->id, win->sh.flags, SH_MIN_W(win), SH_MIN_H(win), SH_MAX_W(win), SH_MAX_H(win), SH_INC_W(win), SH_INC_H(win)); @@ -2166,7 +2171,7 @@ config_win(struct ws_win *win, XConfigureRequestEvent *ev) ce.x += BORDER(win) - ev->border_width; ce.y += BORDER(win) - ev->border_width; ce.border_width = ev->border_width; - ce.above_sibling = ev->above; + ce.above_sibling = ev->sibling; } DNPRINTF(SWM_D_MISC, "config_win: ewmh: %s, window: 0x%x, (x,y) w x h: " @@ -2239,13 +2244,11 @@ void fake_keypress(struct ws_win *win, xcb_keysym_t keysym, uint16_t modifiers) { xcb_key_press_event_t event; - xcb_key_symbols_t *syms; xcb_keycode_t *keycode; if (win == NULL) return; - syms = xcb_key_symbols_alloc(conn); keycode = xcb_key_symbols_get_keycode(syms, keysym); event.event = win->id; @@ -2268,8 +2271,6 @@ fake_keypress(struct ws_win *win, xcb_keysym_t keysym, uint16_t modifiers) xcb_send_event(conn, True, win->id, XCB_EVENT_MASK_KEY_RELEASE, (char *)&event); xcb_flush(conn); - - xcb_key_symbols_free(syms); } void @@ -2285,7 +2286,11 @@ restart(struct swm_region *r, union arg *args) bar_extra_stop(); bar_extra = 1; unmap_all(); - XCloseDisplay(display); + + xcb_key_symbols_free(syms); + xcb_flush(conn); + xcb_disconnect(conn); + execvp(start_argv[0], start_argv); warn("execvp failed"); quit(NULL, NULL); @@ -2296,7 +2301,6 @@ root_to_region(xcb_window_t root) { struct swm_region *r = NULL; int i, num_screens; - xcb_query_pointer_cookie_t qpc; xcb_query_pointer_reply_t *qpr; DNPRINTF(SWM_D_MISC, "root_to_region: window: 0x%x\n", root); @@ -2306,8 +2310,8 @@ root_to_region(xcb_window_t root) if (screens[i].root == root) break; - qpc = xcb_query_pointer(conn, screens[i].root); - qpr = xcb_query_pointer_reply(conn, qpc, NULL); + qpr = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, + screens[i].root), NULL); if (qpr) { DNPRINTF(SWM_D_MISC, "root_to_region: pointer: (%d,%d)\n", @@ -3286,7 +3290,6 @@ adjust_font(struct ws_win *win) void stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) { - XWindowAttributes wa; struct swm_geometry win_g, r_g = *g; struct ws_win *win, *fs_win = NULL; int i, j, s, stacks; @@ -3295,6 +3298,7 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) int split, colno, winno, mwin, msize, mscale; int remain, missing, v_slice, reconfigure; int bordered = 1; + xcb_get_window_attributes_reply_t *war; DNPRINTF(SWM_D_STACK, "stack_master: workspace: %d, rot: %s, " "flip: %s\n", ws->idx, YESNO(rot), YESNO(flip)); @@ -3457,9 +3461,14 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) update_window(win); } - if (XGetWindowAttributes(display, win->id, &wa)) - if (wa.map_state == IsUnmapped) + war = xcb_get_window_attributes_reply(conn, + xcb_get_window_attributes(conn, win->id), + NULL); + if (war) { + if (war->map_state == XCB_MAP_STATE_UNMAPPED) map_window_raised(win->id); + free(war); + } last_h = win_g.h; i++; @@ -3750,29 +3759,28 @@ 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_icccm_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)) { + if (r.name_len > 0) { + name = malloc(r.name_len + 1); + if (!name) { + xcb_icccm_get_text_property_reply_wipe(&r); + return (NULL); + } + memcpy(name, r.name, r.name_len); + name[r.name_len] = '\0'; + } + xcb_icccm_get_text_property_reply_wipe(&r); } - /* 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); - - return (NULL); + return (name); } void @@ -3780,7 +3788,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"); @@ -3817,7 +3825,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); @@ -3883,7 +3891,7 @@ search_win_cleanup(void) while ((sw = TAILQ_FIRST(&search_wl)) != NULL) { xcb_destroy_window(conn, sw->indicator); - XFreeGC(display, sw->gc); + xcb_free_gc(conn, sw->gc); TAILQ_REMOVE(&search_wl, sw, entry); free(sw); } @@ -3895,13 +3903,13 @@ search_win(struct swm_region *r, union arg *args) struct ws_win *win = NULL; struct search_window *sw = NULL; xcb_window_t w; - XGCValues gcv; + uint32_t gcv[1], wa[2]; int i; char s[8]; FILE *lfile; size_t len; XRectangle ibox, lbox; - + xcb_screen_t *screen; DNPRINTF(SWM_D_MISC, "search_win\n"); search_r = r; @@ -3928,28 +3936,33 @@ search_win(struct swm_region *r, union arg *args) } sw->idx = i; sw->win = win; + screen = get_screen(sw->idx); snprintf(s, sizeof s, "%d", i); len = strlen(s); XmbTextExtents(bar_fs, s, len, &ibox, &lbox); - w = XCreateSimpleWindow(display, - win->id, 0, 0,lbox.width + 4, - bar_fs_extents->max_logical_extent.height, 1, - r->s->c[SWM_S_COLOR_UNFOCUS].color, - r->s->c[SWM_S_COLOR_FOCUS].color); - + w = xcb_generate_id(conn); + wa[0] = r->s->c[SWM_S_COLOR_FOCUS].color; + wa[1] = r->s->c[SWM_S_COLOR_UNFOCUS].color; + xcb_create_window(conn, screen->root_depth, w, win->id, + 0, 0, lbox.width + 4, + bar_fs_extents->max_logical_extent.height, 1, + XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, + XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, wa); + sw->indicator = w; TAILQ_INSERT_TAIL(&search_wl, sw, entry); - sw->gc = XCreateGC(display, w, 0, &gcv); + sw->gc = xcb_generate_id(conn); + gcv[0] = r->s->c[SWM_S_COLOR_BAR].color; + xcb_create_gc(conn, sw->gc, w, XCB_GC_FOREGROUND, gcv); map_window_raised(w); - XSetForeground(display, sw->gc, r->s->c[SWM_S_COLOR_BAR].color); - DRAWSTRING(display, w, bar_fs, sw->gc, 2, + xcb_image_text_8(conn, len, w, sw->gc, 2, (bar_fs_extents->max_logical_extent.height - - lbox.height) / 2 - lbox.y, s, len); + lbox.height) / 2 - lbox.y, s); fprintf(lfile, "%d\n", i); i++; @@ -3961,7 +3974,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; @@ -3974,10 +3987,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); @@ -4278,18 +4291,19 @@ update_window(struct ws_win *win) void resize(struct ws_win *win, union arg *args) { - XEvent ev; - Time time = 0; + xcb_timestamp_t time = 0; struct swm_region *r = NULL; int resize_step = 0; - Window rr, cr; - int x, y, wx, wy; - unsigned int mask; struct swm_geometry g; - int top = 0, left = 0; + int top = 0, left = 0, buttonrelease; int dx, dy; - Cursor cursor; unsigned int shape; /* cursor style */ + xcb_cursor_t cursor; + xcb_font_t cursor_font; + xcb_grab_pointer_reply_t *gpr; + xcb_query_pointer_reply_t *xpr; + xcb_generic_event_t *evt; + xcb_motion_notify_event_t *mne; if (win == NULL) return; @@ -4346,15 +4360,17 @@ resize(struct ws_win *win, union arg *args) drain_enter_notify(); /* get cursor offset from window root */ - if (!XQueryPointer(display, win->id, &rr, &cr, &x, &y, &wx, &wy, &mask)) - return; - + xpr = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, win->id), + NULL); + if (!xpr) + return; + g = win->g; - if (wx < WIDTH(win) / 2) + if (xpr->win_x < WIDTH(win) / 2) left = 1; - if (wy < HEIGHT(win) / 2) + if (xpr->win_y < HEIGHT(win) / 2) top = 1; if (args->id == SWM_ARG_ID_CENTER) @@ -4364,27 +4380,40 @@ resize(struct ws_win *win, union arg *args) else shape = (left) ? XC_bottom_left_corner : XC_bottom_right_corner; - cursor = XCreateFontCursor(display, shape); - - if (XGrabPointer(display, win->id, False, MOUSEMASK, GrabModeAsync, - GrabModeAsync, None, cursor, CurrentTime) != GrabSuccess) { - XFreeCursor(display, cursor); + cursor_font = xcb_generate_id(conn); + xcb_open_font(conn, cursor_font, strlen("cursor"), "cursor"); + + cursor = xcb_generate_id(conn); + xcb_create_glyph_cursor(conn, cursor, cursor_font, cursor_font, + shape, shape + 1, 0, 0, 0, 0xffff, 0xffff, 0xffff); + + gpr = xcb_grab_pointer_reply(conn, + xcb_grab_pointer(conn, False, win->id, MOUSEMASK, + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_WINDOW_NONE, + cursor, XCB_CURRENT_TIME), + NULL); + if (!gpr) { + xcb_free_cursor(conn, cursor); + xcb_close_font(conn, cursor_font); + free(xpr); return; } - do { + buttonrelease = 0; + while ((evt = xcb_poll_for_event(conn)) && buttonrelease != 1) { + /* XMaskEvent(display, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); - switch (ev.type) { - case ConfigureRequest: - case Expose: - case MapRequest: - handler[ev.type](&ev); + */ + switch (XCB_EVENT_RESPONSE_TYPE(evt)) { + case XCB_BUTTON_RELEASE: + buttonrelease = 1; break; - case MotionNotify: + case XCB_MOTION_NOTIFY: + mne = (xcb_motion_notify_event_t *)evt; /* cursor offset/delta from start of the operation */ - dx = ev.xmotion.x_root - x; - dy = ev.xmotion.y_root - y; + dx = mne->root_x - xpr->root_x; + dy = mne->root_y - xpr->root_y; /* vertical */ if (top) @@ -4429,14 +4458,18 @@ resize(struct ws_win *win, union arg *args) constrain_window(win, r, 1); /* not free, don't sync more than 120 times / second */ - if ((ev.xmotion.time - time) > (1000 / 120) ) { - time = ev.xmotion.time; + if ((mne->time - time) > (1000 / 120) ) { + time = mne->time; do_sync(); update_window(win); } break; + default: + event_handle(evt); + break; } - } while (ev.type != ButtonRelease); + free(evt); + } if (time) { do_sync(); update_window(win); @@ -4444,7 +4477,10 @@ resize(struct ws_win *win, union arg *args) store_float_geom(win,r); xcb_ungrab_pointer(conn, XCB_CURRENT_TIME); - XFreeCursor(display, cursor); + xcb_free_cursor(conn, cursor); + xcb_close_font(conn, cursor_font); + free(gpr); + free(xpr); /* drain events */ drain_enter_notify(); @@ -4468,14 +4504,15 @@ resize_step(struct swm_region *r, union arg *args) void move(struct ws_win *win, union arg *args) { - XEvent ev; - Time time = 0; - int move_step = 0; + xcb_timestamp_t time = 0; + int move_step = 0, buttonrelease; struct swm_region *r = NULL; - - Window rr, cr; - int x, y, wx, wy; - unsigned int mask; + xcb_font_t cursor_font; + xcb_cursor_t cursor; + xcb_grab_pointer_reply_t *gpr; + xcb_query_pointer_reply_t *qpr; + xcb_generic_event_t *evt; + xcb_motion_notify_event_t *mne; if (win == NULL) return; @@ -4530,44 +4567,72 @@ move(struct ws_win *win, union arg *args) return; } - if (XGrabPointer(display, win->id, False, MOUSEMASK, GrabModeAsync, - GrabModeAsync, None, XCreateFontCursor(display, XC_fleur), - CurrentTime) != GrabSuccess) + cursor_font = xcb_generate_id(conn); + xcb_open_font(conn, cursor_font, strlen("cursor"), "cursor"); + + cursor = xcb_generate_id(conn); + xcb_create_glyph_cursor(conn, cursor, cursor_font, cursor_font, + XC_fleur, XC_fleur + 1, 0, 0, 0, 0xffff, 0xffff, 0xffff); + + gpr = xcb_grab_pointer_reply(conn, + xcb_grab_pointer(conn, False, win->id, MOUSEMASK, + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, + XCB_WINDOW_NONE, cursor, XCB_CURRENT_TIME), + NULL); + if (!gpr) { + xcb_free_cursor(conn, cursor); + xcb_close_font(conn, cursor_font); return; + } /* get cursor offset from window root */ - if (!XQueryPointer(display, win->id, &rr, &cr, &x, &y, &wx, &wy, &mask)) - return; + qpr = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, win->id), + NULL); + if (!qpr) { + xcb_ungrab_pointer(conn, XCB_CURRENT_TIME); + xcb_free_cursor(conn, cursor); + xcb_close_font(conn, cursor_font); + return; + } - do { + buttonrelease = 0; + while ((evt = xcb_poll_for_event(conn)) && buttonrelease != 1) { + /* XMaskEvent(display, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); - switch (ev.type) { - case ConfigureRequest: - case Expose: - case MapRequest: - handler[ev.type](&ev); + */ + switch (XCB_EVENT_RESPONSE_TYPE(evt)) { + case XCB_BUTTON_RELEASE: + buttonrelease = 1; break; - case MotionNotify: - X(win) = ev.xmotion.x_root - wx - border_width; - Y(win) = ev.xmotion.y_root - wy - border_width; + case XCB_MOTION_NOTIFY: + mne = (xcb_motion_notify_event_t *)evt; + X(win) = mne->root_x - qpr->win_x - border_width; + Y(win) = mne->root_y - qpr->win_y - border_width; constrain_window(win, r, 0); /* not free, don't sync more than 120 times / second */ - if ((ev.xmotion.time - time) > (1000 / 120) ) { - time = ev.xmotion.time; + if ((mne->time - time) > (1000 / 120) ) { + time = mne->time; do_sync(); update_window(win); } break; + default: + event_handle(evt); + break; } - } while (ev.type != ButtonRelease); + free(evt); + } if (time) { do_sync(); update_window(win); } store_float_geom(win, r); + free(qpr); + xcb_free_cursor(conn, cursor); + xcb_close_font(conn, cursor_font); xcb_ungrab_pointer(conn, XCB_CURRENT_TIME); /* drain events */ @@ -5462,19 +5527,30 @@ setkeymapping(char *selector, char *value, int flags) void updatenumlockmask(void) { - unsigned int i, j; - XModifierKeymap *modmap; + unsigned int i, j; + xcb_get_modifier_mapping_reply_t *modmap_r; + xcb_keycode_t *modmap, kc; DNPRINTF(SWM_D_MISC, "updatenumlockmask\n"); numlockmask = 0; - modmap = XGetModifierMapping(display); - for (i = 0; i < 8; i++) - for (j = 0; j < modmap->max_keypermod; j++) - if (modmap->modifiermap[i * modmap->max_keypermod + j] - == XKeysymToKeycode(display, XK_Num_Lock)) - numlockmask = (1 << i); - XFreeModifiermap(modmap); + modmap_r = xcb_get_modifier_mapping_reply(conn, + xcb_get_modifier_mapping(conn), + NULL); + if (modmap_r) { + modmap = xcb_get_modifier_mapping_keycodes(modmap_r); + for (i = 0; i < 8; i++) { + for (j = 0; j < modmap_r->keycodes_per_modifier; j++) { + kc = modmap[i * modmap_r->keycodes_per_modifier + + j]; + + if (kc == *((xcb_keycode_t *)xcb_key_symbols_get_keycode(syms, + XK_Num_Lock))) + numlockmask = (1 << i); + } + } + free(modmap_r); + } } void @@ -5482,7 +5558,7 @@ grabkeys(void) { int num_screens; unsigned int j, k; - KeyCode code; + xcb_keycode_t *code; unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask | LockMask }; struct key *kp; @@ -5497,12 +5573,14 @@ grabkeys(void) xcb_ungrab_key(conn, XCB_GRAB_ANY, screens[k].root, XCB_MOD_MASK_ANY); RB_FOREACH(kp, key_tree, &keys) { - if ((code = XKeysymToKeycode(display, kp->keysym))) + if ((code = xcb_key_symbols_get_keycode(syms, + kp->keysym))) for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(display, code, + xcb_grab_key(conn, True, + screens[k].root, kp->mod | modifiers[j], - screens[k].root, True, - GrabModeAsync, GrabModeAsync); + *code, XCB_GRAB_MODE_ASYNC, + XCB_GRAB_MODE_ASYNC); } } } @@ -6247,12 +6325,12 @@ out: } void -set_child_transient(struct ws_win *win, Window *trans) +set_child_transient(struct ws_win *win, xcb_window_t *trans) { struct ws_win *parent, *w; - XWMHints *wmh = NULL; struct swm_region *r; struct workspace *ws; + xcb_icccm_wm_hints_t wmh; parent = find_window(win->transient); if (parent) @@ -6261,37 +6339,28 @@ set_child_transient(struct ws_win *win, Window *trans) DNPRINTF(SWM_D_MISC, "set_child_transient: parent doesn't exist" " for 0x%x trans 0x%x\n", win->id, win->transient); - if (win->hints == NULL) { - warnx("no hints for 0x%x", win->id); - return; - } - - r = root_to_region(win->wa.root); + r = root_to_region(win->wa->root); ws = r->ws; /* parent doen't exist in our window list */ TAILQ_FOREACH(w, &ws->winlist, entry) { - if (wmh) - XFree(wmh); - - if ((wmh = XGetWMHints(display, w->id)) == NULL) { + if (xcb_icccm_get_wm_hints_reply(conn, + xcb_icccm_get_wm_hints(conn, w->id), + &wmh, NULL) != 1) { warnx("can't get hints for 0x%x", w->id); continue; } - if (win->hints->window_group != wmh->window_group) + if (win->hints.window_group != wmh.window_group) continue; w->child_trans = win; win->transient = w->id; *trans = w->id; - DNPRINTF(SWM_D_MISC, "set_child_transient: asjusting " + DNPRINTF(SWM_D_MISC, "set_child_transient: adjusting " "transient to 0x%x\n", win->transient); break; } } - - if (wmh) - XFree(wmh); } long @@ -6338,19 +6407,21 @@ tryharder: struct ws_win * manage_window(xcb_window_t id) { - Window trans = 0; + xcb_window_t trans = XCB_WINDOW_NONE; struct workspace *ws; struct ws_win *win, *ww; - int format, i, ws_idx, n, border_me = 0; - unsigned long nitems, bytes; - Atom ws_idx_atom = 0, type; - Atom *prot = NULL, *pp; - unsigned char ws_idx_str[SWM_PROPLEN], *prop = NULL; + int i, ws_idx, border_me = 0; + xcb_atom_t ws_idx_atom = XCB_ATOM_NONE; + char ws_idx_str[SWM_PROPLEN], *prop = NULL; + size_t proplen; struct swm_region *r; const char *errstr; struct pid_e *p; struct quirk *qp; uint32_t event_mask; + xcb_atom_t prot; + xcb_get_property_reply_t *gpr; + xcb_icccm_get_wm_protocols_reply_t wpr; if ((win = find_window(id)) != NULL) return (win); /* already being managed */ @@ -6397,15 +6468,38 @@ manage_window(xcb_window_t id) p = find_pid(window_get_pid(id)); /* Get all the window data in one shot */ - ws_idx_atom = XInternAtom(display, "_SWM_WS", False); + ws_idx_atom = get_atom_from_string("_SWM_WS"); if (ws_idx_atom) { - XGetWindowProperty(display, id, ws_idx_atom, 0, SWM_PROPLEN, - False, XA_STRING, &type, &format, &nitems, &bytes, &prop); + gpr = xcb_get_property_reply(conn, + xcb_get_property(conn, False, id, ws_idx_atom, + XCB_ATOM_STRING, 0, SWM_PROPLEN), + NULL); + if (gpr) { + proplen = xcb_get_property_value_length(gpr); + if (proplen > 0) { + prop = malloc(proplen + 1); + if (prop) { + memcpy(prop, + xcb_get_property_value(gpr), + proplen); + prop[proplen] = '\0'; + } + } + free(gpr); + } } - XGetWindowAttributes(display, id, &win->wa); - XGetWMNormalHints(display, id, &win->sh, &win->sh_mask); - win->hints = XGetWMHints(display, id); - XGetTransientForHint(display, id, &trans); + win->wa = xcb_get_geometry_reply(conn, + xcb_get_geometry(conn, id), + NULL); + xcb_icccm_get_wm_normal_hints_reply(conn, + xcb_icccm_get_wm_normal_hints(conn, id), + &win->sh, NULL); + xcb_icccm_get_wm_hints_reply(conn, + xcb_icccm_get_wm_hints(conn, id), + &win->hints, NULL); + xcb_icccm_get_wm_transient_for_reply(conn, + xcb_icccm_get_wm_transient_for(conn, id), + &trans, NULL); if (trans) { win->transient = trans; set_child_transient(win, &trans); @@ -6413,16 +6507,19 @@ manage_window(xcb_window_t id) "transient: 0x%x\n", win->id, win->transient); } + prot = get_atom_from_string("WM_PROTOCOLS"); + /* get supported protocols */ - if (XGetWMProtocols(display, id, &prot, &n)) { - for (i = 0, pp = prot; i < n; i++, pp++) { - if (*pp == takefocus) + if (xcb_icccm_get_wm_protocols_reply(conn, + xcb_icccm_get_wm_protocols(conn, id, prot), + &wpr, NULL)) { + for (i = 0; i < wpr.atoms_len; i++) { + if (wpr.atoms[i] == takefocus) win->take_focus = 1; - if (*pp == adelete) + if (wpr.atoms[i] == adelete) win->can_delete = 1; } - if (prot) - XFree(prot); + xcb_icccm_get_wm_protocols_reply_wipe(&wpr); } win->iconic = get_iconic(win); @@ -6432,7 +6529,7 @@ manage_window(xcb_window_t id) * a workspace (either by spawn() or manually moving), and isn't * transient, * put it in the same workspace */ - r = root_to_region(win->wa.root); + r = root_to_region(win->wa->root); if (p) { ws = &r->s->ws[p->ws]; TAILQ_REMOVE(&pidlist, p, entry); @@ -6440,7 +6537,7 @@ manage_window(xcb_window_t id) p = NULL; } else if (prop && win->transient == 0) { DNPRINTF(SWM_D_PROP, "manage_window: get _SWM_WS: %s\n", prop); - ws_idx = strtonum((const char *)prop, 0, workspace_limit - 1, + ws_idx = strtonum(prop, 0, workspace_limit - 1, &errstr); if (errstr) { DNPRINTF(SWM_D_EVENT, "manage_window: window: #%s: %s", @@ -6486,10 +6583,10 @@ manage_window(xcb_window_t id) } /* ignore window border if there is one. */ - WIDTH(win) = win->wa.width; - HEIGHT(win) = win->wa.height; - X(win) = win->wa.x + win->wa.border_width; - Y(win) = win->wa.y + win->wa.border_width; + WIDTH(win) = win->wa->width; + HEIGHT(win) = win->wa->height; + X(win) = win->wa->x + win->wa->border_width; + Y(win) = win->wa->y + win->wa->border_width; win->bordered = 0; win->g_floatvalid = 0; win->floatmaxed = 0; @@ -6503,34 +6600,37 @@ manage_window(xcb_window_t id) /* Set window properties so we can remember this after reincarnation */ if (ws_idx_atom && prop == NULL && - snprintf((char *)ws_idx_str, SWM_PROPLEN, "%d", ws->idx) < + snprintf(ws_idx_str, SWM_PROPLEN, "%d", ws->idx) < SWM_PROPLEN) { DNPRINTF(SWM_D_PROP, "manage_window: set _SWM_WS: %s\n", ws_idx_str); - XChangeProperty(display, win->id, ws_idx_atom, XA_STRING, 8, - PropModeReplace, ws_idx_str, strlen((char *)ws_idx_str)); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id, + ws_idx_atom, XCB_ATOM_STRING, 8, strlen(ws_idx_str), + ws_idx_str); } if (prop) - XFree(prop); + free(prop); ewmh_autoquirk(win); - if (XGetClassHint(display, win->id, &win->ch)) { + if (xcb_icccm_get_wm_class_reply(conn, + xcb_icccm_get_wm_class(conn, win->id), + &win->ch, NULL)) { DNPRINTF(SWM_D_CLASS, "manage_window: class: %s, name: %s\n", - win->ch.res_class, win->ch.res_name); + win->ch.class_name, win->ch.instance_name); /* java is retarded so treat it special */ - if (strstr(win->ch.res_name, "sun-awt")) { + if (strstr(win->ch.instance_name, "sun-awt")) { win->java = 1; border_me = 1; } TAILQ_FOREACH(qp, &quirks, entry) { - if (!strcmp(win->ch.res_class, qp->class) && - !strcmp(win->ch.res_name, qp->name)) { + if (!strcmp(win->ch.class_name, qp->class) && + !strcmp(win->ch.instance_name, qp->name)) { DNPRINTF(SWM_D_CLASS, "manage_window: found: " - "class: %s, name: %s\n", win->ch.res_class, - win->ch.res_name); + "class: %s, name: %s\n", win->ch.class_name, + win->ch.instance_name); if (qp->quirk & SWM_Q_FLOAT) { win->floating = 1; border_me = 1; @@ -6596,10 +6696,10 @@ free_window(struct ws_win *win) TAILQ_REMOVE(&win->ws->unmanagedlist, win, entry); - if (win->ch.res_class) - XFree(win->ch.res_class); - if (win->ch.res_name) - XFree(win->ch.res_name); + if (win->wa) + free(win->wa); + + xcb_icccm_get_wm_class_reply_wipe(&win->ch); kill_refs(win); @@ -6633,11 +6733,6 @@ unmanage_window(struct ws_win *win) focus_prev(win); - if (win->hints) { - XFree(win->hints); - win->hints = NULL; - } - TAILQ_REMOVE(&win->ws->winlist, win, entry); TAILQ_INSERT_TAIL(&win->ws->unmanagedlist, win, entry); } @@ -6681,26 +6776,25 @@ focus_magic(struct ws_win *win) } void -expose(XEvent *e) +expose(xcb_expose_event_t *e) { - DNPRINTF(SWM_D_EVENT, "expose: window: 0x%lx\n", e->xexpose.window); + DNPRINTF(SWM_D_EVENT, "expose: window: 0x%x\n", e->window); } void -keypress(XEvent *e) +keypress(xcb_key_press_event_t *e) { KeySym keysym; - XKeyEvent *ev = &e->xkey; struct key *kp; struct swm_region *r; - keysym = XkbKeycodeToKeysym(display, (KeyCode)ev->keycode, 0, 0); - if ((kp = key_lookup(CLEANMASK(ev->state), keysym)) == NULL) + keysym = XkbKeycodeToKeysym(display, (KeyCode)e->detail, 0, 0); + if ((kp = key_lookup(CLEANMASK(e->state), keysym)) == NULL) return; if (keyfuncs[kp->funcid].func == NULL) return; - r = root_to_region(ev->root); + r = root_to_region(e->root); if (kp->funcid == kf_spawn_custom) spawn_custom(r, &(keyfuncs[kp->funcid].args), kp->spawn_name); else @@ -6708,13 +6802,14 @@ keypress(XEvent *e) } void -buttonpress(XEvent *e) +buttonpress(xcb_button_press_event_t *e) { struct ws_win *win; int i, action; - XButtonPressedEvent *ev = &e->xbutton; - if ((win = find_window(ev->window)) == NULL) + DNPRINTF(SWM_D_EVENT, "buttonpress: window 0x%x\n", e->event); + + if ((win = find_window(e->event)) == NULL) return; focus_magic(win); @@ -6722,44 +6817,64 @@ buttonpress(XEvent *e) for (i = 0; i < LENGTH(buttons); i++) if (action == buttons[i].action && buttons[i].func && - buttons[i].button == ev->button && - CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) + buttons[i].button == e->detail && + CLEANMASK(buttons[i].mask) == CLEANMASK(e->state)) buttons[i].func(win, &buttons[i].args); } void -configurerequest(XEvent *e) +configurerequest(xcb_configure_request_event_t *e) { - XConfigureRequestEvent *ev = &e->xconfigurerequest; struct ws_win *win; - int new = 0; - XWindowChanges wc; + int new = 0, i = 0; + uint16_t mask = 0; + uint32_t wc[7]; - if ((win = find_window(ev->window)) == NULL) - if ((win = find_unmanaged_window(ev->window)) == NULL) + if ((win = find_window(e->window)) == NULL) + if ((win = find_unmanaged_window(e->window)) == NULL) new = 1; if (new) { - bzero(&wc, sizeof wc); - wc.x = ev->x; - wc.y = ev->y; - wc.width = ev->width; - wc.height = ev->height; - wc.border_width = ev->border_width; - wc.sibling = ev->above; - wc.stack_mode = ev->detail; - - DNPRINTF(SWM_D_EVENT, "configurerequest: new window: 0x%lx, " - "new: %s, (x,y) w x h: (%d,%d) %d x %d\n", ev->window, - YESNO(new), wc.x, wc.y, wc.width, wc.height); - - XConfigureWindow(display, ev->window, ev->value_mask, &wc); + if (e->value_mask & XCB_CONFIG_WINDOW_X) { + mask |= XCB_CONFIG_WINDOW_X; + wc[i++] = e->x; + } + if (e->value_mask & XCB_CONFIG_WINDOW_Y) { + mask |= XCB_CONFIG_WINDOW_Y; + wc[i++] = e->y; + } + if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) { + mask |= XCB_CONFIG_WINDOW_WIDTH; + wc[i++] = e->width; + } + if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) { + mask |= XCB_CONFIG_WINDOW_HEIGHT; + wc[i++] = e->height; + } + if (e->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) { + mask |= XCB_CONFIG_WINDOW_BORDER_WIDTH; + wc[i++] = e->border_width; + } + if (e->value_mask & XCB_CONFIG_WINDOW_SIBLING) { + mask |= XCB_CONFIG_WINDOW_SIBLING; + wc[i++] = e->sibling; + } + if (e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) { + mask |= XCB_CONFIG_WINDOW_STACK_MODE; + wc[i++] = e->stack_mode; + } + + DNPRINTF(SWM_D_EVENT, "configurerequest: new window: 0x%x, " + "new: %s, (x,y) w x h: (%d,%d) %d x %d\n", e->window, + YESNO(new), wc[0], wc[1], wc[2], wc[3]); + + xcb_configure_window(conn, e->window, mask, wc); } else if ((!win->manual || win->quirks & SWM_Q_ANYWHERE) && - !(win->sh_mask & EWMH_F_FULLSCREEN)) { - win->g_float.x = ev->x - X(win->ws->r); - win->g_float.y = ev->y - Y(win->ws->r); - win->g_float.w = ev->width; - win->g_float.h = ev->height; + !(win->ewmh_flags & EWMH_F_FULLSCREEN)) { + win->g_float.x = e->x - X(win->ws->r); + win->g_float.y = e->y - Y(win->ws->r); + win->g_float.w = e->width; + win->g_float.h = e->height; win->g_floatvalid = 1; if (win->floating) { @@ -6768,24 +6883,26 @@ configurerequest(XEvent *e) win->g.y += Y(win->ws->r); update_window(win); } else { - config_win(win, ev); + config_win(win, e); } } else { - config_win(win, ev); + config_win(win, e); } } void -configurenotify(XEvent *e) +configurenotify(xcb_configure_notify_event_t *e) { struct ws_win *win; - DNPRINTF(SWM_D_EVENT, "configurenotify: window: 0x%lx\n", - e->xconfigure.window); + DNPRINTF(SWM_D_EVENT, "configurenotify: window: 0x%x\n", + e->window); - win = find_window(e->xconfigure.window); + win = find_window(e->window); if (win) { - XGetWMNormalHints(display, win->id, &win->sh, &win->sh_mask); + xcb_icccm_get_wm_normal_hints_reply(conn, + xcb_icccm_get_wm_normal_hints(conn, win->id), + &win->sh, NULL); adjust_font(win); if (font_adjusted) stack(); @@ -6795,15 +6912,14 @@ configurenotify(XEvent *e) } void -destroynotify(XEvent *e) +destroynotify(xcb_destroy_notify_event_t *e) { struct ws_win *win; - XDestroyWindowEvent *ev = &e->xdestroywindow; - DNPRINTF(SWM_D_EVENT, "destroynotify: window: 0x%lx\n", ev->window); + DNPRINTF(SWM_D_EVENT, "destroynotify: window: 0x%x\n", e->window); - if ((win = find_window(ev->window)) == NULL) { - if ((win = find_unmanaged_window(ev->window)) == NULL) + if ((win = find_window(e->window)) == NULL) { + if ((win = find_unmanaged_window(e->window)) == NULL) return; free_window(win); return; @@ -6820,9 +6936,8 @@ destroynotify(XEvent *e) } void -enternotify(XEvent *e) +enternotify(xcb_enter_notify_event_t *e) { - XCrossingEvent *ev = &e->xcrossing; XEvent cne; struct ws_win *win; #if 0 @@ -6830,12 +6945,12 @@ enternotify(XEvent *e) Window focus_return; int revert_to_return; #endif - DNPRINTF(SWM_D_FOCUS, "enternotify: window: 0x%lx, mode: %d, detail: " - "%d, root: 0x%lx, subwindow: 0x%lx, same_screen: %s, focus: %s, " - "state: %d\n", ev->window, ev->mode, ev->detail, ev->root, - ev->subwindow, YESNO(ev->same_screen), YESNO(ev->focus), ev->state); + DNPRINTF(SWM_D_FOCUS, "enternotify: window: 0x%x, mode: %d, detail: " + "%d, root: 0x%x, subwindow: 0x%x, same_screen_focus: %s, " + "state: %d\n", e->event, e->mode, e->detail, e->root, + e->child, YESNO(e->same_screen_focus), e->state); - if (ev->mode != NotifyNormal) { + if (e->mode != XCB_NOTIFY_MODE_NORMAL) { DNPRINTF(SWM_D_EVENT, "skip enternotify: generated by " "cursor grab.\n"); return; @@ -6918,11 +7033,12 @@ enternotify(XEvent *e) break; } - if ((win = find_window(ev->window)) == NULL) { + if ((win = find_window(e->event)) == NULL) { DNPRINTF(SWM_D_EVENT, "skip enternotify: window is NULL\n"); return; } +#if 0 /* * if we have more enternotifies let them handle it in due time */ @@ -6932,6 +7048,7 @@ enternotify(XEvent *e) XPutBackEvent(display, &cne); return; } +#endif focus_magic(win); } @@ -6940,58 +7057,13 @@ enternotify(XEvent *e) #define MERGE_MEMBERS(a,b) (((a & 0xffff) << 16) | (b & 0xffff)) void -focusevent(XEvent *e) -{ -#if 0 - struct ws_win *win; - u_int32_t mode_detail; - XFocusChangeEvent *ev = &e->xfocus; - - DNPRINTF(SWM_D_EVENT, "focusevent: %s window: 0x%lx mode: %d " - "detail: %d\n", ev->type == FocusIn ? "entering" : "leaving", - ev->window, ev->mode, ev->detail); - - if (last_focus_event == ev->type) { - DNPRINTF(SWM_D_FOCUS, "ignoring focusevent: bad ordering\n"); - return; - } - - last_focus_event = ev->type; - mode_detail = MERGE_MEMBERS(ev->mode, ev->detail); - - switch (mode_detail) { - /* synergy client focus operations */ - case MERGE_MEMBERS(NotifyNormal, NotifyNonlinear): - case MERGE_MEMBERS(NotifyNormal, NotifyNonlinearVirtual): - - /* synergy server focus operations */ - case MERGE_MEMBERS(NotifyWhileGrabbed, NotifyNonlinear): - - /* Entering applications like rdesktop that mangle the pointer */ - case MERGE_MEMBERS(NotifyNormal, NotifyPointer): - - if ((win = find_window(e->xfocus.window)) != NULL && win->ws->r) - XSetWindowBorder(display, win->id, - win->ws->r->s->c[ev->type == FocusIn ? - SWM_S_COLOR_FOCUS : SWM_S_COLOR_UNFOCUS].color); - break; - default: - warnx("ignoring focusevent"); - DNPRINTF(SWM_D_FOCUS, "ignoring focusevent\n"); - break; - } -#endif -} - -void -mapnotify(XEvent *e) +mapnotify(xcb_map_notify_event_t *e) { struct ws_win *win; - XMapEvent *ev = &e->xmap; - DNPRINTF(SWM_D_EVENT, "mapnotify: window: 0x%lx\n", ev->window); + DNPRINTF(SWM_D_EVENT, "mapnotify: window: 0x%x\n", e->window); - win = manage_window(ev->window); + win = manage_window(e->window); if (win) set_win_state(win, XCB_ICCCM_WM_STATE_NORMAL); @@ -7004,61 +7076,84 @@ mapnotify(XEvent *e) } void -mappingnotify(XEvent *e) +mappingnotify(xcb_mapping_notify_event_t *e) { - XMappingEvent *ev = &e->xmapping; + xcb_refresh_keyboard_mapping(syms, e); - XRefreshKeyboardMapping(ev); - if (ev->request == MappingKeyboard) + if (e->request == XCB_MAPPING_KEYBOARD) grabkeys(); } void -maprequest(XEvent *e) +maprequest(xcb_map_request_event_t *e) { struct ws_win *win; struct swm_region *r; - XWindowAttributes wa; - XMapRequestEvent *ev = &e->xmaprequest; + xcb_get_window_attributes_reply_t *war; - DNPRINTF(SWM_D_EVENT, "maprequest: window: 0x%lx\n", - e->xmaprequest.window); + DNPRINTF(SWM_D_EVENT, "maprequest: window: 0x%x\n", + e->window); - if (!XGetWindowAttributes(display, ev->window, &wa)) + war = xcb_get_window_attributes_reply(conn, + xcb_get_window_attributes(conn, e->window), + NULL); + if (!war) return; - if (wa.override_redirect) + if (war->override_redirect) { + free(war); return; + } + free(war); - win = manage_window(e->xmaprequest.window); - if (win == NULL) + win = manage_window(e->window); + if (win == NULL) { return; /* can't happen */ + } stack(); /* make new win focused */ - r = root_to_region(win->wa.root); + r = root_to_region(win->wa->root); if (win->ws == r->ws) focus_magic(win); } void -propertynotify(XEvent *e) +propertynotify(xcb_property_notify_event_t *e) { struct ws_win *win; - XPropertyEvent *ev = &e->xproperty; #ifdef SWM_DEBUG - char *name; - name = XGetAtomName(display, ev->atom); - DNPRINTF(SWM_D_EVENT, "propertynotify: window: 0x%lx, atom: %s\n", - ev->window, name); - XFree(name); + char *name; + size_t len; + xcb_get_atom_name_reply_t *r; + + r = xcb_get_atom_name_reply(conn, + xcb_get_atom_name(conn, e->atom), + NULL); + if (r) { + len = xcb_get_atom_name_name_length(r); + if (len > 0) { + name = malloc(len + 1); + if (name) { + memcpy(name, xcb_get_atom_name_name(r), len); + name[len] = '\0'; + + DNPRINTF(SWM_D_EVENT, + "propertynotify: window: 0x%x, " + "atom: %s\n", + e->window, name); + free(name); + } + } + free(r); + } #endif - win = find_window(ev->window); + win = find_window(e->window); if (win == NULL) return; - if (ev->state == PropertyDelete && ev->atom == a_swm_iconic) { + if (e->state == XCB_PROPERTY_DELETE && e->atom == a_swm_iconic) { update_iconic(win, 0); map_window_raised(win->id); stack(); @@ -7066,13 +7161,14 @@ propertynotify(XEvent *e) return; } - switch (ev->atom) { + switch (e->atom) { #if 0 - case XA_WM_NORMAL_HINTS: - long mask; - XGetWMNormalHints(display, win->id, &win->sh, &mask); + case XCB_ATOM_WM_NORMAL_HINTS: + xcb_icccm_get_wm_normal_hints(conn, + xcb_iccom_get_wm_normal_hints(conn, win->id), + &win->sh, NULL); warnx("normal hints: flag 0x%x", win->sh.flags); - if (win->sh.flags & PMinSize) { + if (win->sh.flags & XCB_SIZE_HINT_P_MIN_SIZE) { WIDTH(win) = win->sh.min_width; HEIGHT(win) = win->sh.min_height; warnx("min %d %d", WIDTH(win), HEIGHT(win)); @@ -7080,8 +7176,8 @@ propertynotify(XEvent *e) XMoveResizeWindow(display, win->id, X(win), Y(win), WIDTH(win), HEIGHT(win)); #endif - case XA_WM_CLASS: - case XA_WM_NAME: + case XCB_ATOM_WM_CLASS: + case XCB_ATOM_WM_NAME: bar_update(); break; default: @@ -7090,35 +7186,35 @@ propertynotify(XEvent *e) } void -unmapnotify(XEvent *e) +unmapnotify(xcb_unmap_notify_event_t *e) { struct ws_win *win; - DNPRINTF(SWM_D_EVENT, "unmapnotify: window: 0x%lx\n", e->xunmap.window); + DNPRINTF(SWM_D_EVENT, "unmapnotify: window: 0x%x\n", e->window); /* determine if we need to help unmanage this window */ - win = find_window(e->xunmap.window); + win = find_window(e->window); if (win == NULL) return; - if (getstate(e->xunmap.window) == XCB_ICCCM_WM_STATE_NORMAL) { + if (getstate(e->window) == XCB_ICCCM_WM_STATE_NORMAL) { unmanage_window(win); stack(); /* giant hack for apps that don't destroy transient windows */ /* eat a bunch of events to prevent remanaging the window */ XEvent cne; - while (XCheckWindowEvent(display, e->xunmap.window, + while (XCheckWindowEvent(display, e->window, EnterWindowMask, &cne)) ; - while (XCheckWindowEvent(display, e->xunmap.window, + while (XCheckWindowEvent(display, e->window, StructureNotifyMask, &cne)) ; - while (XCheckWindowEvent(display, e->xunmap.window, + while (XCheckWindowEvent(display, e->window, SubstructureNotifyMask, &cne)) ; /* resend unmap because we ated it */ - XUnmapWindow(display, e->xunmap.window); + xcb_unmap_window(conn, e->window); } if (focus_mode == SWM_FOCUS_DEFAULT) @@ -7126,68 +7222,59 @@ unmapnotify(XEvent *e) } void -visibilitynotify(XEvent *e) +visibilitynotify(xcb_visibility_notify_event_t *e) { int i, num_screens; struct swm_region *r; - DNPRINTF(SWM_D_EVENT, "visibilitynotify: window: 0x%lx\n", - e->xvisibility.window); + DNPRINTF(SWM_D_EVENT, "visibilitynotify: window: 0x%x\n", + e->window); - if (e->xvisibility.state == VisibilityUnobscured) { + if (e->state == XCB_VISIBILITY_UNOBSCURED) { num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); for (i = 0; i < num_screens; i++) TAILQ_FOREACH(r, &screens[i].rl, entry) - if (e->xvisibility.window == WINID(r->bar)) + if (e->window == WINID(r->bar)) bar_update(); } } void -clientmessage(XEvent *e) +clientmessage(xcb_client_message_event_t *e) { - XClientMessageEvent *ev; - struct ws_win *win; + struct ws_win *win; - ev = &e->xclient; - - win = find_window(ev->window); - if (win == NULL) { - if (ev->message_type == ewmh[_NET_ACTIVE_WINDOW].atom) { - DNPRINTF(SWM_D_EVENT, "clientmessage: request focus on " - "unmanaged window.\n"); - e->xmaprequest.window = ev->window; - maprequest(e); - } + win = find_window(e->window); + if (win == NULL) return; } - DNPRINTF(SWM_D_EVENT, "clientmessage: window: 0x%lx, type: %ld\n", - ev->window, ev->message_type); + DNPRINTF(SWM_D_EVENT, "clientmessage: window: 0x%x, type: %u\n", + e->window, e->response_type); - if (ev->message_type == ewmh[_NET_ACTIVE_WINDOW].atom) { + if (e->response_type == ewmh[_NET_ACTIVE_WINDOW].atom) { DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_ACTIVE_WINDOW\n"); focus_win(win); } - if (ev->message_type == ewmh[_NET_CLOSE_WINDOW].atom) { + if (e->response_type == ewmh[_NET_CLOSE_WINDOW].atom) { DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_CLOSE_WINDOW\n"); if (win->can_delete) client_msg(win, adelete); else xcb_kill_client(conn, win->id); } - if (ev->message_type == ewmh[_NET_MOVERESIZE_WINDOW].atom) { + if (e->response_type == ewmh[_NET_MOVERESIZE_WINDOW].atom) { DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_MOVERESIZE_WINDOW\n"); if (win->floating) { - if (ev->data.l[0] & (1<<8)) /* x */ - X(win) = ev->data.l[1]; - if (ev->data.l[0] & (1<<9)) /* y */ - Y(win) = ev->data.l[2]; - if (ev->data.l[0] & (1<<10)) /* width */ - WIDTH(win) = ev->data.l[3]; - if (ev->data.l[0] & (1<<11)) /* height */ - HEIGHT(win) = ev->data.l[4]; + if (e->data.data32[0] & (1<<8)) /* x */ + X(win) = e->data.data32[1]; + if (e->data.data32[0] & (1<<9)) /* y */ + Y(win) = e->data.data32[2]; + if (e->data.data32[0] & (1<<10)) /* width */ + WIDTH(win) = e->data.data32[3]; + if (e->data.data32[0] & (1<<11)) /* height */ + HEIGHT(win) = e->data.data32[4]; update_window(win); } @@ -7197,12 +7284,12 @@ clientmessage(XEvent *e) config_win(win, NULL); } } - if (ev->message_type == ewmh[_NET_WM_STATE].atom) { + if (e->response_type == ewmh[_NET_WM_STATE].atom) { DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_WM_STATE\n"); - ewmh_update_win_state(win, ev->data.l[1], ev->data.l[0]); - if (ev->data.l[2]) - ewmh_update_win_state(win, ev->data.l[2], - ev->data.l[0]); + ewmh_update_win_state(win, e->data.data32[1], e->data.data32[0]); + if (e->data.data32[2]) + ewmh_update_win_state(win, e->data.data32[2], + e->data.data32[0]); stack(); } @@ -7351,32 +7438,35 @@ 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, screen->width_in_pixels, screen->height_in_pixels); - else + 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, 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 */ { @@ -7386,21 +7476,25 @@ scan_xrandr(int i) } void -screenchange(XEvent *e) +screenchange(xcb_randr_screen_change_notify_event_t *e) { - XRRScreenChangeNotifyEvent *xe = (XRRScreenChangeNotifyEvent *)e; struct swm_region *r; int i, num_screens; - DNPRINTF(SWM_D_EVENT, "screenchange: root: 0x%lx\n", xe->root); - - if (!XRRUpdateConfiguration(e)) - return; + DNPRINTF(SWM_D_EVENT, "screenchange: root: 0x%x\n", e->root); + if (e->rotation & (XCB_RANDR_ROTATION_ROTATE_90 + | XCB_RANDR_ROTATION_ROTATE_270)) + xcb_randr_set_screen_size(conn, e->root, e->height, + e->width, e->mheight, e->mwidth); + else + xcb_randr_set_screen_size(conn, e->root, e->width, + e->height, e->mwidth, e->mheight); + num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); /* silly event doesn't include the screen index */ for (i = 0; i < num_screens; i++) - if (screens[i].root == xe->root) + if (screens[i].root == e->root) break; if (i >= num_screens) errx(1, "screenchange: screen not found"); @@ -7492,8 +7586,10 @@ setup_screens(void) { int i, j, k, num_screens; struct workspace *ws; - XGCValues gcv; + uint32_t gcv[1], wa[1]; const xcb_query_extension_reply_t *qep; + xcb_cursor_t cursor; + xcb_font_t cursor_font; xcb_randr_query_version_cookie_t c; xcb_randr_query_version_reply_t *r; @@ -7515,6 +7611,14 @@ setup_screens(void) qep = xcb_get_extension_data(conn, &xcb_randr_id); xrandr_eventbase = qep->first_event; + cursor_font = xcb_generate_id(conn); + xcb_open_font(conn, cursor_font, strlen("cursor"), "cursor"); + + cursor = xcb_generate_id(conn); + xcb_create_glyph_cursor(conn, cursor, cursor_font, cursor_font, + XC_left_ptr, XC_left_ptr + 1, 0, 0, 0, 0xffff, 0xffff, 0xffff); + wa[0] = cursor; + /* map physical screens */ for (i = 0; i < num_screens; i++) { DNPRINTF(SWM_D_WS, "setup_screens: init screen: %d\n", i); @@ -7531,13 +7635,14 @@ setup_screens(void) setscreencolor("rgb:a0/a0/a0", i + 1, SWM_S_COLOR_BAR_FONT); /* create graphics context on screen */ - gcv.graphics_exposures = 0; - screens[i].bar_gc = XCreateGC(display, screens[i].root, - GCGraphicsExposures, &gcv); + screens[i].bar_gc = xcb_generate_id(conn); + gcv[0] = 0; + xcb_create_gc(conn, screens[i].bar_gc, screens[i].root, + XCB_GC_GRAPHICS_EXPOSURES, gcv); /* set default cursor */ - XDefineCursor(display, screens[i].root, - XCreateFontCursor(display, XC_left_ptr)); + xcb_change_window_attributes(conn, screens[i].root, + XCB_CW_CURSOR, wa); /* init all workspaces */ /* XXX these should be dynamically allocated too */ @@ -7565,6 +7670,8 @@ setup_screens(void) xcb_randr_select_input(conn, screens[i].root, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE); } + xcb_free_cursor(conn, cursor); + xcb_close_font(conn, cursor_font); } void @@ -7583,6 +7690,8 @@ workaround(void) int i, num_screens; xcb_atom_t netwmcheck, netwmname, utf8_string; xcb_window_t root, win; + xcb_screen_t *screen; + uint32_t wa[2]; /* work around sun jdk bugs, code from wmname */ netwmcheck = get_atom_from_string("_NET_SUPPORTING_WM_CHECK"); @@ -7592,9 +7701,15 @@ workaround(void) num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); for (i = 0; i < num_screens; i++) { root = screens[i].root; - win = XCreateSimpleWindow(display,root, 0, 0, 1, 1, 0, - screens[i].c[SWM_S_COLOR_UNFOCUS].color, - screens[i].c[SWM_S_COLOR_UNFOCUS].color); + screen = get_screen(i); + + win = xcb_generate_id(conn); + wa[0] = screens[i].c[SWM_S_COLOR_UNFOCUS].color; + wa[1] = screens[i].c[SWM_S_COLOR_UNFOCUS].color; + xcb_create_window(conn, screen->root_depth, win, 0, + 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, + screen->root_visual, + XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, wa); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, netwmcheck, XCB_ATOM_WINDOW, 32, 1, &win); @@ -7605,6 +7720,41 @@ workaround(void) } } +void +event_handle(xcb_generic_event_t *evt) +{ + uint8_t type = XCB_EVENT_RESPONSE_TYPE(evt); + + if (type == 0) + { + /* XXX - handle error */ + return; + } + + switch (type) { +#define EVENT(type, callback) case type: callback((void *)evt); return + EVENT(XCB_BUTTON_PRESS, buttonpress); + EVENT(XCB_BUTTON_RELEASE, buttonpress); + EVENT(XCB_CLIENT_MESSAGE, clientmessage); + EVENT(XCB_CONFIGURE_NOTIFY, configurenotify); + EVENT(XCB_CONFIGURE_REQUEST, configurerequest); + EVENT(XCB_DESTROY_NOTIFY, destroynotify); + EVENT(XCB_ENTER_NOTIFY, enternotify); + EVENT(XCB_EXPOSE, expose); + EVENT(XCB_KEY_PRESS, keypress); + EVENT(XCB_KEY_RELEASE, keypress); + EVENT(XCB_MAP_NOTIFY, mapnotify); + EVENT(XCB_MAP_REQUEST, maprequest); + EVENT(XCB_MAPPING_NOTIFY, mappingnotify); + EVENT(XCB_PROPERTY_NOTIFY, propertynotify); + EVENT(XCB_UNMAP_NOTIFY, unmapnotify); + EVENT(XCB_VISIBILITY_NOTIFY, visibilitynotify); +#undef EVENT + } + if (type - xrandr_eventbase == XCB_RANDR_SCREEN_CHANGE_NOTIFY) + screenchange((void *)evt); +} + int main(int argc, char *argv[]) { @@ -7614,10 +7764,10 @@ main(int argc, char *argv[]) union arg a; char conf[PATH_MAX], *cfile = NULL; struct stat sb; - XEvent e; int xfd, i, num_screens; fd_set rd; struct sigaction sact; + xcb_generic_event_t *evt; start_argv = argv; warnx("Welcome to spectrwm V%s Build: %s", SPECTRWM_VERSION, buildstr); @@ -7666,6 +7816,10 @@ main(int argc, char *argv[]) if (pwd == NULL) errx(1, "invalid user: %d", getuid()); + syms = xcb_key_symbols_alloc(conn); + if (syms == NULL) + errx(1, "unable to allocate key symbols"); + setup_globals(); setup_screens(); setup_keys(); @@ -7739,32 +7893,11 @@ noconfig: xfd = xcb_get_file_descriptor(conn); while (running) { - while (XPending(display)) { - XNextEvent(display, &e); + while ((evt = xcb_poll_for_event(conn))) { if (running == 0) goto done; - if (e.type < LASTEvent) { - DNPRINTF(SWM_D_EVENTQ ,"XEvent: handled: %s, " - "window: 0x%lx, type: %s (%d), %d remaining" - "\n", YESNO(handler[e.type]), - e.xany.window, geteventname(&e), - e.type, QLength(display)); - - if (handler[e.type]) - handler[e.type](&e); - } else { - DNPRINTF(SWM_D_EVENTQ, "XRandr Event: window: " - "0x%lx, type: %s (%d)\n", e.xany.window, - xrandr_geteventname(&e), e.type); - - switch (e.type - xrandr_eventbase) { - case XCB_RANDR_SCREEN_CHANGE_NOTIFY: - screenchange(&e); - break; - default: - break; - } - } + event_handle(evt); + free(evt); } /* if we are being restarted go focus on first window */ @@ -7810,11 +7943,12 @@ done: bar_extra_stop(); for (i = 0; i < num_screens; ++i) - if (screens[i].bar_gc != NULL) - XFreeGC(display, screens[i].bar_gc); + if (screens[i].bar_gc != 0) + xcb_free_gc(conn, screens[i].bar_gc); XFreeFontSet(display, bar_fs); + + xcb_key_symbols_free(syms); xcb_disconnect(conn); - XCloseDisplay(display); return (0); }