Beispiel #1
0
static xcb_translate_coordinates_reply_t *
translateCoordinates(QXcbConnection *c, xcb_window_t from, xcb_window_t to, int x, int y)
{
    xcb_translate_coordinates_cookie_t cookie =
            xcb_translate_coordinates(c->xcb_connection(), from, to, x, y);
    return xcb_translate_coordinates_reply(c->xcb_connection(), cookie, 0);
}
Beispiel #2
0
	void
	Window::translate_coords(xcb_window_t target, int32_t& x, int32_t& y)
	{
		xcb_translate_coordinates_cookie_t c = xcb_translate_coordinates(conn->xcb(), window, target, x, y);
		xcb_generic_error_t* error;
		xcb_translate_coordinates_reply_t* reply = xcb_translate_coordinates_reply(conn->xcb(), c, &error);
		throw_if_error(error);
		
		x = reply->dst_x;
		y = reply->dst_y;
		
		free(reply);
	}
/**
 * Converts a Weston compositor x,y coordinate into a global screen coordinate.
 * When Weston is using the x11 backend, the x,y coordinate is mapped to the X
 * display output (needed to correctly map a uinput pointer to weston).
 **/
static void toScreen(int32_t *x, int32_t *y)
{
	struct weston_output *output(Globals::output());

	toDevice(x, y);

	std::string make(output->make);
	if (make == "xwayland" or make == "weston-X11") {
#if defined(HAVE_X11_SUPPORT)
		struct x11_compositor *x11_compositor = (struct x11_compositor*)Globals::compositor();
		struct x11_output *x11_output = (struct x11_output*) output;

		xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(
			x11_compositor->conn,
			xcb_get_geometry(
				x11_compositor->conn,
				x11_output->window
			),
			NULL
		);

		xcb_translate_coordinates_reply_t *trans = xcb_translate_coordinates_reply(
			x11_compositor->conn,
			xcb_translate_coordinates(
				x11_compositor->conn,
				x11_output->window,
				geom->root,
				-(geom->border_width),
				-(geom->border_width)
			),
			NULL
		);

		*x += (int16_t)trans->dst_x;
		*y += (int16_t)trans->dst_y;

		delete trans;
		delete geom;
#else
		exit(EXIT_FAILURE);
#endif
	}
}
Beispiel #4
0
// === WindowGeometry() ===
QRect LXCB::WindowGeometry(WId win, bool includeFrame){
  if(DEBUG){ qDebug() << "XCB: WindowGeometry()"; }
  QRect geom;
  if(win==0){ return geom; }
  xcb_get_geometry_cookie_t cookie = xcb_get_geometry(QX11Info::connection(), win);
  xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(QX11Info::connection(), cookie, NULL);
  //qDebug() << "Get Window Geometry:" << reply;
  if(reply != 0){
    geom = QRect(0, 0, reply->width, reply->height); //make sure to use the origin point for the window
    //qDebug() << " - "<<reply->x << reply->y << reply->width << reply->height;
    free(reply);
    if(includeFrame){
      //Need to add/include the frame extents as well (assuming the frame info is available)
      xcb_get_property_cookie_t cookie = xcb_ewmh_get_frame_extents_unchecked(&EWMH, win);
      if(cookie.sequence != 0){
	xcb_ewmh_get_extents_reply_t frame;
        if(1== xcb_ewmh_get_frame_extents_reply(&EWMH, cookie, &frame, NULL) ){
	    //adjust the origin point to account for the frame
	    geom.translate(-frame.left, -frame.top); //move to the orign point for the frame
	    //adjust the size (include the frame sizes)
	    geom.setWidth( geom.width() + frame.left + frame.right );
	    geom.setHeight( geom.height() + frame.top + frame.bottom );
	}
	//qDebug() << " - Frame:" << frame.left << frame.right << frame.top << frame.bottom;
	//qDebug() << " - Modified with Frame:" << geom.x() << geom.y() << geom.width() << geom.height();
      }
    }
    //Now need to convert this to absolute coordinates (not parent-relavitve)
      xcb_translate_coordinates_cookie_t tcookie = xcb_translate_coordinates(QX11Info::connection(), win, QX11Info::appRootWindow(), geom.x(), geom.y());
      xcb_translate_coordinates_reply_t *trans = xcb_translate_coordinates_reply(QX11Info::connection(), tcookie, NULL);
      if(trans!=0){
	//qDebug() << " - Got Translation:" << trans->dst_x << trans->dst_y;
	//Replace the origin point with the global position (sizing remains the same)
        geom.moveLeft(trans->dst_x); //adjust X coordinate (no size change)
	geom.moveTop(trans->dst_y); //adjust Y coordinate (no size change)
	free(trans);
      }
  }else{
    //Need to do another catch for this situation (probably not mapped yet)
  }
  return geom;
}
bool LinuxWindowCapture::WindowRect() {
  if( mWindow == 0 )
    return false;

  xcb_connection_t* dpy = xcb_connect( NULL, NULL );
  if ( xcb_connection_has_error( dpy ) )
    qDebug() << "Can't open display";

  xcb_screen_t* screen = xcb_setup_roots_iterator( xcb_get_setup( dpy ) ).data;
  if( !screen )
    qDebug() << "Can't acquire screen";

  xcb_get_geometry_cookie_t geometryC = xcb_get_geometry( dpy, mWindow );
  xcb_get_geometry_reply_t* geometryR = xcb_get_geometry_reply( dpy, geometryC, NULL );


  if( geometryR ) {
    xcb_translate_coordinates_cookie_t
                    translateC = xcb_translate_coordinates( dpy,
                                                            mWindow,
                                                            screen->root,
                                                            geometryR->x,
                                                            geometryR->y );
    xcb_translate_coordinates_reply_t*
        translateR = xcb_translate_coordinates_reply( dpy, translateC, NULL );

    mRect.setRect( translateR->dst_x,
                   translateR->dst_y,
                   geometryR->width,
                   geometryR->height );

    free( geometryR );
    free( translateR );
    xcb_disconnect( dpy );

    return true;
  }
  xcb_disconnect( dpy );
  return false;
}
Beispiel #6
0
QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
{
    xcb_window_t root = m_screen->root;

    int x = p.x();
    int y = p.y();

    xcb_window_t parent = root;
    xcb_window_t child = root;

    do {
        xcb_translate_coordinates_cookie_t translate_cookie =
            xcb_translate_coordinates_unchecked(xcb_connection(), parent, child, x, y);

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

        if (!translate_reply) {
            return 0;
        }

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

        free(translate_reply);

        if (!child || child == root)
            return 0;

        QPlatformWindow *platformWindow = connection()->platformWindowFromId(child);
        if (platformWindow)
            return platformWindow->window();
    } while (parent != child);

    return 0;
}
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;
}
Beispiel #8
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);
Beispiel #9
0
static gboolean
_eventd_nd_xcb_randr_check_focused(EventdNdBackendContext *self, EventdNdXcbRandrOutput *output)
{
    gint x, y;
    switch ( self->follow_focus )
    {
    case EVENTD_ND_XCB_FOLLOW_FOCUS_MOUSE:
    {
        xcb_query_pointer_cookie_t c;
        xcb_query_pointer_reply_t *r;
        c = xcb_query_pointer(self->xcb_connection, self->screen->root);
        r = xcb_query_pointer_reply(self->xcb_connection, c, NULL);
        if ( r == NULL )
            return FALSE;

        x = r->root_x;
        y = r->root_y;
        free(r);
    }
    break;
    case EVENTD_ND_XCB_FOLLOW_FOCUS_KEYBOARD:
    {
        xcb_get_property_cookie_t wc;
        xcb_get_property_reply_t *wr;
        wc = xcb_get_property(self->xcb_connection, FALSE, self->screen->root, self->ewmh._NET_ACTIVE_WINDOW, XCB_ATOM_WINDOW, 0, sizeof(xcb_window_t));
        wr = xcb_get_property_reply(self->xcb_connection, wc, NULL);
        if ( wr == NULL )
            return FALSE;

        xcb_window_t w;
        w = *((xcb_window_t *) xcb_get_property_value(wr));
        free(wr);

        xcb_translate_coordinates_cookie_t cc;
        xcb_translate_coordinates_reply_t *cr;
        cc = xcb_translate_coordinates(self->xcb_connection, w, self->screen->root, 0, 0);
        cr = xcb_translate_coordinates_reply(self->xcb_connection, cc, NULL);
        if ( cr == NULL )
            return FALSE;

        x = cr->dst_x;
        y = cr->dst_y;
        free(cr);
    }
    break;
    default:
        g_return_val_if_reached(FALSE);
    }

    for ( ; output->output != NULL ; ++output )
    {
        if ( ! ( ( x >= output->crtc->x && x <= ( output->crtc->x + output->crtc->width ) ) && ( y >= output->crtc->y && y <= ( output->crtc->y + output->crtc->height ) ) ) )
            continue;
        self->geometry.x = output->crtc->x;
        self->geometry.y = output->crtc->y;
        self->geometry.w = output->crtc->width;
        self->geometry.h = output->crtc->height;

        return TRUE;
    }
    return FALSE;
}
Beispiel #10
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;
}
Beispiel #11
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;
}
Beispiel #12
0
    //_____________________________________________
    void SizeGrip::sendMoveResizeEvent( QPoint position )
    {

        #if OXYGEN_HAVE_X11
        if( !QX11Info::isPlatformX11() ) return;

        // pointer to connection
        auto connection( QX11Info::connection() );

        // client
        auto c = m_decoration.data()->client().data();

        /*
        get root position matching position
        need to use xcb because the embedding of the widget
        breaks QT's mapToGlobal and other methods
        */
        QPoint rootPosition( position );
        xcb_get_geometry_cookie_t cookie( xcb_get_geometry( connection, winId() ) );
        ScopedPointer<xcb_get_geometry_reply_t> reply( xcb_get_geometry_reply( connection, cookie, 0x0 ) );
        if( reply )
        {

            // translate coordinates
            xcb_translate_coordinates_cookie_t coordCookie( xcb_translate_coordinates(
                connection, winId(), reply.data()->root,
                -reply.data()->border_width,
                -reply.data()->border_width ) );

            ScopedPointer< xcb_translate_coordinates_reply_t> coordReply( xcb_translate_coordinates_reply( connection, coordCookie, 0x0 ) );

            if( coordReply )
            {
                rootPosition.rx() += coordReply.data()->dst_x;
                rootPosition.ry() += coordReply.data()->dst_y;
            }

        }

        // move/resize atom
        if( !m_moveResizeAtom )
        {

            // create atom if not found
            const QString atomName( "_NET_WM_MOVERESIZE" );
            xcb_intern_atom_cookie_t cookie( xcb_intern_atom( connection, false, atomName.size(), qPrintable( atomName ) ) );
            ScopedPointer<xcb_intern_atom_reply_t> reply( xcb_intern_atom_reply( connection, cookie, 0x0 ) );
            m_moveResizeAtom = reply ? reply->atom:0;

        }

        if( !m_moveResizeAtom ) return;

        // button release event
        xcb_button_release_event_t releaseEvent;
        memset(&releaseEvent, 0, sizeof(releaseEvent));

        releaseEvent.response_type = XCB_BUTTON_RELEASE;
        releaseEvent.event =  winId();
        releaseEvent.child = XCB_WINDOW_NONE;
        releaseEvent.root = QX11Info::appRootWindow();
        releaseEvent.event_x = position.x();
        releaseEvent.event_y = position.y();
        releaseEvent.root_x = rootPosition.x();
        releaseEvent.root_y = rootPosition.y();
        releaseEvent.detail = XCB_BUTTON_INDEX_1;
        releaseEvent.state = XCB_BUTTON_MASK_1;
        releaseEvent.time = XCB_CURRENT_TIME;
        releaseEvent.same_screen = true;
        xcb_send_event( connection, false, winId(), XCB_EVENT_MASK_BUTTON_RELEASE, reinterpret_cast<const char*>(&releaseEvent));

        xcb_ungrab_pointer( connection, XCB_TIME_CURRENT_TIME );

        // move resize event
        xcb_client_message_event_t clientMessageEvent;
        memset(&clientMessageEvent, 0, sizeof(clientMessageEvent));

        clientMessageEvent.response_type = XCB_CLIENT_MESSAGE;
        clientMessageEvent.type = m_moveResizeAtom;
        clientMessageEvent.format = 32;
        clientMessageEvent.window = c->windowId();
        clientMessageEvent.data.data32[0] = rootPosition.x();
        clientMessageEvent.data.data32[1] = rootPosition.y();
        clientMessageEvent.data.data32[2] = 4; // bottom right
        clientMessageEvent.data.data32[3] = Qt::LeftButton;
        clientMessageEvent.data.data32[4] = 0;

        xcb_send_event( connection, false, QX11Info::appRootWindow(),
            XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
            XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
            reinterpret_cast<const char*>(&clientMessageEvent) );

        xcb_flush( connection );
        #endif

    }
