Exemple #1
0
static void
nextwin (void) {
	xcb_query_tree_reply_t *r;
	xcb_window_t *c,t = 0;
	xcb_get_window_attributes_cookie_t ac;
	xcb_get_window_attributes_reply_t *ar;

	r = xcb_query_tree_reply(conn, xcb_query_tree(conn, scr->root), 0);
	if (!r || !r->children_len)
		return;
	c = xcb_query_tree_children(r);
	for (unsigned int i=0; i < r->children_len; i++) {
		ac = xcb_get_window_attributes(conn, c[i]);
		ar = xcb_get_window_attributes_reply(conn, ac, NULL);

		if (ar && ar->map_state == XCB_MAP_STATE_VIEWABLE) {
			if (!(ar->override_redirect || c[i] == (*focuswin))) {
				t = c[i];
			}
			break;
		}
	}

	if (t) {
		focus(t, ACTIVE);
		center_pointer(t);
	}
	free(r);
}
Exemple #2
0
static xcb_visualtype_t *
get_visualtype_for_window(xcb_connection_t *conn, xcb_window_t window,
                          unsigned *depth)
{
   xcb_query_tree_cookie_t tree_cookie;
   xcb_get_window_attributes_cookie_t attrib_cookie;
   xcb_query_tree_reply_t *tree;
   xcb_get_window_attributes_reply_t *attrib;

   tree_cookie = xcb_query_tree(conn, window);
   attrib_cookie = xcb_get_window_attributes(conn, window);

   tree = xcb_query_tree_reply(conn, tree_cookie, NULL);
   attrib = xcb_get_window_attributes_reply(conn, attrib_cookie, NULL);
   if (attrib == NULL || tree == NULL) {
      free(attrib);
      free(tree);
      return NULL;
   }

   xcb_window_t root = tree->root;
   xcb_visualid_t visual_id = attrib->visual;
   free(attrib);
   free(tree);

   xcb_screen_t *screen = get_screen_for_root(conn, root);
   if (screen == NULL)
      return NULL;

   return screen_get_visualtype(screen, visual_id, depth);
}
Exemple #3
0
/*
 * This sets up the DAMAGE extentsion to receive damage events on all
 * child windows
 *
 */
static void set_up_damage_notifications(xcb_connection_t *conn,
                                        xcb_screen_t *scr) {
    xcb_damage_query_version_unchecked(conn, XCB_DAMAGE_MAJOR_VERSION,
                                       XCB_DAMAGE_MINOR_VERSION);

    dam_ext_data = xcb_get_extension_data(conn, &xcb_damage_id);

    xcb_query_tree_reply_t *reply =
        xcb_query_tree_reply(conn, xcb_query_tree(conn, scr->root), NULL);
    xcb_window_t *children = xcb_query_tree_children(reply);
    xcb_get_window_attributes_cookie_t *attribs =
        (xcb_get_window_attributes_cookie_t *)malloc(
            sizeof(xcb_get_window_attributes_cookie_t) * reply->children_len);

    if (!attribs) {
        errx(EXIT_FAILURE, "Failed to allocate memory");
    }

    for (int i = 0; i < reply->children_len; ++i) {
        attribs[i] = xcb_get_window_attributes_unchecked(conn, children[i]);
    }
    for (int i = 0; i < reply->children_len; ++i) {
        /* Get attributes to check if input-only window */
        xcb_get_window_attributes_reply_t *attrib =
            xcb_get_window_attributes_reply(conn, attribs[i], NULL);

        create_damage(conn, children[i], attrib);
    }
    free(attribs);
    free(reply);
}
Exemple #4
0
void find_window_by_property(xcb_window_t window, xcb_atom_t property,
		xcb_window_t *res) {
	*res = XCB_WINDOW_NONE;
	
	xcb_get_property_cookie_t get_property_cookie =
			xcb_get_property(display, 0, window, property, XCB_ATOM_ANY, 0, 0);
	xcb_get_property_reply_t *get_property_reply =
			xcb_get_property_reply(display, get_property_cookie, NULL);
	if (get_property_reply != NULL) {
		if (get_property_reply->type != XCB_ATOM_NONE) {
			*res = window;
			free(get_property_reply);
			return;
		}
		free(get_property_reply);
	}
	
	xcb_query_tree_cookie_t query_tree_cookie =
			xcb_query_tree(display, window);
	xcb_query_tree_reply_t *query_tree_reply =
			xcb_query_tree_reply(display, query_tree_cookie, NULL);
	if (query_tree_reply == NULL)
		return;
	int length = xcb_query_tree_children_length(query_tree_reply);
	xcb_window_t *children = xcb_query_tree_children(query_tree_reply);
	for (int i = 0; i < length; i++) {
		find_window_by_property(children[i], property, res);
		if (*res != XCB_WINDOW_NONE)
			break;
	}
	free(query_tree_reply);
}
Exemple #5
0
/*
 * Go through all existing windows (if the window manager is restarted) and manage them
 *
 */
