Esempio n. 1
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);
}
Esempio n. 2
0
void X11XRenderBackend::init(bool createOverlay)
{
    if (m_front != XCB_RENDER_PICTURE_NONE)
        xcb_render_free_picture(connection(), m_front);
    bool haveOverlay = createOverlay ? m_overlayWindow->create() : (m_overlayWindow->window() != XCB_WINDOW_NONE);
    if (haveOverlay) {
        m_overlayWindow->setup(XCB_WINDOW_NONE);
        ScopedCPointer<xcb_get_window_attributes_reply_t> attribs(xcb_get_window_attributes_reply(connection(),
            xcb_get_window_attributes_unchecked(connection(), m_overlayWindow->window()), NULL));
        if (!attribs) {
            setFailed("Failed getting window attributes for overlay window");
            return;
        }
        m_format = XRenderUtils::findPictFormat(attribs->visual);
        if (m_format == 0) {
            setFailed("Failed to find XRender format for overlay window");
            return;
        }
        m_front = xcb_generate_id(connection());
        xcb_render_create_picture(connection(), m_front, m_overlayWindow->window(), m_format, 0, NULL);
    } else {
        // create XRender picture for the root window
        m_format = XRenderUtils::findPictFormat(defaultScreen()->root_visual);
        if (m_format == 0) {
            setFailed("Failed to find XRender format for root window");
            return; // error
        }
        m_front = xcb_generate_id(connection());
        const uint32_t values[] = {XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS};
        xcb_render_create_picture(connection(), m_front, rootWindow(), m_format, XCB_RENDER_CP_SUBWINDOW_MODE, values);
    }
    createBuffer();
}
Esempio n. 3
0
int handle_map_request_event(void *data, xcb_connection_t *c, xcb_map_request_event_t *event)
{
    xcb_get_window_attributes_cookie_t win_attrs_cookie;
    xcb_get_window_attributes_reply_t *win_attrs_reply;
    win_attrs_cookie = xcb_get_window_attributes_unchecked(c, event->window);
    win_attrs_reply = xcb_get_window_attributes_reply(c, win_attrs_cookie, NULL);
    if (!win_attrs_reply) {
        fprintf(stderr, "map request: failed to get window attributes\n");
        return -1;
    }

    if (win_attrs_reply->override_redirect) {
        fprintf(stderr, "map request: window has override redirect set - ignoring map request\n");
        return 0;
    }

    client_t *client = NULL;

    client = find_client(event->window);
    if (!client)
        client = manage_window(event->window);

    xcb_map_window(c, event->window);

    run_arrange_hook();

    free(win_attrs_reply);

    return 0;
}
Esempio n. 4
0
/** The map request event handler.
 * \param ev The event.
 */
