Esempio n. 1
0
/** Handle systray message.
 * \param ev The event.
 * \return 0 on no error.
 */
int
systray_process_client_message(xcb_client_message_event_t *ev)
{
    int screen_nbr = 0, ret = 0;
    xcb_get_geometry_cookie_t geom_c;
    xcb_get_geometry_reply_t *geom_r;
    xcb_screen_iterator_t iter;

    switch(ev->data.data32[1])
    {
      case SYSTEM_TRAY_REQUEST_DOCK:
        geom_c = xcb_get_geometry_unchecked(globalconf.connection, ev->window);

        if(!(geom_r = xcb_get_geometry_reply(globalconf.connection, geom_c, NULL)))
            return -1;

        for(iter = xcb_setup_roots_iterator(xcb_get_setup(globalconf.connection)), screen_nbr = 0;
            iter.rem && iter.data->root != geom_r->root; xcb_screen_next (&iter), ++screen_nbr);

        p_delete(&geom_r);

        ret = systray_request_handle(ev->data.data32[2], screen_nbr, NULL);
        break;
    }

    return ret;
}
Esempio n. 2
0
void Client::updateState(xcb_ewmh_connection_t* ewmhConn)
{
    xcb_connection_t* conn = ewmhConn->connection;
    xcb_get_geometry_cookie_t geomCookie;
    if (!mOwned)
        geomCookie = xcb_get_geometry_unchecked(conn, mWindow);
    const xcb_get_property_cookie_t normalHintsCookie = xcb_icccm_get_wm_normal_hints(conn, mWindow);
    const xcb_get_property_cookie_t leaderCookie = xcb_get_property(conn, 0, mWindow, Atoms::WM_CLIENT_LEADER, XCB_ATOM_WINDOW, 0, 1);
    const xcb_get_property_cookie_t transientCookie = xcb_icccm_get_wm_transient_for(conn, mWindow);
    const xcb_get_property_cookie_t hintsCookie = xcb_icccm_get_wm_hints(conn, mWindow);
    const xcb_get_property_cookie_t classCookie = xcb_icccm_get_wm_class(conn, mWindow);
    const xcb_get_property_cookie_t nameCookie = xcb_icccm_get_wm_name(conn, mWindow);
    const xcb_get_property_cookie_t protocolsCookie = xcb_icccm_get_wm_protocols(conn, mWindow, Atoms::WM_PROTOCOLS);
    const xcb_get_property_cookie_t strutCookie = xcb_ewmh_get_wm_strut(ewmhConn, mWindow);
    const xcb_get_property_cookie_t partialStrutCookie = xcb_ewmh_get_wm_strut_partial(ewmhConn, mWindow);
    const xcb_get_property_cookie_t stateCookie = xcb_ewmh_get_wm_state(ewmhConn, mWindow);
    const xcb_get_property_cookie_t typeCookie = xcb_ewmh_get_wm_window_type(ewmhConn, mWindow);
    const xcb_get_property_cookie_t pidCookie = xcb_ewmh_get_wm_pid(ewmhConn, mWindow);

    if (!mOwned)
        updateSize(conn, geomCookie);
    updateNormalHints(conn, normalHintsCookie);
    updateLeader(conn, leaderCookie);
    updateTransient(conn, transientCookie);
    updateHints(conn, hintsCookie);
    updateClass(conn, classCookie);
    updateName(conn, nameCookie);
    updateProtocols(conn, protocolsCookie);
    updateStrut(ewmhConn, strutCookie);
    updatePartialStrut(ewmhConn, partialStrutCookie);
    updateEwmhState(ewmhConn, stateCookie);
    updateWindowTypes(ewmhConn, typeCookie);
    updatePid(ewmhConn, pidCookie);
}
/**
 * Sends the GetGeometry request.
 * @param drawable Drawable whose characteristics are sought.
 * @ingroup Ecore_X_Drawable_Group
 */