void manage_existing_windows(xcb_window_t root) {
    xcb_query_tree_reply_t *reply;
    int i, len;
    xcb_window_t *children;
    xcb_get_window_attributes_cookie_t *cookies;

    /* Get the tree of windows whose parent is the root window (= all) */
    if ((reply = xcb_query_tree_reply(conn, xcb_query_tree(conn, root), 0)) == NULL)
        return;

    len = xcb_query_tree_children_length(reply);
    cookies = smalloc(len * sizeof(*cookies));

    /* Request the window attributes for every window */
    children = xcb_query_tree_children(reply);
    for (i = 0; i < len; ++i)
        cookies[i] = xcb_get_window_attributes(conn, children[i]);

    /* Call manage_window with the attributes for every window */
    for (i = 0; i < len; ++i)
        manage_window(children[i], cookies[i], true);

    free(reply);
    free(cookies);
}
Exemple #6
0
bool DisplayVkXcb::isValidNativeWindow(EGLNativeWindowType window) const
{
    // There doesn't appear to be an xcb function explicitly for checking the validity of a
    // window ID, but xcb_query_tree_reply will return nullptr if the window doesn't exist.
    xcb_query_tree_cookie_t cookie = xcb_query_tree(mXcbConnection, window);
    xcb_query_tree_reply_t *reply  = xcb_query_tree_reply(mXcbConnection, cookie, nullptr);
    if (reply)
    {
        free(reply);
        return true;
    }
    return false;
}
Exemple #7
0
/*
 * Find a window that has WM_STATE set in the window tree below win.
 * Unmapped/unviewable windows are not considered valid matches.
 * Children are searched in top-down stacking order.
 * The first matching window is returned, None if no match is found.
 */