static void
event_handle_maprequest(xcb_map_request_event_t *ev)
{
    client_t *c;
    xcb_get_window_attributes_cookie_t wa_c;
    xcb_get_window_attributes_reply_t *wa_r;
    xcb_get_geometry_cookie_t geom_c;
    xcb_get_geometry_reply_t *geom_r;

    wa_c = xcb_get_window_attributes_unchecked(globalconf.connection, ev->window);

    if(!(wa_r = xcb_get_window_attributes_reply(globalconf.connection, wa_c, NULL)))
        return;

    if(wa_r->override_redirect)
        goto bailout;

    if(xembed_getbywin(&globalconf.embedded, ev->window))
    {
        xcb_map_window(globalconf.connection, ev->window);
        xembed_window_activate(globalconf.connection, ev->window);
    }
    else if((c = client_getbywin(ev->window)))
    {
        /* Check that it may be visible, but not asked to be hidden */
        if(client_on_selected_tags(c) && !c->hidden)
        {
            lua_State *L = globalconf_get_lua_State();
            luaA_object_push(L, c);
            client_set_minimized(L, -1, false);
            lua_pop(L, 1);
            /* it will be raised, so just update ourself */
            client_raise(c);
        }
    }
    else
    {
        geom_c = xcb_get_geometry_unchecked(globalconf.connection, ev->window);

        if(!(geom_r = xcb_get_geometry_reply(globalconf.connection, geom_c, NULL)))
        {
            goto bailout;
        }

        client_manage(ev->window, geom_r, wa_r);

        p_delete(&geom_r);
    }

bailout:
    p_delete(&wa_r);
}
Esempio n. 5
0
File: window.c Progetto: dosbre/xray
int add_winvec(struct window **list, xcb_window_t wid[], int len)
{
	xcb_get_window_attributes_cookie_t ack[len];
	xcb_get_geometry_cookie_t gck[len];
	struct window *w;
	int i, n = 0;

	for (i = 0; i < len; ++i) {
		ack[i] = xcb_get_window_attributes_unchecked(X, wid[i]);
		gck[i] = xcb_get_geometry_unchecked(X, wid[i]);
	}
	for (i = 0; i < len; ++i) {
		xcb_get_window_attributes_reply_t *ar;
		xcb_get_geometry_reply_t *gr;

		if ((w = add_win(list, wid[i])) != NULL) {
			ar = xcb_get_window_attributes_reply(X, ack[i], NULL);
			gr = xcb_get_geometry_reply(X, gck[i], NULL);
			if (ar && gr) {
				w->visual = ar->visual;
				w->_class = ar->_class;
				w->map_state = ar->map_state;
				w->x = gr->x;
				w->y = gr->y;
				w->width = gr->width;
				w->height = gr->height;
				w->border_width = gr->border_width;
				free(ar);
				free(gr);
				++n;
			} else {
				if (ar)
					free(ar);
				if (gr)
					free(gr);
				remove_win(list, w);
				continue;
			}
		}
	}
	debugf("add_winvec: added %d of %d windows to stack\n", n, len);
	return n;
}
Esempio n. 6
0
File: event.c Progetto: nqv/nilwm
static
void handle_map_request(xcb_map_request_event_t *e) {
    xcb_get_window_attributes_reply_t *reply;
    struct client_t *c;
    struct workspace_t *ws;

    NIL_LOG("event: map request win=%d", e->window);
    reply = xcb_get_window_attributes_reply(nil_.con,
        xcb_get_window_attributes_unchecked(nil_.con, e->window), 0);
    if (!reply) {
        NIL_ERR("no reply %d", e->window);
        return;
    }
    if (reply->override_redirect) {
        NIL_ERR("override_redirect %d", e->window);
        free(reply);
        return;
    }
    free(reply);
    c = find_client(e->window, &ws);
    if (!c) {
        NIL_ERR("no client %d", e->window);
        return;
    }
    init_client(c);
    NIL_SET_FLAG(c->flags, CLIENT_DISPLAY);
    if (!NIL_HAS_FLAG(c->flags, CLIENT_FLOAT)) {
        /* only rearrange if it's not float */
        arrange_ws(ws);
    }
    if (check_client_size(c)) {             /* fix window size if needed */
        update_client_geom(c);
    }
    config_client(c);
    if (ws == &nil_.ws[nil_.ws_idx]) {
        xcb_map_window(nil_.con, c->win);
        xcb_set_input_focus(nil_.con, XCB_INPUT_FOCUS_POINTER_ROOT, c->win,
            XCB_CURRENT_TIME);
    }
    xcb_flush(nil_.con);
}
void FdoSelectionManager::addDamageWatch(xcb_window_t client)
{
    qCDebug(SNIPROXY) << "adding damage watch for " << client;

    xcb_connection_t *c = QX11Info::connection();
    const auto attribsCookie = xcb_get_window_attributes_unchecked(c, client);

    auto damageId = xcb_generate_id(c);
    m_damageWatches[client] = damageId;
    xcb_damage_create(c, damageId, client, XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY);

    QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> attr(xcb_get_window_attributes_reply(c, attribsCookie, Q_NULLPTR));
    uint32_t events = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
    if (!attr.isNull()) {
        events = events | attr->your_event_mask;
    }
    // the event mask will not be removed again. We cannot track whether another component also needs STRUCTURE_NOTIFY (e.g. KWindowSystem).
    // if we would remove the event mask again, other areas will break.
    xcb_change_window_attributes(c, client, XCB_CW_EVENT_MASK, &events);

}
Esempio n. 8
0
/* FIXME: round trips */
static Shadow *
_ecore_x_window_tree_walk(Ecore_X_Window window)
{
   Shadow *s, **sl;
   xcb_get_window_attributes_reply_t *reply_attr;
   xcb_get_geometry_reply_t *reply_geom;
   xcb_query_tree_reply_t *reply_tree;
   xcb_get_window_attributes_cookie_t cookie_attr;
   xcb_get_geometry_cookie_t cookie_geom;
   xcb_query_tree_cookie_t cookie_tree;
   int i, j;

   CHECK_XCB_CONN;

   cookie_attr = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
   reply_attr = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie_attr, NULL);
   if (!reply_attr) return NULL;
   if (reply_attr->map_state != XCB_MAP_STATE_VIEWABLE)
     {
        free(reply_attr);
        return NULL;
     }

   free(reply_attr);

   cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window);
   reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL);
   if (!reply_geom) return NULL;

   if (!(s = calloc(1, sizeof(Shadow))))
     {
        free(reply_geom);
        return NULL;
     }

   s->win = window;
   s->x = reply_geom->x;
   s->y = reply_geom->y;
   s->w = reply_geom->width;
   s->h = reply_geom->height;

   free(reply_geom);

   cookie_tree = xcb_query_tree_unchecked(_ecore_xcb_conn, window);
   reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL);
   if (reply_tree)
     {
        xcb_window_t *list;
        int num;

        num = xcb_query_tree_children_length(reply_tree);
        list = xcb_query_tree_children(reply_tree);

        s->children = calloc(1, sizeof(Shadow *) * num);
        if (s->children)
          {
             s->children_num = num;
             for (i = 0; i < num; i++)
               {
                  s->children[i] = _ecore_x_window_tree_walk(list[i]);
                  if (s->children[i])
                    s->children[i]->parent = s;
               }
             /* compress list down */
             j = 0;
             for (i = 0; i < num; i++)
               {
                  if (s->children[i])
                    {
                       s->children[j] = s->children[i];
                       j++;
                    }
               }
             if (j == 0)
               {
                  free(s->children);
                  s->children = NULL;
                  s->children_num = 0;
               }
             else
               {
                  s->children_num = j;
                  sl = realloc(s->children, sizeof(Shadow *) * j);
                  if (sl) s->children = sl;
               }
          }

        free(reply_tree);
     }

   return s;
}
Esempio n. 9
0
/** Scan X to find windows to manage.
 */
