void client_message(xcb_generic_event_t *evt) { xcb_client_message_event_t *e = (xcb_client_message_event_t *) evt; if (e->type == ewmh->_NET_CURRENT_DESKTOP) { coordinates_t loc; if (ewmh_locate_desktop(e->data.data32[0], &loc)) { focus_node(loc.monitor, loc.desktop, loc.desktop->focus); } return; } coordinates_t loc; if (!locate_window(e->window, &loc)) { return; } if (e->type == ewmh->_NET_WM_STATE) { handle_state(loc.monitor, loc.desktop, loc.node, e->data.data32[1], e->data.data32[0]); handle_state(loc.monitor, loc.desktop, loc.node, e->data.data32[2], e->data.data32[0]); } else if (e->type == ewmh->_NET_ACTIVE_WINDOW) { if ((ignore_ewmh_focus && e->data.data32[0] == XCB_EWMH_CLIENT_SOURCE_TYPE_NORMAL) || loc.node == mon->desk->focus) { return; } focus_node(loc.monitor, loc.desktop, loc.node); } else if (e->type == ewmh->_NET_WM_DESKTOP) { coordinates_t dloc; if (ewmh_locate_desktop(e->data.data32[0], &dloc)) { transfer_node(loc.monitor, loc.desktop, loc.node, dloc.monitor, dloc.desktop, dloc.desktop->focus); } } else if (e->type == ewmh->_NET_CLOSE_WINDOW) { window_close(loc.node); } }
size_t bt_btr_continue(struct bt_btr *btr, const uint8_t *buf, size_t sz, enum bt_btr_status *status) { assert(btr); assert(buf); assert(sz > 0); btr->buf.addr = buf; btr->buf.offset = 0; btr->buf.at = 0; btr->buf.buf_sz = sz; btr->buf.sz = BYTES_TO_BITS(sz); *status = BT_BTR_STATUS_OK; BT_LOGV("Continuing decoding: btr-addr=%p, buf-addr=%p, buf-size=%zu", btr, buf, sz); /* Continue running the machine */ BT_LOGV_STR("Running the state machine."); while (true) { *status = handle_state(btr); if (*status != BT_BTR_STATUS_OK || btr->state == BTR_STATE_DONE) { break; } } /* Update packet offset for next time */ update_packet_offset(btr); return btr->buf.at; }
void client_message(xcb_generic_event_t *evt) { xcb_client_message_event_t *e = (xcb_client_message_event_t *) evt; PRINTF("client message %X %u\n", e->window, e->type); if (e->type == ewmh->_NET_CURRENT_DESKTOP) { coordinates_t loc; if (ewmh_locate_desktop(e->data.data32[0], &loc)) focus_node(loc.monitor, loc.desktop, loc.desktop->focus); return; } coordinates_t loc; if (!locate_window(e->window, &loc)) return; if (e->type == ewmh->_NET_WM_STATE) { handle_state(loc.monitor, loc.desktop, loc.node, e->data.data32[1], e->data.data32[0]); handle_state(loc.monitor, loc.desktop, loc.node, e->data.data32[2], e->data.data32[0]); } else if (e->type == ewmh->_NET_ACTIVE_WINDOW) { if ((ignore_ewmh_focus && e->data.data32[0] == XCB_EWMH_CLIENT_SOURCE_TYPE_NORMAL) || loc.node == mon->desk->focus) return; if (loc.desktop->focus->client->fullscreen && loc.desktop->focus != loc.node) { set_fullscreen(loc.desktop->focus, false); arrange(loc.monitor, loc.desktop); } focus_node(loc.monitor, loc.desktop, loc.node); } else if (e->type == ewmh->_NET_WM_DESKTOP) { coordinates_t dloc; if (ewmh_locate_desktop(e->data.data32[0], &dloc)) transfer_node(loc.monitor, loc.desktop, loc.node, dloc.monitor, dloc.desktop, dloc.desktop->focus); } else if (e->type == ewmh->_NET_CLOSE_WINDOW) { window_close(loc.node); } }
static void read_properties(struct wlc_xwm *xwm, struct wlc_x11_window *win, const xcb_atom_t *props, size_t nmemb) { assert(win); struct wlc_view *view; if (!(view = view_for_window(win))) return; xcb_get_property_cookie_t *cookies; if (!(cookies = chck_calloc_of(nmemb, sizeof(xcb_get_property_cookie_t)))) return; for (uint32_t i = 0; i < nmemb; ++i) cookies[i] = xcb_get_property(x11.connection, 0, win->id, props[i], XCB_ATOM_ANY, 0, 2048); for (uint32_t i = 0; i < nmemb; ++i) { xcb_get_property_reply_t *reply; if (!(reply = xcb_get_property_reply(x11.connection, cookies[i], NULL))) continue; if (reply->type == XCB_ATOM_STRING || reply->type == x11.atoms[UTF8_STRING]) { // Class && Name // STRING == latin1, but we naively just read it as is. For full support we should convert to utf8. if (props[i] == XCB_ATOM_WM_CLASS) { wlc_view_set_class_ptr(view, xcb_get_property_value(reply), xcb_get_property_value_length(reply)); wlc_dlog(WLC_DBG_XWM, "WM_CLASS: %s", view->data._class.data); } else if (props[i] == XCB_ATOM_WM_NAME || props[i] == x11.atoms[NET_WM_NAME]) { if (reply->type != XCB_ATOM_STRING || !win->has_utf8_title) { wlc_view_set_title_ptr(view, xcb_get_property_value(reply), xcb_get_property_value_length(reply)); win->has_utf8_title = true; } wlc_dlog(WLC_DBG_XWM, "(%d) %s %s %s", win->has_utf8_title, (reply->type == XCB_ATOM_STRING ? "STRING" : "UTF8_STRING"), (props[i] == XCB_ATOM_WM_NAME ? "WM_NAME" : "NET_WM_NAME"), view->data.title.data); } } else if (props[i] == XCB_ATOM_WM_TRANSIENT_FOR && reply->type == XCB_ATOM_WINDOW) { // Transient xcb_window_t *xid = xcb_get_property_value(reply); set_parent(xwm, win, *xid); wlc_dlog(WLC_DBG_XWM, "WM_TRANSIENT_FOR: %u", *xid); } else if (props[i] == x11.atoms[NET_WM_PID] && reply->type == XCB_ATOM_CARDINAL) { // PID wlc_dlog(WLC_DBG_XWM, "NET_WM_PID"); } else if (props[i] == x11.atoms[NET_WM_WINDOW_TYPE] && reply->type == XCB_ATOM_ATOM) { // Window type view->type &= ~WLC_BIT_UNMANAGED | ~WLC_BIT_SPLASH | ~WLC_BIT_MODAL; xcb_atom_t *atoms = xcb_get_property_value(reply); for (uint32_t i = 0; i < reply->value_len; ++i) { if (atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_TOOLTIP] || atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_UTILITY] || atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_DND] || atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_DROPDOWN_MENU] || atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_POPUP_MENU] || atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_COMBO]) { wlc_view_set_type_ptr(view, WLC_BIT_UNMANAGED, true); } if (atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_DIALOG]) wlc_view_set_type_ptr(view, WLC_BIT_MODAL, true); if (atoms[i] == x11.atoms[NET_WM_WINDOW_TYPE_SPLASH]) wlc_view_set_type_ptr(view, WLC_BIT_SPLASH, true); } wlc_dlog(WLC_DBG_XWM, "NET_WM_WINDOW_TYPE: %u", view->type); } else if (props[i] == x11.atoms[WM_PROTOCOLS]) { xcb_atom_t *atoms = xcb_get_property_value(reply); for (uint32_t i = 0; i < reply->value_len; ++i) { if (atoms[i] == x11.atoms[WM_DELETE_WINDOW]) win->has_delete_window = true; } wlc_dlog(WLC_DBG_XWM, "WM_PROTOCOLS: %u", view->type); } else if (props[i] == x11.atoms[WM_NORMAL_HINTS]) { wlc_dlog(WLC_DBG_XWM, "WM_NORMAL_HINTS"); } else if (props[i] == x11.atoms[NET_WM_STATE]) { handle_state(win, xcb_get_property_value(reply), reply->value_len, NET_WM_STATE_ADD); wlc_dlog(WLC_DBG_XWM, "NET_WM_STATE"); } else if (props[i] == x11.atoms[MOTIF_WM_HINTS]) { // Motif hints wlc_dlog(WLC_DBG_XWM, "MOTIF_WM_HINTS"); } free(reply); } free(cookies); }
size_t bt_btr_start(struct bt_btr *btr, struct bt_field_type *type, const uint8_t *buf, size_t offset, size_t packet_offset, size_t sz, enum bt_btr_status *status) { assert(btr); assert(BYTES_TO_BITS(sz) >= offset); reset(btr); btr->buf.addr = buf; btr->buf.offset = offset; btr->buf.at = 0; btr->buf.packet_offset = packet_offset; btr->buf.buf_sz = sz; btr->buf.sz = BYTES_TO_BITS(sz) - offset; *status = BT_BTR_STATUS_OK; BT_LOGV("Starting decoding: btr-addr=%p, ft-addr=%p, " "buf-addr=%p, buf-size=%zu, offset=%zu, " "packet-offset=%zu", btr, type, buf, sz, offset, packet_offset); /* Set root type */ if (is_compound_type(type)) { /* Compound type: push on visit stack */ int stack_ret; if (btr->user.cbs.types.compound_begin) { BT_LOGV("Calling user function (compound, begin)."); *status = btr->user.cbs.types.compound_begin( type, btr->user.data); BT_LOGV("User function returned: status=%s", bt_btr_status_string(*status)); if (*status != BT_BTR_STATUS_OK) { BT_LOGW("User function failed: btr-addr=%p, status=%s", btr, bt_btr_status_string(*status)); goto end; } } stack_ret = stack_push_with_len(btr, type); if (stack_ret) { /* stack_push_with_len() logs errors */ *status = BT_BTR_STATUS_ERROR; goto end; } btr->state = BTR_STATE_ALIGN_COMPOUND; } else { /* Basic type: set as current basic type */ btr->cur_basic_field_type = type; bt_get(btr->cur_basic_field_type); btr->state = BTR_STATE_ALIGN_BASIC; } /* Run the machine! */ BT_LOGV_STR("Running the state machine."); while (true) { *status = handle_state(btr); if (*status != BT_BTR_STATUS_OK || btr->state == BTR_STATE_DONE) { break; } } /* Update packet offset for next time */ update_packet_offset(btr); end: return btr->buf.at; }