EAPI void
ecore_x_drawable_geometry_get_prefetch(Ecore_X_Drawable drawable)
{
   xcb_get_geometry_cookie_t cookie;

   if (drawable == 0) drawable = ((xcb_screen_t *)_ecore_xcb_screen)->root;

   cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, drawable);
   _ecore_xcb_cookie_cache(cookie.sequence);
}
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: towel.c Progetto: kanru/towel
static void
towel_window_init_cairo(towel_window_t *win)
{
  xcb_visualtype_t *vt;

  xcb_get_geometry_cookie_t cookie = xcb_get_geometry_unchecked(win->conn,
                                                                win->id);
  xcb_get_geometry_reply_t *geo = xcb_get_geometry_reply(win->conn, cookie, NULL);

  vt = xcb_aux_find_visual_by_id(win->screen, win->screen->root_visual);
  win->cs = cairo_xcb_surface_create(win->conn, win->id,
                                     vt, geo->width, geo->height);
  win->cr = cairo_create(win->cs);

  free(geo);
}
Esempio n. 6
0
/* Read the X window geometry and record it in the client structure */
void read_client_geometry(client_t *client)
{
    xcb_get_geometry_cookie_t geometry_cookie;
    xcb_get_geometry_reply_t *geometry_reply;
    geometry_cookie = xcb_get_geometry_unchecked(wm_conf.connection, client->window);
    geometry_reply = xcb_get_geometry_reply(wm_conf.connection, geometry_cookie, NULL);
    if (geometry_reply) {
        client->rect.x = geometry_reply->x;
        client->rect.y = geometry_reply->y;
        client->rect.width = geometry_reply->width;
        client->rect.height = geometry_reply->height;
        client->border_width = geometry_reply->border_width;
        free(geometry_reply);
    }
    else {
        fprintf(stderr, "  ! failed to get geometry geometry for window %u\n", client->window);
    }
}
Esempio n. 7
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. 8
0
File: towel.c Progetto: kanru/towel
static towel_window_t*
towel_create_window(xcb_connection_t *conn)
{
  /* Get screen setup and root window */
  towel_window_t *win = calloc(1, sizeof(towel_window_t));
  const xcb_setup_t *setup = xcb_get_setup(conn);
  xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
  xcb_get_geometry_cookie_t geo_cookie;
  xcb_get_geometry_reply_t *geo;
  uint32_t mask = XCB_CW_EVENT_MASK;
  uint32_t values[] = {XCB_EVENT_MASK_EXPOSURE|XCB_EVENT_MASK_POINTER_MOTION};

  win->conn = conn;
  win->screen = iter.data;

  geo_cookie = xcb_get_geometry_unchecked(conn, win->screen->root);
  geo = xcb_get_geometry_reply(win->conn, geo_cookie, NULL);


  win->x = 0;
  win->y = 0;
  win->width = geo->width;
  win->height = geo->height;
  free(geo);

  win->id = xcb_generate_id(conn);
  xcb_create_window(conn,
                    XCB_COPY_FROM_PARENT,
                    win->id,
                    win->screen->root,
                    win->x, win->y,
                    win->width, win->height,
                    0,
                    XCB_WINDOW_CLASS_INPUT_OUTPUT,
                    win->screen->root_visual,
                    mask, values);

  xcb_flush(conn);

  towel_window_init_cairo(win);
  return win;
}
Esempio n. 9
0
/** Handle systray message.
 * \param ev The event.
 * \return 0 on no error.
 */
int
systray_process_client_message(xcb_client_message_event_t *ev)
{
    int ret = 0;
    xcb_get_geometry_cookie_t geom_c;
    xcb_get_geometry_reply_t *geom_r;

    switch(ev->data.data32[1])
    {
      case SYSTEM_TRAY_REQUEST_DOCK:
        geom_c = xcb_get_geometry_unchecked(globalconf.connection, ev->window);

        if(!(geom_r = xcb_get_geometry_reply(globalconf.connection, geom_c, NULL)))
            return -1;

        if(globalconf.screen->root == geom_r->root)
            ret = systray_request_handle(ev->data.data32[2], NULL);

        p_delete(&geom_r);
        break;
    }

    return ret;
}
Esempio n. 10
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. 11
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. 12
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. 13
0
/** The configure event handler.
 * \param ev The event.
 */