static void
scan(xcb_query_tree_cookie_t tree_c[])
{
    int i, x_screen, tree_c_len;
    const int screen_max = xcb_setup_roots_length(xcb_get_setup(globalconf.connection));
    xcb_query_tree_reply_t *tree_r;
    xcb_window_t *wins = NULL;
    xcb_get_window_attributes_reply_t *attr_r;
    xcb_get_geometry_reply_t *geom_r;
    long state;

    for(x_screen = 0; x_screen < screen_max; x_screen++)
    {
        tree_r = xcb_query_tree_reply(globalconf.connection,
                                      tree_c[x_screen],
                                      NULL);

        if(!tree_r)
            continue;

        /* Get the tree of the children windows of the current root window */
        if(!(wins = xcb_query_tree_children(tree_r)))
            fatal("cannot get tree children");

        tree_c_len = xcb_query_tree_children_length(tree_r);
        xcb_get_window_attributes_cookie_t attr_wins[tree_c_len];
        xcb_get_property_cookie_t state_wins[tree_c_len];

        for(i = 0; i < tree_c_len; i++)
        {
            attr_wins[i] = xcb_get_window_attributes_unchecked(globalconf.connection,
                                                               wins[i]);

            state_wins[i] = window_state_get_unchecked(wins[i]);
        }

        xcb_get_geometry_cookie_t *geom_wins[tree_c_len];

        for(i = 0; i < tree_c_len; i++)
        {
            attr_r = xcb_get_window_attributes_reply(globalconf.connection,
                                                     attr_wins[i],
                                                     NULL);

            state = window_state_get_reply(state_wins[i]);

            if(!attr_r || attr_r->override_redirect
               || attr_r->map_state == XCB_MAP_STATE_UNMAPPED
               || state == XCB_ICCCM_WM_STATE_WITHDRAWN)
            {
                geom_wins[i] = NULL;
                p_delete(&attr_r);
                continue;
            }

            p_delete(&attr_r);

            /* Get the geometry of the current window */
            geom_wins[i] = p_alloca(xcb_get_geometry_cookie_t, 1);
            *(geom_wins[i]) = xcb_get_geometry_unchecked(globalconf.connection, wins[i]);
        }

        for(i = 0; i < tree_c_len; i++)
        {
            if(!geom_wins[i] || !(geom_r = xcb_get_geometry_reply(globalconf.connection,
                                                                  *(geom_wins[i]), NULL)))
                continue;

            /* The window can be mapped, so force it to be undrawn for startup */
            xcb_unmap_window(globalconf.connection, wins[i]);

            client_manage(wins[i], geom_r,
                          phys_screen_getbycoord(geom_r->x, geom_r->y, geom_r->root),
                          x_screen, true);

            p_delete(&geom_r);
        }

        p_delete(&tree_r);
    }
}
Esempio n. 10
0
QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) const
{
    if (width == 0 || height == 0)
        return QPixmap();

    // TODO: handle multiple screens
    QXcbScreen *screen = const_cast<QXcbScreen *>(this);
    xcb_window_t root = screen->root();

    if (window == 0)
        window = root;

    xcb_get_geometry_cookie_t geometry_cookie = xcb_get_geometry_unchecked(xcb_connection(), window);

    xcb_get_geometry_reply_t *reply =
        xcb_get_geometry_reply(xcb_connection(), geometry_cookie, NULL);

    if (!reply) {
        return QPixmap();
    }

    if (width < 0)
        width = reply->width - x;
    if (height < 0)
        height = reply->height - y;

    geometry_cookie = xcb_get_geometry_unchecked(xcb_connection(), root);
    xcb_get_geometry_reply_t *root_reply =
        xcb_get_geometry_reply(xcb_connection(), geometry_cookie, NULL);

    if (!root_reply) {
        free(reply);
        return QPixmap();
    }

    if (reply->depth == root_reply->depth) {
        // if the depth of the specified window and the root window are the
        // same, grab pixels from the root window (so that we get the any
        // overlapping windows and window manager frames)

        // map x and y to the root window
        xcb_translate_coordinates_cookie_t translate_cookie =
            xcb_translate_coordinates_unchecked(xcb_connection(), window, root, x, y);

        xcb_translate_coordinates_reply_t *translate_reply =
            xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, NULL);

        if (!translate_reply) {
            free(reply);
            free(root_reply);
            return QPixmap();
        }

        x = translate_reply->dst_x;
        y = translate_reply->dst_y;

        window = root;

        free(translate_reply);
        free(reply);
        reply = root_reply;
    } else {
        free(root_reply);
        root_reply = 0;
    }

    xcb_get_window_attributes_reply_t *attributes_reply =
        xcb_get_window_attributes_reply(xcb_connection(), xcb_get_window_attributes_unchecked(xcb_connection(), window), NULL);

    if (!attributes_reply) {
        free(reply);
        return QPixmap();
    }

    const xcb_visualtype_t *visual = screen->visualForId(attributes_reply->visual);
    free(attributes_reply);

    xcb_pixmap_t pixmap = xcb_generate_id(xcb_connection());
    xcb_create_pixmap(xcb_connection(), reply->depth, pixmap, window, width, height);

    uint32_t gc_value_mask = XCB_GC_SUBWINDOW_MODE;
    uint32_t gc_value_list[] = { XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS };

    xcb_gcontext_t gc = xcb_generate_id(xcb_connection());
    xcb_create_gc(xcb_connection(), gc, pixmap, gc_value_mask, gc_value_list);

    xcb_copy_area(xcb_connection(), window, pixmap, gc, x, y, 0, 0, width, height);

    QPixmap result = qt_xcb_pixmapFromXPixmap(connection(), pixmap, width, height, reply->depth, visual);

    free(reply);
    xcb_free_gc(xcb_connection(), gc);
    xcb_free_pixmap(xcb_connection(), pixmap);

    return result;
}
Esempio n. 11
0
int main(int argc,char**argv){
	xcb_connection_t*d=xcb_connect(0,0);
	int32_t*x,*y,*tx=0,mx,my,rt=xcb_setup_roots_iterator(xcb_get_setup(d)).data->root,cs[255],*cz=cs+1;
	uint8_t mz,mZ;
	xcb_change_window_attributes(d,rt,XCB_CW_EVENT_MASK,&cwa);
	xcb_grab_key(d,1,rt,0,64,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC);
	xcb_grab_key(d,1,rt,8,XCB_GRAB_ANY,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC);
	xcb_grab_button(d,1,rt,XCB_EVENT_MASK_BUTTON_PRESS,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC,XCB_NONE,XCB_NONE,XCB_GRAB_ANY,8);
	#ifdef COMPOSITE
	xcb_composite_redirect_subwindows(d,rt,XCB_COMPOSITE_REDIRECT_AUTOMATIC);
	#endif
	xcb_generic_event_t*e=0;
main:xcb_flush(d);
	waitpid(-1,0,WNOHANG);
noflush:x=y=cz-1;
again:free(e);
	switch((e=xcb_wait_for_event(d))->response_type&127){
	case XCB_BUTTON_PRESS:
		for(;x>cs;x--)
			if(*x==((xcb_button_press_event_t*)e)->child){
				if(((xcb_key_press_event_t*)e)->detail==2)goto pocus;
			case XCB_KEY_PRESS:
				mz=128|((xcb_key_press_event_t*)e)->detail;
				my=((xcb_key_press_event_t*)e)->state;
				goto*(cz==cs+1?&&kcode:&&stack);
			}
		goto noflush;
	case XCB_KEY_RELEASE:
		if(((xcb_key_press_event_t*)e)->detail!=64||!tx)default:goto again;
		xt:x=tx;
		tx=0;
		goto stack;
	case XCB_CONFIGURE_REQUEST:{
		void*p=buf;
		for(mz=0;mz<5;mz++)
			if(((xcb_configure_request_event_t*)e)->value_mask&1<<mz){*(uint32_t*)p=*(int16_t*)(((void*)e)+16+mz*2);p+=4;}
		if(((xcb_configure_request_event_t*)e)->value_mask&XCB_CONFIG_WINDOW_SIBLING){*(uint32_t*)p=((xcb_configure_request_event_t*)e)->sibling;p+=4;}
		if(mz=((xcb_configure_request_event_t*)e)->value_mask&XCB_CONFIG_WINDOW_STACK_MODE)*(uint32_t*)p=((xcb_configure_request_event_t*)e)->stack_mode;
		xcb_configure_window(d,((xcb_configure_request_event_t*)e)->window,((xcb_configure_request_event_t*)e)->value_mask,buf);
		if(mz){
			p=xcb_query_tree_reply(d,xcb_query_tree_unchecked(d,rt),0);
			int32_t*cl=p+32+((xcb_query_tree_reply_t*)p)->children_len*4;
			for(y=p+32;y<cl;y++){
				for(x=cs+1;x<cz;x++)
					if(*x==*y)goto nono;
				*y=0;
				nono:;
			}
			x=cs;
			for(y=p+32;y<cl;y++)
				if(*y)*++x=*y;
			free(p);
			goto pocus;
		}else goto main;}
	case XCB_MAP_REQUEST:{
		void*p=xcb_get_window_attributes_reply(d,xcb_get_window_attributes_unchecked(d,((xcb_map_request_event_t*)e)->window),0);
		if(((xcb_get_window_attributes_reply_t*)p)->override_redirect){
			free(p);
			goto pocus;
		}
		free(p);
		for(;x>cs;x--)
			if(*x==((xcb_map_request_event_t*)e)->window)goto noflush;
		xcb_map_window(d,*cz++=((xcb_map_request_event_t*)e)->window);
		goto hocus;}
	case XCB_MOTION_NOTIFY:
		*buf=mZ&&((xcb_motion_notify_event_t*)e)->root_x<=mx?:((xcb_motion_notify_event_t*)e)->root_x-mx;
		buf[1]=mZ&&((xcb_motion_notify_event_t*)e)->root_y<=my?:((xcb_motion_notify_event_t*)e)->root_y-my;
		xcb_configure_window(d,*x,mZ?XCB_CONFIG_WINDOW_WIDTH|XCB_CONFIG_WINDOW_HEIGHT:XCB_CONFIG_WINDOW_X|XCB_CONFIG_WINDOW_Y,buf);
		goto main;
	case XCB_BUTTON_RELEASE:
		xcb_ungrab_pointer(d,XCB_CURRENT_TIME);
		goto main;
	case XCB_UNMAP_NOTIFY:unmap:goto*(x==cs?&&noflush:*x==((xcb_unmap_notify_event_t*)e)->window&&--cz>cs+1?&&stack:(x--,&&unmap));
	}
stack:mx=*x;
	for(;x!=y;x+=x<y?:-1)*x=x[x<y?:-1];
	*x=mx;
hocus:x=cz-1;
	xcb_configure_window(d,*x,XCB_CONFIG_WINDOW_STACK_MODE,di);
pocus:xcb_set_input_focus(d,XCB_INPUT_FOCUS_POINTER_ROOT,*x,XCB_CURRENT_TIME);
	if(!(mz&128))goto main;
kcode:switch(mz&=127){
	void*p;
	case 1:case 3:
		p=xcb_grab_pointer_reply(d,xcb_grab_pointer_unchecked(d,0,rt,XCB_EVENT_MASK_BUTTON_RELEASE|XCB_EVENT_MASK_POINTER_MOTION,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC,XCB_NONE,XCB_NONE,XCB_CURRENT_TIME),0);
		if(((xcb_grab_pointer_reply_t*)p)->status!=XCB_GRAB_STATUS_SUCCESS){
			free(p);
			goto noflush;
		}
		free(p);
		p=xcb_get_geometry_reply(d,xcb_get_geometry_unchecked(d,*y),0);
		mx=((xcb_get_geometry_reply_t*)p)->x;
		my=((xcb_get_geometry_reply_t*)p)->y;
		free(p);
		if(mZ=mz==1){
			p=xcb_query_pointer_reply(d,xcb_query_pointer_unchecked(d,rt),0);
			mx=((xcb_query_pointer_reply_t*)p)->root_x-mx;
			my=((xcb_query_pointer_reply_t*)p)->root_y-my;
			free(p);
		}
		goto noflush;
	case 23:case 49:
		if(cz-cs<3)goto main;
		y=tx;
		tx=mz==23?(y!=cs+1?(y?:x)-1:x):!y||y==x?cs+1:y+1;
		if(y&&y<cz-1){
			*buf=y[mz==23?:-1];
			buf[1]=mz==23;
			xcb_configure_window(d,*y,XCB_CONFIG_WINDOW_SIBLING|XCB_CONFIG_WINDOW_STACK_MODE,buf);
		}
		xcb_configure_window(d,*tx,XCB_CONFIG_WINDOW_STACK_MODE,di);
		goto main;
	case 32:return 0;
	case 44:
		if(cz>cs+1)xcb_configure_window(d,*y,XCB_CONFIG_WINDOW_X|XCB_CONFIG_WINDOW_Y|XCB_CONFIG_WINDOW_WIDTH|XCB_CONFIG_WINDOW_HEIGHT,di);
		goto main;
	case 46:
		if(cz==cs+1)goto main;
		if(tx)goto*(mz|=128,&&xt);
		{xcb_intern_atom_cookie_t c1=xcb_intern_atom_unchecked(d,0,12,"WM_PROTOCOLS"),c2=xcb_intern_atom_unchecked(d,0,16,"WM_DELETE_WINDOW");
		p=xcb_intern_atom_reply(d,c1,0);
		mx=((xcb_intern_atom_reply_t*)p)->atom;
		free(p);
		p=xcb_intern_atom_reply(d,c2,0);}
		my=((xcb_intern_atom_reply_t*)p)->atom;
		free(p);
		p=xcb_get_property_reply(d,xcb_get_property_unchecked(d,0,*y,mx,XCB_ATOM_ATOM,0,-1),0);
		xcb_send_event(d,0,*y,XCB_EVENT_MASK_NO_EVENT,(void*)(xcb_client_message_event_t[]){{.response_type=XCB_CLIENT_MESSAGE,.window=*y,.type=mx,.format=32,.data.data32={my,XCB_CURRENT_TIME}}});
Esempio n. 12
0
/** Scan X to find windows to manage.
 */
static void
scan(xcb_query_tree_cookie_t tree_c)
{
    int i, tree_c_len;
    xcb_query_tree_reply_t *tree_r;
    xcb_window_t *wins = NULL;
    xcb_get_window_attributes_reply_t *attr_r;
    xcb_get_geometry_reply_t *geom_r;
    long state;

    tree_r = xcb_query_tree_reply(globalconf.connection,
                                  tree_c,
                                  NULL);

    if(!tree_r)
        return;

    /* Get the tree of the children windows of the current root window */
    if(!(wins = xcb_query_tree_children(tree_r)))
        fatal("cannot get tree children");

    tree_c_len = xcb_query_tree_children_length(tree_r);
    xcb_get_window_attributes_cookie_t attr_wins[tree_c_len];
    xcb_get_property_cookie_t state_wins[tree_c_len];

    for(i = 0; i < tree_c_len; i++)
    {
        attr_wins[i] = xcb_get_window_attributes_unchecked(globalconf.connection,
                       wins[i]);

        state_wins[i] = xwindow_get_state_unchecked(wins[i]);
    }

    xcb_get_geometry_cookie_t *geom_wins[tree_c_len];

    for(i = 0; i < tree_c_len; i++)
    {
        attr_r = xcb_get_window_attributes_reply(globalconf.connection,
                 attr_wins[i],
                 NULL);

        state = xwindow_get_state_reply(state_wins[i]);

        if(!attr_r || attr_r->override_redirect
                || attr_r->map_state == XCB_MAP_STATE_UNMAPPED
                || state == XCB_ICCCM_WM_STATE_WITHDRAWN)
        {
            geom_wins[i] = NULL;
            p_delete(&attr_r);
            continue;
        }

        p_delete(&attr_r);

        /* Get the geometry of the current window */
        geom_wins[i] = p_alloca(xcb_get_geometry_cookie_t, 1);
        *(geom_wins[i]) = xcb_get_geometry_unchecked(globalconf.connection, wins[i]);
    }

    for(i = 0; i < tree_c_len; i++)
    {
        if(!geom_wins[i] || !(geom_r = xcb_get_geometry_reply(globalconf.connection,
                                       *(geom_wins[i]), NULL)))
            continue;

        client_manage(wins[i], geom_r, true);

        p_delete(&geom_r);
    }

    p_delete(&tree_r);
}
Esempio n. 13
0
Compositor::Compositor()
    : connection_(QX11Info::connection()),
      root_(QX11Info::appRootWindow()),
      damageExt_(xcb_get_extension_data(connection_, &xcb_damage_id)),
      initFinished_(false)
{
    qRegisterMetaType<ClientWindow *>();

    Q_ASSERT(QCoreApplication::instance());
    QCoreApplication::instance()->installNativeEventFilter(this);

    auto ewmhCookie = xcb_ewmh_init_atoms(connection_, &ewmh_);
    if (!xcb_ewmh_init_atoms_replies(&ewmh_, ewmhCookie, Q_NULLPTR)) {
        qFatal("Cannot init EWMH");
    }

    auto wmCmCookie = xcb_ewmh_get_wm_cm_owner_unchecked(&ewmh_, QX11Info::appScreen());
    xcb_window_t wmCmOwnerWin = XCB_NONE;
    if (!xcb_ewmh_get_wm_cm_owner_reply(&ewmh_, wmCmCookie, &wmCmOwnerWin, Q_NULLPTR)) {
        qFatal("Cannot check _NET_WM_CM_Sn");
    }
    if (wmCmOwnerWin) {
        qFatal("Another compositing manager is already running");
    }

    auto attributesCookie = xcb_get_window_attributes_unchecked(connection_, root_);
    auto damageQueryVersionCookie = xcb_damage_query_version_unchecked(connection_, 1, 1);
    auto overlayWindowCookie = xcb_composite_get_overlay_window_unchecked(connection_, root_);

    auto attributes =
            xcbReply(xcb_get_window_attributes_reply(connection_, attributesCookie, Q_NULLPTR));
    if (!attributes) {
        qFatal("Cannot get root window attributes");
    }
    auto newEventMask = attributes->your_event_mask
            | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY
            | XCB_EVENT_MASK_STRUCTURE_NOTIFY
            | XCB_EVENT_MASK_PROPERTY_CHANGE;
    xcb_change_window_attributes(connection_, root_, XCB_CW_EVENT_MASK, &newEventMask);

    auto treeCookie = xcb_query_tree_unchecked(connection_, root_);
    auto rootGeometryCookie = xcb_get_geometry_unchecked(connection_, root_);

    auto damageVersion =
            xcbReply(xcb_damage_query_version_reply(connection_, damageQueryVersionCookie, Q_NULLPTR));
    if (!damageVersion) {
        qFatal("Cannot query version of Damage extension");
    }

    auto overlayWindow =
            xcbReply(xcb_composite_get_overlay_window_reply(connection_, overlayWindowCookie, Q_NULLPTR));
    if (!overlayWindow) {
        qFatal("Cannot get overlay window");
    }
    overlayWindow_.reset(QWindow::fromWinId(overlayWindow->overlay_win));

    auto region = xcb_generate_id(connection_);
    xcb_xfixes_create_region(connection_, region, 0, Q_NULLPTR);
    xcb_xfixes_set_window_shape_region(connection_, overlayWindow->overlay_win, XCB_SHAPE_SK_INPUT, 0, 0, region);
    xcb_xfixes_destroy_region(connection_, region);

    xcb_composite_redirect_subwindows(connection_, root_, XCB_COMPOSITE_REDIRECT_MANUAL);

    auto rootGeometry =
            xcbReply(xcb_get_geometry_reply(connection_, rootGeometryCookie, Q_NULLPTR));
    if (!rootGeometry) {
        qFatal("Cannot query root window geometry");
    }
    rootGeometry_ = QRect(rootGeometry->x, rootGeometry->y, rootGeometry->width, rootGeometry->height);

    auto tree = xcbReply(xcb_query_tree_reply(connection_, treeCookie, Q_NULLPTR));
    if (!tree) {
        qFatal("Cannot query window tree");
    }

    auto children = xcb_query_tree_children(tree.get());
    for (int i = 0; i < xcb_query_tree_children_length(tree.get()); i++) {
        addChildWindow(children[i]);
    }
    updateActiveWindow();

    initFinished_ = true;
}