static xcb_window_t
Find_Client_In_Children(xcb_connection_t * dpy, xcb_window_t win)
{
    xcb_query_tree_cookie_t qt_cookie;
    xcb_query_tree_reply_t *tree;
    xcb_window_t *children;
    unsigned int n_children;
    int i;

    qt_cookie = xcb_query_tree (dpy, win);
    tree = xcb_query_tree_reply (dpy, qt_cookie, NULL);
    if (!tree)
        return XCB_WINDOW_NONE;
    n_children = xcb_query_tree_children_length (tree);
    if (!n_children) {
        free (tree);
        return XCB_WINDOW_NONE;
    }
    children = xcb_query_tree_children (tree);

    /* Check each child for WM_STATE and other validity */
    win = XCB_WINDOW_NONE;
    for (i = (int) n_children - 1; i >= 0; i--) {
        if (!Window_Is_Viewable(dpy, children[i])) {
            /* Don't bother descending into this one */
            children[i] = XCB_WINDOW_NONE;
            continue;
        }
        if (!Window_Has_Property(dpy, children[i], atom_wm_state))
            continue;

        /* Got one */
        win = children[i];
        goto done;
    }

    /* No children matched, now descend into each child */
    for (i = (int) n_children - 1; i >= 0; i--) {
        if (children[i] == XCB_WINDOW_NONE)
            continue;
        win = Find_Client_In_Children(dpy, children[i]);
        if (win != XCB_WINDOW_NONE)
            break;
    }

  done:
    free (tree); /* includes children */

    return win;
}
QList< xcb_window_t > LinuxWindowCapture::listWindowsRecursive( const xcb_window_t& window ) {
  QList< xcb_window_t > windows;
  xcb_connection_t* xcbConn = QX11Info::connection();
  xcb_query_tree_cookie_t queryC = xcb_query_tree( xcbConn, window );
  CScopedPointer< xcb_query_tree_reply_t > queryR( xcb_query_tree_reply( xcbConn, queryC, nullptr ) );

  if ( queryR ) {
    xcb_window_t* children = xcb_query_tree_children( queryR.data() );
    for( auto c = 0; c < xcb_query_tree_children_length( queryR.data() ); ++c ) {
      windows << children[ c ];
      windows << listWindowsRecursive( children[ c ] );
    }
  }
  return windows;
}
Exemple #9
0
void find_toplevel_window(xcb_window_t window, xcb_window_t *res) {
	for (;;) {
		xcb_query_tree_cookie_t cookie = xcb_query_tree(display, window);
		xcb_query_tree_reply_t *reply =
				xcb_query_tree_reply(display, cookie, NULL);
		if (reply == NULL)
			break;
		if (reply->parent == XCB_WINDOW_NONE || reply->parent == reply->root) {
			free(reply);
			break;
		}
		window = reply->parent;
		free(reply);
	}
	*res = window;
}
Exemple #10
0
/*
  Generate a XCWM_EVENT_WINDOW_CREATE event for all
  existing mapped top-level windows when we start
*/
static void
_xcwm_windows_adopt(xcwm_context_t *context, xcwm_event_cb_t callback_ptr)
{
    xcb_query_tree_cookie_t tree_cookie = xcb_query_tree(context->conn, context->root_window->window_id);
    xcb_query_tree_reply_t *reply = xcb_query_tree_reply(context->conn, tree_cookie, NULL);
    if (NULL == reply) {
        return;
    }

    int len = xcb_query_tree_children_length(reply);
    xcb_window_t *children = xcb_query_tree_children(reply);

    int i;
    for (i = 0; i < len; i ++) {
        xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(context->conn, children[i]);
        xcb_get_window_attributes_reply_t *attr = xcb_get_window_attributes_reply(context->conn, cookie, NULL);

        if (!attr) {
            fprintf(stderr, "Couldn't get attributes for window 0x%08x\n", children[i]);
            continue;
        }

        if (attr->map_state == XCB_MAP_STATE_VIEWABLE) {
            printf("window 0x%08x viewable\n", children[i]);

            xcwm_window_t *window = _xcwm_window_create(context, children[i], context->root_window->window_id);
            if (!window) {
                continue;
            }

            _xcwm_window_composite_pixmap_update(window);

            xcwm_event_t return_evt;
            return_evt.window = window;
            return_evt.event_type = XCWM_EVENT_WINDOW_CREATE;

            callback_ptr(&return_evt);
        }
        else {
            printf("window 0x%08x non-viewable\n", children[i]);
        }

        free(attr);
    }

    free(reply);
}
static void
lookat(xcb_connection_t *dpy, xcb_window_t root, int verbose, int maxcmdlen)
{
    root_list_state *rl = malloc(sizeof(*rl));

    if (!rl)
	return; /* TODO: OOM message */

    /*
     * get the list of windows
     */

    rl->c = dpy;
    rl->cookie = xcb_query_tree(dpy, root);
    rl->verbose = verbose;
    rl->maxcmdlen = maxcmdlen;
    enqueue(root_list, rl);
}
QList< xcb_window_t > LinuxWindowCapture::listWindowsRecursive( xcb_connection_t* dpy, xcb_window_t& window )
{
  QList< xcb_window_t > windows;
  xcb_query_tree_reply_t* queryR;

  xcb_query_tree_cookie_t queryC = xcb_query_tree( dpy, window );

  if( ( queryR = xcb_query_tree_reply( dpy, queryC, NULL ) ) ) {
    xcb_window_t* children = xcb_query_tree_children( queryR );

    for( int c = 0; c < xcb_query_tree_children_length( queryR ); ++c  ) {
      windows << children[ c ];
      windows << listWindowsRecursive( dpy, children[ c ]);
    }
    free( queryR );
  }
  return windows;
}
Exemple #13
0
xcb_window_t
Window_With_Name (
    xcb_connection_t *dpy,
    xcb_window_t top,
    const char *name)
{
    struct wininfo_cookies cookies;

    atom_net_wm_name = Get_Atom (dpy, "_NET_WM_NAME");
    atom_utf8_string = Get_Atom (dpy, "UTF8_STRING");

    if (atom_net_wm_name && atom_utf8_string)
	cookies.get_net_wm_name = xcb_get_net_wm_name (dpy, top);
    cookies.get_wm_name = xcb_get_wm_name (dpy, top);
    cookies.query_tree = xcb_query_tree (dpy, top);
    xcb_flush (dpy);
    return recursive_Window_With_Name(dpy, top, &cookies, name);
}
Exemple #14
0
void adopt_orphans(void)
{
	xcb_query_tree_reply_t *qtr = xcb_query_tree_reply(dpy, xcb_query_tree(dpy, root), NULL);
	if (qtr == NULL) {
		return;
	}

	int len = xcb_query_tree_children_length(qtr);
	xcb_window_t *wins = xcb_query_tree_children(qtr);

	for (int i = 0; i < len; i++) {
		uint32_t idx;
		xcb_window_t win = wins[i];
		if (xcb_ewmh_get_wm_desktop_reply(ewmh, xcb_ewmh_get_wm_desktop(ewmh, win), &idx, NULL) == 1) {
			schedule_window(win);
		}
	}

	free(qtr);
}
Exemple #15
0
static void
discover (void) {
	xcb_query_tree_reply_t      *r;
	xcb_window_t                *c;

	r = xcb_query_tree_reply(conn, xcb_query_tree(conn, scr->root), NULL);

	if (r == NULL) {
		warnx("cannot get a list of windows");
		return;
	}

	c = xcb_query_tree_children(r);

	for (unsigned int i = 0; i < r->children_len; i++) {
		setup_win(c[i]);
		focus(c[i], INACTIVE);
	}
	nextwin();
}
static void root_list(void *closure)
{
    int i;
    xcb_window_t *child;
    xcb_query_tree_reply_t *reply;
    root_list_state *rl = closure;

    reply = xcb_query_tree_reply(rl->c, rl->cookie, NULL);
    if (!reply)
	goto done;

    child = xcb_query_tree_children(reply);
    for (i = 0; i < reply->children_len; i++) {
	/* Get information about each child */
	child_wm_state *cs = malloc(sizeof(*cs) + sizeof(*cs->prop_cookie) + sizeof(*cs->tree_cookie) + sizeof(*cs->win));
	if (!cs)
	    goto done; /* TODO: print OOM message */
	cs->c = rl->c;
	cs->verbose = rl->verbose;
	cs->maxcmdlen = rl->maxcmdlen;
	cs->prop_cookie = (void *)&cs[1];
	cs->tree_cookie = (void *)&cs->prop_cookie[1];
	cs->win = (void *)&cs->tree_cookie[1];

	cs->orig_win = child[i];
	cs->win[0] = child[i];

	cs->prop_cookie[0] = xcb_get_property(rl->c, 0, child[i],
			WM_STATE, XCB_GET_PROPERTY_TYPE_ANY,
			0, 0);
	/* Just in case the property isn't there, get the tree too */
	cs->tree_cookie[0] = xcb_query_tree(rl->c, child[i]);

	cs->list_length = 1;
	enqueue(child_info, cs);
    }
    free(reply);

done:
    free(rl);
}
Exemple #17
0
void xconn_clean(xconn_t c)
{
#if 0
	xcb_query_tree_cookie_t wintree;
	xcb_query_tree_reply_t *rep;
	xcb_window_t *children;
	xcb_window_t root;
	int i,len;
	if(!c) return;
	root=xconn_get_root(c);
	wintree = xcb_query_tree(c->c, root);
	rep = xcb_query_tree_reply(c->c, wintree, 0);
	if(!rep) return;
	len = xcb_query_tree_children_length(rep);
	children = xcb_query_tree_children(rep);
	for(i=0;i<len;i++)
		xcb_kill_client(c->c,children[i]);
	free(rep);
	xcb_flush(c->c);
#endif
}
Exemple #18
0
static SCM scm_dump_client(SCM client_smob)
{
    client_t *client = (client_t *)SCM_SMOB_DATA(client_smob);

    SCM out_port = scm_current_output_port();

    char *str = NULL;
    int len;
    const char *fmt = "window: %u\nposition: (%d, %d)\nsize: %u x %u\nborder width: %u\n";
    if ((len = asprintf(&str, fmt, 
                        client->window,
                        client->rect.x, client->rect.y,
                        client->rect.width, client->rect.height,
                        client->border_width)) < 0) {
        fprintf(stderr, "asprintf failed\n");
        /* not sure what to return here, will figure it out later */
        return SCM_UNSPECIFIED;
    }
    scm_c_write(out_port, str, len);
    free(str);

    xcb_query_tree_cookie_t c = xcb_query_tree(wm_conf.connection, client->window);
    xcb_query_tree_reply_t *r = xcb_query_tree_reply(wm_conf.connection, c, NULL);

    if ((len = asprintf(&str, "root: %u\nparent: %u\nchildren_len: %u\n",
                        r->root,
                        r->parent,
                        r->children_len)) < 0) {
        fprintf(stderr, "asprintf failed\n");
        return SCM_UNSPECIFIED;
    }
    scm_c_write(out_port, str, len);
    free(str);

    if (r)
        free(r);

    return SCM_UNSPECIFIED;
}
bool LinuxWindowCapture::ExtractWindowProperties( xcb_window_t winId, QRect* winRect, bool* winFocus ) {
  if( !winId )
    return false;

  xcb_connection_t* xcbConn = QX11Info::connection();

  xcb_get_geometry_cookie_t geometryC = xcb_get_geometry( xcbConn, winId );
  CScopedPointer< xcb_get_geometry_reply_t > geometryR( xcb_get_geometry_reply( xcbConn, geometryC, nullptr ) );
  if( !geometryR ) return false;

  // assume the parent window is the screen then we can just use the coordinates directly
  int x = geometryR->x;
  int y = geometryR->y;

  CScopedPointer< xcb_query_tree_reply_t > treeR( xcb_query_tree_reply( xcbConn, xcb_query_tree( xcbConn, winId ), nullptr ) );
  if ( !treeR ) return false;

  // if the parent isn't screen translate coords
  if ( treeR->parent != QX11Info::appRootWindow() ) {
    xcb_translate_coordinates_cookie_t
                    translateC = xcb_translate_coordinates( xcbConn, winId, QX11Info::appRootWindow(), x, y );
    CScopedPointer< xcb_translate_coordinates_reply_t >
                    translateR( xcb_translate_coordinates_reply( xcbConn, translateC, nullptr ) );
    if ( !translateR ) return false;

    x = translateR->dst_x;
    y = translateR->dst_y;
  }
  winRect->setRect( x, y, geometryR->width, geometryR->height );

  xcb_get_input_focus_cookie_t focusC = xcb_get_input_focus( xcbConn );
  CScopedPointer < xcb_get_input_focus_reply_t > focusR( xcb_get_input_focus_reply( xcbConn, focusC, nullptr ) );
  if ( !focusR ) return false;

  *winFocus = ( focusR->focus == winId );
  return true;
}
Exemple #20
0
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);
}
Exemple #21
0
void krad_x11_enable_capture (krad_x11_t *x11, uint32_t window_id) {

  xcb_get_geometry_reply_t *geo;
  xcb_query_tree_reply_t *tree;
  xcb_translate_coordinates_cookie_t translateCookie;
  xcb_translate_coordinates_reply_t *trans;

  geo = xcb_get_geometry_reply (x11->connection,
        xcb_get_geometry (x11->connection, window_id), NULL);
  if (geo == NULL) {
    window_id = 0;
  } else {
    tree = xcb_query_tree_reply (x11->connection,
                                 xcb_query_tree (x11->connection, window_id), NULL);
    if (tree == NULL) {
      window_id = 0;
      free (geo);
    } else {

      translateCookie = xcb_translate_coordinates (x11->connection,
                                                  window_id,
                                                  x11->screen->root,
                                                  geo->x, geo->y);

      trans = xcb_translate_coordinates_reply (x11->connection,
                                               translateCookie,
                                               NULL);    

      if (trans == NULL) {
        window_id = 0;
        free (tree);
        free (geo);
      } else {
        x11->width = geo->width;
        x11->height = geo->height;
        x11->x = trans->dst_x - geo->x;
        x11->y = trans->dst_y - geo->y;
        free (trans);
        free (tree);
        free (geo);
      }
    }
  }

  if (window_id == 0) {
    x11->width = x11->screen_width;
    x11->height = x11->screen_height;
    x11->window = x11->screen->root;
  }

  //printf ("capture width %d height %d x %d y %d\n",
  //       x11->width, x11->height, x11->x, x11->y);

  x11->img = xcb_image_create_native (x11->connection,
                                      x11->width, x11->height,
                                      XCB_IMAGE_FORMAT_Z_PIXMAP,
                                      x11->screen_bit_depth, 0, ~0, 0);
  if (!x11->img) {
    exit (15);
  }
  
  x11->stride = x11->img->stride;

  x11->shminfo.shmid = shmget (IPC_PRIVATE,
                               x11->img->stride * x11->img->height,
                               (IPC_CREAT | 0666));

  if (x11->shminfo.shmid == (uint32_t)-1) {
    xcb_image_destroy (x11->img);
    failfast ("shminfo fail");
  }

  x11->shminfo.shmaddr = shmat (x11->shminfo.shmid, 0, 0);
  x11->img->data = x11->shminfo.shmaddr;

  if (x11->img->data == (uint8_t *)-1) {
    xcb_image_destroy (x11->img);
    failfast ("xcb image fail");
  }

  x11->shminfo.shmseg = xcb_generate_id (x11->connection);
  xcb_shm_attach (x11->connection, x11->shminfo.shmseg, x11->shminfo.shmid, 0);
  x11->capture_enabled = 1;
}
static void child_info(void *closure)
{
    child_wm_state *cs = closure;
    xcb_window_t orig = cs->orig_win;
    xcb_connection_t *c = cs->c;
    int verbose = cs->verbose;
    int maxcmdlen = cs->maxcmdlen;
    int i, j;

    int child_count, num_rep;
    xcb_query_tree_reply_t **reply;

    for (i = 0; i < cs->list_length; i++) {
	xcb_get_property_reply_t *reply;
	reply = xcb_get_property_reply(c, cs->prop_cookie[i], NULL);
	if (reply) {
	    if (reply->type) {
		/* Show information for this window */
		print_client_properties(c, cs->win[i], cs->verbose, cs->maxcmdlen);

		free(reply);

		/* drain stale replies */
		for (j = i+1; j < cs->list_length; j++) {
		    reply = xcb_get_property_reply(c, cs->prop_cookie[j], NULL);
		    if (reply)
			free(reply);
		}
		for (j = 0; j < cs->list_length; j++) {
		    xcb_query_tree_reply_t *rep;
		    rep = xcb_query_tree_reply(c, cs->tree_cookie[j], NULL);
		    if (rep)
			free(rep);
		}
		goto done;
	    }
	    free(reply);
	}
    }

    /* WM_STATE not found. Recurse into children: */
    num_rep = 0;
    reply = malloc(sizeof(*reply) * cs->list_length);
    if (!reply)
	goto done; /* TODO: print OOM message, drain reply queue */

    for (i = 0; i < cs->list_length; i++) {
	reply[num_rep] = xcb_query_tree_reply(c, cs->tree_cookie[i], NULL);
	if (reply[num_rep])
	    num_rep++;
    }

    child_count = 0;
    for (i = 0; i < num_rep; i++)
	child_count += reply[i]->children_len;

    if (!child_count) {
	/* No children have CS_STATE; try the parent window */
	print_client_properties(c, cs->orig_win, cs->verbose, cs->maxcmdlen);
	goto reply_done;
    }

    cs = malloc(sizeof(*cs) + child_count * (sizeof(*cs->prop_cookie) + sizeof(*cs->tree_cookie) + sizeof(*cs->win)));
    if (!cs)
	goto reply_done; /* TODO: print OOM message */

    cs->c = c;
    cs->verbose = verbose;
    cs->maxcmdlen = maxcmdlen;
    cs->orig_win = orig;
    cs->prop_cookie = (void *)&cs[1];
    cs->tree_cookie = (void *)&cs->prop_cookie[child_count];
    cs->win = (void *)&cs->tree_cookie[child_count];
    cs->list_length = child_count;

    child_count = 0;
    for (i = 0; i < num_rep; i++) {
	xcb_window_t *child = xcb_query_tree_children(reply[i]);
	for (j = 0; j < reply[i]->children_len; j++) {
	    cs->win[child_count] = child[j];
	    cs->prop_cookie[child_count] = xcb_get_property(c, 0, child[j],
			    WM_STATE, XCB_GET_PROPERTY_TYPE_ANY,
			    0, 0);
	    /* Just in case the property isn't there, get the tree too */
	    cs->tree_cookie[child_count++] = xcb_query_tree(c, child[j]);
	}
    }

    enqueue(child_info, cs);

reply_done:
    for (i = 0; i < num_rep; i++)
	free(reply[i]);
    free(reply);

done:
    free(closure);
}
Exemple #23
0
/*
 * List all hidden windows.
 *
 */