static void
event_handle_configurerequest(xcb_configure_request_event_t *ev)
{
    client_t *c;

    if((c = client_getbywin(ev->window)))
    {
        area_t geometry = c->geometry;
        uint16_t bw = c->border_width;
        uint16_t tb_left = c->titlebar[CLIENT_TITLEBAR_LEFT].size;
        uint16_t tb_right = c->titlebar[CLIENT_TITLEBAR_RIGHT].size;
        uint16_t tb_top = c->titlebar[CLIENT_TITLEBAR_TOP].size;
        uint16_t tb_bottom = c->titlebar[CLIENT_TITLEBAR_BOTTOM].size;
        uint16_t deco_left = bw + tb_left;
        uint16_t deco_right = bw + tb_right;
        uint16_t deco_top = bw + tb_top;
        uint16_t deco_bottom = bw + tb_bottom;
        int16_t diff_w = 0, diff_h = 0, diff_border = 0;

        lua_State *L = globalconf_get_lua_State();

        if(ev->value_mask & XCB_CONFIG_WINDOW_X)
        {
            int16_t diff = 0;
            geometry.x = ev->x;
            xwindow_translate_for_gravity(c->size_hints.win_gravity, deco_left, 0, deco_right, 0, &diff, NULL);
            geometry.x += diff;
        }
        if(ev->value_mask & XCB_CONFIG_WINDOW_Y)
        {
            int16_t diff = 0;
            geometry.y = ev->y;
            xwindow_translate_for_gravity(c->size_hints.win_gravity, 0, deco_top, 0, deco_bottom, NULL, &diff);
            geometry.y += diff;
        }
        if(ev->value_mask & XCB_CONFIG_WINDOW_WIDTH)
        {
            uint16_t old_w = geometry.width;
            geometry.width = ev->width;
            /* The ConfigureRequest specifies the size of the client window, we want the frame */
            geometry.width += tb_left + tb_right;
            diff_w = geometry.width - old_w;
        }
        if(ev->value_mask & XCB_CONFIG_WINDOW_HEIGHT)
        {
            uint16_t old_h = geometry.height;
            geometry.height = ev->height;
            /* The ConfigureRequest specifies the size of the client window, we want the frame */
            geometry.height += tb_top + tb_bottom;
            diff_h = geometry.height - old_h;
        }
        if(ev->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH)
        {
            diff_border = ev->border_width - bw;
            diff_h += diff_border;
            diff_w += diff_border;

            luaA_object_push(L, c);
            window_set_border_width(L, -1, ev->border_width);
            lua_pop(L, 1);
        }

        /* If the client resizes without moving itself, apply window gravity */
        if(c->size_hints.flags & XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY)
        {
            int16_t diff_x = 0, diff_y = 0;
            xwindow_translate_for_gravity(c->size_hints.win_gravity, diff_border, diff_border, diff_w, diff_h, &diff_x, &diff_y);
            if(!(ev->value_mask & XCB_CONFIG_WINDOW_X))
                geometry.x += diff_x;
            if(!(ev->value_mask & XCB_CONFIG_WINDOW_Y))
                geometry.y += diff_y;
        }

        c->got_configure_request = true;

        /* Request the changes to be applied */
        luaA_object_push(L, c);
        lua_pushstring(L, "ewmh");     /* context */
        lua_newtable(L);               /* props */

        /* area, it needs to be directly in the `hints` table to comply with
           the "protocol"
         */
        lua_pushstring(L, "x");
        lua_pushinteger(L, geometry.x);
        lua_rawset(L, -3);

        lua_pushstring(L, "y");
        lua_pushinteger(L, geometry.y);
        lua_rawset(L, -3);

        lua_pushstring(L, "width");
        lua_pushinteger(L, geometry.width);
        lua_rawset(L, -3);

        lua_pushstring(L, "height");
        lua_pushinteger(L, geometry.height);
        lua_rawset(L, -3);

        luaA_object_emit_signal(L, -3, "request::geometry", 2);
        lua_pop(L, 1);
    }
    else if (xembed_getbywin(&globalconf.embedded, ev->window))
    {
        /* Ignore this so that systray icons cannot resize themselves.
         * We decide their size!
         * However, Xembed says that we act like a WM to the embedded window and
         * thus we have to send a synthetic configure notify informing the
         * window that its configure request was denied.
         */
        xcb_get_geometry_cookie_t geom_cookie =
            xcb_get_geometry_unchecked(globalconf.connection, ev->window);
        xcb_translate_coordinates_cookie_t coords_cookie =
            xcb_translate_coordinates_unchecked(globalconf.connection,
                    ev->window, globalconf.screen->root, 0, 0);
        xcb_get_geometry_reply_t *geom =
            xcb_get_geometry_reply(globalconf.connection, geom_cookie, NULL);
        xcb_translate_coordinates_reply_t *coords =
            xcb_translate_coordinates_reply(globalconf.connection, coords_cookie, NULL);

        if (geom && coords)
        {
            xwindow_configure(ev->window,
                    (area_t) { .x = coords->dst_x,
                               .y = coords->dst_y,
                               .width = geom->width,
                               .height = geom->height },
                    0);
Esempio n. 14
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;
}
Esempio n. 15
0
File: event.c Progetto: feler/ceres
}
#include "config.h"

/* EVENT HANDLERS [!!] {{{
 */

/* event_map_request - map request handler {{{
 */
static int
event_map_request(void *data __attribute__ ((unused)),
                  xcb_connection_t *connection, xcb_map_request_event_t *ev)
{
    xcb_get_geometry_cookie_t geom_cookie;
    xcb_get_geometry_reply_t *geom_reply;

    geom_cookie = xcb_get_geometry_unchecked(connection, ev->window);
    geom_reply = xcb_get_geometry_reply(connection, geom_cookie, NULL);

    client_manage(ev->window, geom_reply);

    bar_draw(rootconf.bar);

    return 0;
} /*  }}} */

/* event_enter_notify - enter notify event handler {{{
 */
static int
event_enter_notify(void *data __attribute__ ((unused)),
                   xcb_connection_t *connection, xcb_enter_notify_event_t *ev)
{
Esempio n. 16
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. 17
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}}});