Beispiel #13
0
/**
 * Processing callback
 */
static void Demux (void *data)
{
    demux_t *demux = data;
    demux_sys_t *p_sys = demux->p_sys;
    xcb_connection_t *conn = p_sys->conn;

    /* Update capture region (if needed) */
    xcb_get_geometry_cookie_t gc = xcb_get_geometry (conn, p_sys->window);
    int16_t x = p_sys->x, y = p_sys->y;
    xcb_translate_coordinates_cookie_t tc;

    if (p_sys->window != p_sys->root)
        tc = xcb_translate_coordinates (conn, p_sys->window, p_sys->root,
                                        x, y);

    xcb_get_geometry_reply_t *geo = xcb_get_geometry_reply (conn, gc, NULL);
    if (geo == NULL)
    {
        msg_Err (demux, "bad X11 drawable 0x%08"PRIx32, p_sys->window);
        return;
    }

    uint16_t w = geo->width - x;
    uint16_t h = geo->height - y;
    free (geo);
    if (p_sys->w > 0 && p_sys->w < w)
        w = p_sys->w;
    if (p_sys->h > 0 && p_sys->h < h)
        h = p_sys->h;

    if (p_sys->window != p_sys->root)
    {
        xcb_translate_coordinates_reply_t *coords =
             xcb_translate_coordinates_reply (conn, tc, NULL);
        if (coords == NULL)
            return;
        x = coords->dst_x;
        y = coords->dst_y;
        free (coords);
    }

    xcb_get_image_reply_t *img;
    img = xcb_get_image_reply (conn,
        xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, p_sys->root,
                       x, y, w, h, ~0), NULL);
    if (img == NULL)
        return;

    /* Send block - zero copy */
    block_t *block = block_heap_Alloc (img, xcb_get_image_data (img),
                                       xcb_get_image_data_length (img));
    if (block == NULL)
        return;

    vlc_mutex_lock (&p_sys->lock);
    if (w != p_sys->fmt.video.i_visible_width
     || h != p_sys->fmt.video.i_visible_height)
    {
        if (p_sys->es != NULL)
            es_out_Del (demux->out, p_sys->es);
        p_sys->fmt.video.i_visible_width = p_sys->fmt.video.i_width = w;
        p_sys->fmt.video.i_visible_height = p_sys->fmt.video.i_height = h;
        p_sys->es = es_out_Add (demux->out, &p_sys->fmt);
    }

    /* Capture screen */
    if (p_sys->es != NULL)
    {
        if (p_sys->pts == VLC_TS_INVALID)
            p_sys->pts = mdate ();
        block->i_pts = block->i_dts = p_sys->pts;

        es_out_Control (demux->out, ES_OUT_SET_PCR, p_sys->pts);
        es_out_Send (demux->out, p_sys->es, block);
        p_sys->pts += p_sys->interval;
    }
    vlc_mutex_unlock (&p_sys->lock);
}
Beispiel #14
0
// determine which monitor holds the active window, or failing that the mouse pointer
void monitor_active ( workarea *mon )
{
    xcb_window_t root = xcb->screen->root;
    int          x, y;

    if ( config.monitor >= 0 ) {
        if ( monitor_get_dimension ( config.monitor, mon ) ) {
            return;
        }
        fprintf ( stderr, "Failed to find selected monitor.\n" );
    }
    if ( config.monitor == -3 ) {
        if ( pointer_get ( root, &x, &y ) ) {
            monitor_dimensions ( x, y, mon );
            mon->x = x;
            mon->y = y;
            return;
        }
    }
    // Get the current desktop.
    unsigned int current_desktop = 0;
    if ( config.monitor == -1 && xcb_ewmh_get_current_desktop_reply ( &xcb->ewmh,
                                                                      xcb_ewmh_get_current_desktop ( &xcb->ewmh, xcb->screen_nbr ),
                                                                      &current_desktop, NULL ) ) {
        xcb_get_property_cookie_t             c = xcb_ewmh_get_desktop_viewport ( &xcb->ewmh, xcb->screen_nbr );
        xcb_ewmh_get_desktop_viewport_reply_t vp;
        if ( xcb_ewmh_get_desktop_viewport_reply ( &xcb->ewmh, c, &vp, NULL ) ) {
            if ( current_desktop < vp.desktop_viewport_len ) {
                monitor_dimensions ( vp.desktop_viewport[current_desktop].x,
                                     vp.desktop_viewport[current_desktop].y, mon );
                xcb_ewmh_get_desktop_viewport_reply_wipe ( &vp );
                return;
            }
            xcb_ewmh_get_desktop_viewport_reply_wipe ( &vp );
        }
    }

    xcb_window_t active_window;
    if ( xcb_ewmh_get_active_window_reply ( &xcb->ewmh,
                                            xcb_ewmh_get_active_window ( &xcb->ewmh, xcb->screen_nbr ), &active_window, NULL ) ) {
        // get geometry.
        xcb_get_geometry_cookie_t c  = xcb_get_geometry ( xcb->connection, active_window );
        xcb_get_geometry_reply_t  *r = xcb_get_geometry_reply ( xcb->connection, c, NULL );
        if ( r ) {
            xcb_translate_coordinates_cookie_t ct = xcb_translate_coordinates ( xcb->connection, active_window, root, r->x, r->y );
            xcb_translate_coordinates_reply_t  *t = xcb_translate_coordinates_reply ( xcb->connection, ct, NULL );
            if ( t ) {
                if ( config.monitor == -2 ) {
                    // place the menu above the window
                    // if some window is focused, place menu above window, else fall
                    // back to selected monitor.
                    mon->x = t->dst_x - r->x;
                    mon->y = t->dst_y - r->y;
                    mon->w = r->width;
                    mon->h = r->height;
                    mon->t = r->border_width;
                    mon->b = r->border_width;
                    mon->l = r->border_width;
                    mon->r = r->border_width;
                    free ( r );
                    free ( t );
                    return;
                } else if ( config.monitor == -4 ){
                    monitor_dimensions ( t->dst_x, t->dst_y, mon );
                    free(r);
                    free(t);
                    return;

                }
            }
            free ( r );
        }
    }
    if ( pointer_get ( root, &x, &y ) ) {
        monitor_dimensions ( x, y, mon );
        return;
    }

    monitor_dimensions ( 0, 0, mon );
}
Beispiel #15
0
static xcb_rectangle_t get_window_position(void) {
    xcb_rectangle_t result = (xcb_rectangle_t){logical_px(50), logical_px(50), MAX_WIDTH, font.height + 2 * BORDER + 2 * PADDING};

    xcb_get_property_reply_t *supporting_wm_reply = NULL;
    xcb_get_input_focus_reply_t *input_focus = NULL;
    xcb_get_geometry_reply_t *geometry = NULL;
    xcb_get_property_reply_t *wm_class = NULL;
    xcb_translate_coordinates_reply_t *coordinates = NULL;

    xcb_atom_t A__NET_SUPPORTING_WM_CHECK;
    xcb_intern_atom_cookie_t nswc_cookie = xcb_intern_atom(conn, 0, strlen("_NET_SUPPORTING_WM_CHECK"), "_NET_SUPPORTING_WM_CHECK");
    xcb_intern_atom_reply_t *nswc_reply = xcb_intern_atom_reply(conn, nswc_cookie, NULL);
    if (nswc_reply == NULL) {
        ELOG("Could not intern atom _NET_SUPPORTING_WM_CHECK\n");
        exit(-1);
    }
    A__NET_SUPPORTING_WM_CHECK = nswc_reply->atom;
    free(nswc_reply);

    supporting_wm_reply = xcb_get_property_reply(
        conn, xcb_get_property(conn, false, root, A__NET_SUPPORTING_WM_CHECK, XCB_ATOM_WINDOW, 0, 32), NULL);
    xcb_window_t *supporting_wm_win = NULL;
    if (supporting_wm_reply == NULL || xcb_get_property_value_length(supporting_wm_reply) == 0) {
        DLOG("Could not determine EWMH support window.\n");
    } else {
        supporting_wm_win = xcb_get_property_value(supporting_wm_reply);
    }

    /* In rare cases, the window holding the input focus might disappear while we are figuring out its
     * position. To avoid this, we grab the server in the meantime. */
    xcb_grab_server(conn);

    input_focus = xcb_get_input_focus_reply(conn, xcb_get_input_focus(conn), NULL);
    if (input_focus == NULL || input_focus->focus == XCB_NONE) {
        DLOG("Failed to receive the current input focus or no window has the input focus right now.\n");
        goto free_resources;
    }

    /* We need to ignore the EWMH support window to which the focus can be set if there's no suitable window to focus. */
    if (supporting_wm_win != NULL && input_focus->focus == *supporting_wm_win) {
        DLOG("Input focus is on the EWMH support window, ignoring.\n");
        goto free_resources;
    }

    geometry = xcb_get_geometry_reply(conn, xcb_get_geometry(conn, input_focus->focus), NULL);
    if (geometry == NULL) {
        DLOG("Failed to received window geometry.\n");
        goto free_resources;
    }

    wm_class = xcb_get_property_reply(
        conn, xcb_get_property(conn, false, input_focus->focus, XCB_ATOM_WM_CLASS, XCB_GET_PROPERTY_TYPE_ANY, 0, 32), NULL);

    /* We need to find out whether the input focus is on an i3 frame window. If it is, we must not translate the coordinates. */
    if (wm_class == NULL || xcb_get_property_value_length(wm_class) == 0 || strcmp(xcb_get_property_value(wm_class), "i3-frame") != 0) {
        coordinates = xcb_translate_coordinates_reply(
            conn, xcb_translate_coordinates(conn, input_focus->focus, root, geometry->x, geometry->y), NULL);
        if (coordinates == NULL) {
            DLOG("Failed to translate coordinates.\n");
            goto free_resources;
        }

        DLOG("Determined coordinates of window with input focus at x = %i / y = %i.\n", coordinates->dst_x, coordinates->dst_y);
        result.x += coordinates->dst_x;
        result.y += coordinates->dst_y;
    } else {
        DLOG("Determined coordinates of window with input focus at x = %i / y = %i.\n", geometry->x, geometry->y);
        result.x += geometry->x;
        result.y += geometry->y;
    }

free_resources:
    xcb_ungrab_server(conn);
    xcb_flush(conn);

    FREE(supporting_wm_reply);
    FREE(input_focus);
    FREE(geometry);
    FREE(wm_class);
    FREE(coordinates);
    return result;
}