int findhidden(void) {
    xcb_query_tree_reply_t *reply;
    int i;
    int len;
    xcb_window_t *children;
    xcb_get_window_attributes_reply_t *attr;
    uint32_t state;
    xcb_get_property_cookie_t cookie;
    xcb_icccm_get_text_property_reply_t prop;
    xcb_generic_error_t *error;

    /* Get all children. */
    reply = xcb_query_tree_reply(conn,
                                 xcb_query_tree(conn, screen->root), 0);
    if (NULL == reply) {
        return -1;
    }

    len = xcb_query_tree_children_length(reply);
    children = xcb_query_tree_children(reply);

    /* List all hidden windows on this root. */
    for (i = 0; i < len; i ++) {
        attr = xcb_get_window_attributes_reply(
                   conn, xcb_get_window_attributes(conn, children[i]), NULL);

        if (!attr) {
            fprintf(stderr, "Couldn't get attributes for window %d.",
                    children[i]);
            continue;
        }

        /*
         * Don't bother windows in override redirect mode.
         *
         * This mode means they wouldn't have been reported to us
         * with a MapRequest if we had been running, so in the
         * normal case we wouldn't have seen them.
         */
        if (!attr->override_redirect) {
            state = get_wm_state(children[i]);
            if (state == XCB_ICCCM_WM_STATE_ICONIC) {
                /*
                 * Example names:
                 *
                 * _NET_WM_ICON_NAME(UTF8_STRING) = 0x75, 0x72, 0x78,
                 * 0x76, 0x74 WM_ICON_NAME(STRING) = "urxvt"
                 * _NET_WM_NAME(UTF8_STRING) = 0x75, 0x72, 0x78, 0x76,
                 * 0x74 WM_NAME(STRING) = "urxvt"
                 */
                cookie = xcb_icccm_get_wm_icon_name(conn, children[i]);
                xcb_icccm_get_wm_icon_name_reply(conn, cookie, &prop, &error);

                prop.name[prop.name_len] = '\0';
                if (printcommand) {
                    /* FIXME: Need to escape : in prop.name. */
                    printf("'%s':'xdotool windowmap 0x%x windowraise 0x%x'\n",
                           prop.name, children[i], children[i]);
                } else {
                    puts(prop.name);
                }
            }
        } /* if not override redirect */

        free(attr);
    } /* for */

    free(reply);

    return 0;
}
Exemple #24
0
xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md, bool ignoreNonXdndAwareWindows)
{
    if (w == shapedPixmapWindow()->handle()->winId())
        return 0;

    if (md) {
        xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(xcb_connection(), w);
        xcb_get_window_attributes_reply_t *reply = xcb_get_window_attributes_reply(xcb_connection(), cookie, 0);
        if (!reply)
            return 0;

        if (reply->map_state != XCB_MAP_STATE_VIEWABLE)
            return 0;

        free(reply);

        xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(xcb_connection(), w);
        xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(xcb_connection(), gcookie, 0);
        if (!greply)
            return 0;

        QRect windowRect(greply->x, greply->y, greply->width, greply->height);
        free(greply);
        if (windowRect.contains(pos)) {
            bool windowContainsMouse = !ignoreNonXdndAwareWindows;
            {
                xcb_get_property_cookie_t cookie =
                        Q_XCB_CALL(xcb_get_property(xcb_connection(), false, w, connection()->atom(QXcbAtom::XdndAware),
                                                    XCB_GET_PROPERTY_TYPE_ANY, 0, 0));
                xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);

                bool isAware = reply && reply->type != XCB_NONE;
                free(reply);
                if (isAware) {
                    const QPoint relPos = pos - windowRect.topLeft();
                    // When ShapeInput and ShapeBounding are not set they return a single rectangle with the geometry of the window, this is why we
                    // need to check both here so that in the case one is set and the other is not we still get the correct result.
                    if (connection()->hasInputShape())
                        windowContainsMouse = windowInteractsWithPosition(xcb_connection(), relPos, w, XCB_SHAPE_SK_INPUT);
                    if (windowContainsMouse && connection()->hasXShape())
                        windowContainsMouse = windowInteractsWithPosition(xcb_connection(), relPos, w, XCB_SHAPE_SK_BOUNDING);
                    if (!connection()->hasInputShape() && !connection()->hasXShape())
                        windowContainsMouse = true;
                    if (windowContainsMouse)
                        return w;
                }
            }

            xcb_query_tree_cookie_t cookie = xcb_query_tree (xcb_connection(), w);
            xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, 0);

            if (!reply)
                return 0;
            int nc = xcb_query_tree_children_length(reply);
            xcb_window_t *c = xcb_query_tree_children(reply);

            xcb_window_t r = 0;
            for (uint i = nc; !r && i--;)
                r = findRealWindow(pos - windowRect.topLeft(), c[i], md-1, ignoreNonXdndAwareWindows);

            free(reply);
            if (r)
                return r;

            // We didn't find a client window!  Just use the
            // innermost window.

            // No children!
            if (!windowContainsMouse)
                return 0;
            else
                return w;
        }
    }
    return 0;
}