static xcb_window_t recursive_Window_With_Name ( xcb_connection_t *dpy, xcb_window_t window, struct wininfo_cookies *cookies, const char *name) { xcb_window_t *children; unsigned int nchildren; int i; xcb_window_t w = 0; xcb_generic_error_t *err; xcb_query_tree_reply_t *tree; struct wininfo_cookies *child_cookies; xcb_get_property_reply_t *prop; if (cookies->get_net_wm_name.sequence) { prop = xcb_get_property_reply (dpy, cookies->get_net_wm_name, &err); if (prop) { if (prop->type == atom_utf8_string) { const char *prop_name = xcb_get_property_value (prop); int prop_name_len = xcb_get_property_value_length (prop); /* can't use strcmp, since prop.name is not null terminated */ if (strncmp (prop_name, name, prop_name_len) == 0) { w = window; } } free (prop); } else if (err) { if (err->response_type == 0) Print_X_Error (dpy, err); return 0; } } if (w) { xcb_discard_reply (dpy, cookies->get_wm_name.sequence); } else { #ifdef USE_XCB_ICCCM xcb_get_text_property_reply_t nameprop; if (xcb_get_wm_name_reply (dpy, cookies->get_wm_name, &nameprop, &err)) { /* can't use strcmp, since nameprop.name is not null terminated */ if (strncmp (nameprop.name, name, nameprop.name_len) == 0) { w = window; } xcb_get_text_property_reply_wipe (&nameprop); } #else prop = xcb_get_property_reply (dpy, cookies->get_wm_name, &err); if (prop) { if (prop->type == XCB_ATOM_STRING) { const char *prop_name = xcb_get_property_value (prop); int prop_name_len = xcb_get_property_value_length (prop); /* can't use strcmp, since prop.name is not null terminated */ if (strncmp (prop_name, name, prop_name_len) == 0) { w = window; } } free (prop); } #endif else if (err) { if (err->response_type == 0) Print_X_Error (dpy, err); return 0; } } if (w) { xcb_discard_reply (dpy, cookies->query_tree.sequence); return w; } tree = xcb_query_tree_reply (dpy, cookies->query_tree, &err); if (!tree) { if (err->response_type == 0) Print_X_Error (dpy, err); return 0; } nchildren = xcb_query_tree_children_length (tree); children = xcb_query_tree_children (tree); child_cookies = calloc(nchildren, sizeof(struct wininfo_cookies)); if (child_cookies == NULL) Fatal_Error("Failed to allocate memory in recursive_Window_With_Name"); for (i = 0; i < nchildren; i++) { if (atom_net_wm_name && atom_utf8_string) child_cookies[i].get_net_wm_name = xcb_get_net_wm_name (dpy, children[i]); child_cookies[i].get_wm_name = xcb_get_wm_name (dpy, children[i]); child_cookies[i].query_tree = xcb_query_tree (dpy, children[i]); } xcb_flush (dpy); for (i = 0; i < nchildren; i++) { w = recursive_Window_With_Name (dpy, children[i], &child_cookies[i], name); if (w) break; } if (w) { /* clean up remaining replies */ for (/* keep previous i */; i < nchildren; i++) { if (child_cookies[i].get_net_wm_name.sequence) xcb_discard_reply (dpy, child_cookies[i].get_net_wm_name.sequence); xcb_discard_reply (dpy, child_cookies[i].get_wm_name.sequence); xcb_discard_reply (dpy, child_cookies[i].query_tree.sequence); } } free (child_cookies); free (tree); /* includes storage for children[] */ return (w); }
EAPI char * ecore_x_icccm_title_get(Ecore_X_Window win) { xcb_get_property_cookie_t cookie; #ifdef OLD_XCB_VERSION xcb_get_text_property_reply_t prop; #else xcb_icccm_get_text_property_reply_t prop; #endif uint8_t ret = 0; char *title = NULL; LOGFN(__FILE__, __LINE__, __FUNCTION__); CHECK_XCB_CONN; if (!win) return NULL; #ifdef OLD_XCB_VERSION cookie = xcb_get_wm_name_unchecked(_ecore_xcb_conn, win); ret = xcb_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); #else cookie = xcb_icccm_get_wm_name_unchecked(_ecore_xcb_conn, win); ret = xcb_icccm_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); #endif if (ret == 0) return NULL; if (prop.name_len < 1) { #ifdef OLD_XCB_VERSION xcb_get_text_property_reply_wipe(&prop); #else xcb_icccm_get_text_property_reply_wipe(&prop); #endif return NULL; } if (!(title = malloc((prop.name_len + 1) * sizeof(char *)))) { #ifdef OLD_XCB_VERSION xcb_get_text_property_reply_wipe(&prop); #else xcb_icccm_get_text_property_reply_wipe(&prop); #endif return NULL; } memcpy(title, prop.name, sizeof(char *) * prop.name_len); title[prop.name_len] = '\0'; if (prop.encoding != ECORE_X_ATOM_UTF8_STRING) { Ecore_Xcb_Textproperty tp; int count = 0; char **list = NULL; Eina_Bool ret = EINA_FALSE; tp.value = strdup(title); tp.nitems = prop.name_len; tp.encoding = prop.encoding; #ifdef HAVE_ICONV ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count); #else ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count); #endif if (ret) { if (count > 0) title = strdup(list[0]); if (list) free(list); } } #ifdef OLD_XCB_VERSION xcb_get_text_property_reply_wipe(&prop); #else xcb_icccm_get_text_property_reply_wipe(&prop); #endif return title; }