Пример #1
0
void query_pointer(xcb_window_t *win, xcb_point_t *pt)
{
	xcb_query_pointer_reply_t *qpr = xcb_query_pointer_reply(dpy, xcb_query_pointer(dpy, root), NULL);

	if (qpr != NULL) {
		if (win != NULL) {
			*win = qpr->child;
			xcb_point_t pt = {qpr->root_x, qpr->root_y};
			for (stacking_list_t *s = stack_tail; s != NULL; s = s->prev) {
				if (!s->node->client->shown || s->node->hidden) {
					continue;
				}
				xcb_rectangle_t rect = get_rectangle(NULL, s->node);
				if (is_inside(pt, rect)) {
					if (s->node->id == qpr->child || is_presel_window(qpr->child)) {
						*win = s->node->id;
					}
					break;
				}
			}
		}
		if (pt != NULL) {
			*pt = (xcb_point_t) {qpr->root_x, qpr->root_y};
		}
	}

	free(qpr);
}
Пример #2
0
    //_________________________________________________________
    WId DetectDialog::findWindow()
    {

        #if BREEZE_HAVE_X11
        if (!QX11Info::isPlatformX11()) {
            return 0;
        }
        // check atom
        if( !m_wmStateAtom ) return 0;

        xcb_connection_t* connection( QX11Info::connection() );
        xcb_window_t parent( QX11Info::appRootWindow() );

        // why is there a loop of only 10 here
        for( int i = 0; i < 10; ++i )
        {

            // query pointer
            xcb_query_pointer_cookie_t pointerCookie( xcb_query_pointer( connection, parent ) );
            QScopedPointer<xcb_query_pointer_reply_t, QScopedPointerPodDeleter> pointerReply( xcb_query_pointer_reply( connection, pointerCookie, nullptr ) );
            if( !( pointerReply && pointerReply->child ) ) return 0;

            const xcb_window_t child( pointerReply->child );
            xcb_get_property_cookie_t cookie( xcb_get_property( connection, 0, child, m_wmStateAtom, XCB_GET_PROPERTY_TYPE_ANY, 0, 0 ) );
            QScopedPointer<xcb_get_property_reply_t, QScopedPointerPodDeleter> reply( xcb_get_property_reply( connection, cookie, nullptr ) );
            if( reply  && reply->type ) return child;
            else parent = child;

        }
        #endif

        return 0;

    }
Пример #3
0
Vector2i InputImpl::getMousePosition()
{
    // Open a connection with the X server
    xcb_connection_t* connection = OpenConnection();

    ScopedXcbPtr<xcb_generic_error_t> error(NULL);

    ScopedXcbPtr<xcb_query_pointer_reply_t> pointer(
        xcb_query_pointer_reply(
            connection,
            xcb_query_pointer(
                connection,
                XCBDefaultRootWindow(connection)
            ),
            &error
        )
    );

    // Close the connection with the X server
    CloseConnection(connection);

    if (error)
    {
        err() << "Failed to query pointer" << std::endl;

        return Vector2i(0, 0);
    }

    return Vector2i(pointer->root_x, pointer->root_y);
}
Пример #4
0
void QXcbCursor::queryPointer(QXcbConnection *c, xcb_window_t *rootWin, QPoint *pos, int *keybMask)
{
    if (pos)
        *pos = QPoint();
    xcb_screen_iterator_t it = xcb_setup_roots_iterator(c->setup());
    while (it.rem) {
        xcb_window_t root = it.data->root;
        xcb_query_pointer_cookie_t cookie = xcb_query_pointer(c->xcb_connection(), root);
        xcb_generic_error_t *err = 0;
        xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(c->xcb_connection(), cookie, &err);
        if (!err && reply) {
            if (pos)
                *pos = QPoint(reply->root_x, reply->root_y);
            if (rootWin)
                *rootWin = root;
            if (keybMask)
                *keybMask = reply->mask;
            free(reply);
            return;
        }
        free(err);
        free(reply);
        xcb_screen_next(&it);
    }
}
Пример #5
0
/* Get the pointer position. */
void fwm_pointer_getxy(int16_t *x, int16_t *y) {
    xcb_query_pointer_reply_t *r;

    r = xcb_query_pointer_reply(gd.conn,
            xcb_query_pointer(gd.conn, gd.def_screen->root),
            NULL);
    *x = r->root_x;
    *y = r->root_y;
    /* Tiis implies grabbing pointer, but not doing so by now.
     * x = _this.root_x;
     * y = _this.root_y;
     */
}
Пример #6
0
ExcCode screen_cursor_get_position(int *x, int *y, int *same_screen) {
	xcb_query_pointer_cookie_t cookie =
			xcb_query_pointer(display, root);
	xcb_query_pointer_reply_t *reply =
			xcb_query_pointer_reply(display, cookie, NULL);
	if (reply == NULL)
		PANIC(ERR_X_REQUEST, "screen_cursor_get_position");
	*x = reply->root_x;
	*y = reply->root_y;
	*same_screen = reply->same_screen;
	free(reply);
	return 0;
}
Пример #7
0
/**
 * @param x  The x position of the mouse [out]
 * @param y  The y position of the mouse [out]
 *
 * find mouse pointer location
 *
 * @returns 1 when found
 */
static int pointer_get ( xcb_window_t root, int *x, int *y )
{
    *x = 0;
    *y = 0;
    xcb_query_pointer_cookie_t c  = xcb_query_pointer ( xcb->connection, root );
    xcb_query_pointer_reply_t  *r = xcb_query_pointer_reply ( xcb->connection, c, NULL );
    if ( r ) {
        *x = r->root_x;
        *y = r->root_y;
        free ( r );
        return 1;
    }

    return 0;
}
Пример #8
0
bool InputImpl::isMouseButtonPressed(Mouse::Button button)
{
    // Open a connection with the X server
    xcb_connection_t* connection = OpenConnection();

    ScopedXcbPtr<xcb_generic_error_t> error(NULL);

    // Get pointer mask
    ScopedXcbPtr<xcb_query_pointer_reply_t> pointer(
        xcb_query_pointer_reply(
            connection,
            xcb_query_pointer(
                connection,
                XCBDefaultRootWindow(connection)
            ),
            &error
        )
    );

    // Close the connection with the X server
    CloseConnection(connection);

    if (error)
    {
        err() << "Failed to query pointer" << std::endl;

        return false;
    }

    uint16_t buttons = pointer->mask;

    switch (button)
    {
    case Mouse::Left:
        return buttons & XCB_BUTTON_MASK_1;
    case Mouse::Right:
        return buttons & XCB_BUTTON_MASK_3;
    case Mouse::Middle:
        return buttons & XCB_BUTTON_MASK_2;
    case Mouse::XButton1:
        return false; // not supported by X
    case Mouse::XButton2:
        return false; // not supported by X
    default:
        return false;
    }
}
Пример #9
0
/*
 * Find child window at pointer location
 */
static xcb_window_t
Find_Child_At_Pointer(xcb_connection_t * dpy, xcb_window_t win)
{
    xcb_window_t child_return = XCB_WINDOW_NONE;

    xcb_query_pointer_cookie_t qp_cookie;
    xcb_query_pointer_reply_t *qp_reply;

    qp_cookie = xcb_query_pointer (dpy, win);
    qp_reply = xcb_query_pointer_reply (dpy, qp_cookie, NULL);

    if (qp_reply) {
        child_return = qp_reply->child;
        free (qp_reply);
    }

    return child_return;
}
Пример #10
0
void XQueryPointer(Display *display, Window w, Window *root_return, Window *child_return,
		int *root_x_return, int *root_y_return, int *win_x_return, int *win_y_return, unsigned int *mask_return)
{
	xcb_query_pointer_cookie_t cookie = xcb_query_pointer(display, w);
	xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(display, cookie, NULL);

	if (reply == NULL)
		fatal("Error in X11 communication\n");

	*root_return = reply->root;
	*child_return = reply->child;
	*root_x_return = reply->root_x;
	*root_y_return = reply->root_y;
	*win_x_return = reply->win_x;
	*win_y_return = reply->win_y;
	*mask_return = reply->mask;
	free(reply);
}
Пример #11
0
void query_pointer(xcb_window_t *win, xcb_point_t *pt)
{
	window_lower(motion_recorder);

	xcb_query_pointer_reply_t *qpr = xcb_query_pointer_reply(dpy, xcb_query_pointer(dpy, root), NULL);

	if (qpr != NULL) {
		if (win != NULL) {
			*win = qpr->child;
		}
		if (pt != NULL) {
			*pt = (xcb_point_t) {qpr->root_x, qpr->root_y};
		}
	}

	free(qpr);

	window_raise(motion_recorder);
}
Пример #12
0
Vector2i InputImpl::getMousePosition(const Window& relativeTo)
{
    WindowHandle handle = relativeTo.getSystemHandle();
    if (handle)
    {
        // Open a connection with the X server
        xcb_connection_t* connection = OpenConnection();

        ScopedXcbPtr<xcb_generic_error_t> error(NULL);

        ScopedXcbPtr<xcb_query_pointer_reply_t> pointer(
            xcb_query_pointer_reply(
                connection,
                xcb_query_pointer(
                    connection,
                    handle
                ),
                &error
            )
        );

        // Close the connection with the X server
        CloseConnection(connection);

        if (error)
        {
            err() << "Failed to query pointer" << std::endl;

            return Vector2i(0, 0);
        }

        return Vector2i(pointer->win_x, pointer->win_y);
    }
    else
    {
        return Vector2i();
    }
}
Пример #13
0
static void
events_loop(void)
{
	xcb_generic_event_t *ev;
#ifdef ENABLE_MOUSE
	uint32_t values[3];
	xcb_get_geometry_reply_t *geom;
	xcb_window_t win = 0;
#endif

	/* loop */
	for (;;) {
		ev = xcb_wait_for_event(conn);

		if (!ev)
			errx(1, "xcb connection broken");

		switch (CLEANMASK(ev->response_type)) {

		case XCB_CREATE_NOTIFY: {
			xcb_create_notify_event_t *e;
			e = (xcb_create_notify_event_t *)ev;

			if (!e->override_redirect) {
				subscribe(e->window);
				focus(e->window, ACTIVE);
			}
		} break;

		case XCB_DESTROY_NOTIFY: {
			xcb_destroy_notify_event_t *e;
			e = (xcb_destroy_notify_event_t *)ev;

			xcb_kill_client(conn, e->window);
		} break;

#ifdef ENABLE_SLOPPY
		case XCB_ENTER_NOTIFY: {
			xcb_enter_notify_event_t *e;
			e = (xcb_enter_notify_event_t *)ev;
			focus(e->event, ACTIVE);
		} break;
#endif

		case XCB_MAP_NOTIFY: {
			xcb_map_notify_event_t *e;
			e = (xcb_map_notify_event_t *)ev;

			if (!e->override_redirect) {
				xcb_map_window(conn, e->window);
				focus(e->window, ACTIVE);
			}
		} break;

#ifdef ENABLE_MOUSE
		case XCB_BUTTON_PRESS: {
			xcb_button_press_event_t *e;
			e = ( xcb_button_press_event_t *)ev;
			win = e->child;

			if (!win || win == scr->root)
				break;

			values[0] = XCB_STACK_MODE_ABOVE;
			xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_STACK_MODE, values);
			geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
			if (e->detail == 1) {
				values[2] = 1;
				xcb_warp_pointer(conn, XCB_NONE, win, 0, 0, 0,
					0, geom->width/2, geom->height/2);
			} else {
				values[2] = 3;
				xcb_warp_pointer(conn, XCB_NONE, win, 0, 0, 0,
						0, geom->width, geom->height);
			}
			xcb_grab_pointer(conn, 0, scr->root,
				XCB_EVENT_MASK_BUTTON_RELEASE
				| XCB_EVENT_MASK_BUTTON_MOTION
				| XCB_EVENT_MASK_POINTER_MOTION_HINT,
				XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
				scr->root, XCB_NONE, XCB_CURRENT_TIME);
			xcb_flush(conn);
		} break;

		case XCB_MOTION_NOTIFY: {
			xcb_query_pointer_reply_t *pointer;
			pointer = xcb_query_pointer_reply(conn,
					xcb_query_pointer(conn, scr->root), 0);
			if (values[2] == 1) {
				geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
				if (!geom)
					break;

				values[0] = (pointer->root_x + geom->width / 2
					> scr->width_in_pixels
					- (BORDERWIDTH*2))
					? scr->width_in_pixels - geom->width
					- (BORDERWIDTH*2)
					: pointer->root_x - geom->width / 2;
				values[1] = (pointer->root_y + geom->height / 2
					> scr->height_in_pixels
					- (BORDERWIDTH*2))
					? (scr->height_in_pixels - geom->height
					- (BORDERWIDTH*2))
					: pointer->root_y - geom->height / 2;

				if (pointer->root_x < geom->width/2)
					values[0] = 0;
				if (pointer->root_y < geom->height/2)
					values[1] = 0;

				xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_X
					| XCB_CONFIG_WINDOW_Y, values);
				xcb_flush(conn);
			} else if (values[2] == 3) {
				geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
				values[0] = pointer->root_x - geom->x;
				values[1] = pointer->root_y - geom->y;
				xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_WIDTH
					| XCB_CONFIG_WINDOW_HEIGHT, values);
				xcb_flush(conn);
			}
		} break;

		case XCB_BUTTON_RELEASE:
			focus(win, ACTIVE);
			xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
			break;
#endif

		case XCB_CONFIGURE_NOTIFY: {
			xcb_configure_notify_event_t *e;
			e = (xcb_configure_notify_event_t *)ev;

			if (e->window != focuswin)
				focus(e->window, INACTIVE);

			focus(focuswin, ACTIVE);
		} break;

		}

		xcb_flush(conn);
		free(ev);
	}
}
Пример #14
0
void ae3d::Window::PumpEvents()
{
    xcb_generic_event_t* event;
    
    while ((event = xcb_poll_for_event( WindowGlobal::connection )))
    {
        //const bool synthetic_event = (event->response_type & 0x80) != 0;
        const uint8_t response_type = event->response_type & ~0x80;

        switch (response_type)
        {
            case XCB_EVENT_MASK_BUTTON_PRESS:
            case XCB_EVENT_MASK_BUTTON_RELEASE:
            {
                const xcb_query_pointer_reply_t* pointer = xcb_query_pointer_reply( WindowGlobal::connection, xcb_query_pointer(WindowGlobal::connection, XDefaultRootWindow(WindowGlobal::display)), nullptr );
                const bool newb1 = (pointer->mask & XCB_BUTTON_MASK_1) != 0;
                const bool newb2 = (pointer->mask & XCB_BUTTON_MASK_2) != 0;
                const bool newb3 = (pointer->mask & XCB_BUTTON_MASK_3) != 0;
                const xcb_button_press_event_t* be = (xcb_button_press_event_t*)event;

                const auto b1Type = response_type == XCB_EVENT_MASK_BUTTON_PRESS ? ae3d::WindowEventType::Mouse1Down : ae3d::WindowEventType::Mouse1Up;
                const auto b2Type = response_type == XCB_EVENT_MASK_BUTTON_PRESS ? ae3d::WindowEventType::Mouse2Down : ae3d::WindowEventType::Mouse2Up;
                const auto b3Type = response_type == XCB_EVENT_MASK_BUTTON_PRESS ? ae3d::WindowEventType::MouseMiddleDown : ae3d::WindowEventType::MouseMiddleUp;

                WindowGlobal::IncEventIndex();
                
                if (newb1)
                {
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = b1Type;
                }
                else if (newb3)
                {
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = b2Type;
                }
                else if (newb2)
                {
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = b3Type;
                }
                else
                {
                    std::cerr << "Unhandled mouse button." << std::endl;
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = b1Type;
                }
                
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].mouseX = be->event_x;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].mouseY = be->event_y;
            }
            break;
            case XCB_KEY_PRESS:
            case XCB_KEY_RELEASE:
            {
                xcb_key_press_event_t *e = (xcb_key_press_event_t *)event;
                const bool isDown = (response_type == XCB_KEY_PRESS);
                const auto type = isDown ? ae3d::WindowEventType::KeyDown : ae3d::WindowEventType::KeyUp;

                WindowGlobal::IncEventIndex();
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = type;
                const xcb_keysym_t keysym = xcb_key_symbols_get_keysym(WindowGlobal::key_symbols, e->detail, 0);
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].keyCode = WindowGlobal::keyMap[ keysym ];
            }
            case XCB_MOTION_NOTIFY:
            {
                xcb_motion_notify_event_t* e = (xcb_motion_notify_event_t*)event;
                WindowGlobal::IncEventIndex();
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = ae3d::WindowEventType::MouseMove;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].mouseX = e->event_x;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].mouseY = e->event_y;
                break;
            }
            case XCB_CLIENT_MESSAGE:
            {
                xcb_client_message_event_t* client_message_event = (xcb_client_message_event_t*)event;
                if (client_message_event->type == WindowGlobal::wm_protocols)
                {
                    if (client_message_event->data.data32[0] == WindowGlobal::wm_delete_window)
                    {
                        exit(1);
                        break;
                    }
                 }
                break;
            }
            case XCB_EXPOSE:
            {
            }
            break;
        }
    }

    if (!WindowGlobal::gamePad.isActive)
    {
        return;
    }

    js_event j;

    while (read( WindowGlobal::gamePad.fd, &j, sizeof(js_event) ) == sizeof(js_event))
        //read(WindowGlobal::gamePad.fd, &j, sizeof(js_event));
    {
        // Don't care if init or afterwards
        j.type &= ~JS_EVENT_INIT;
            
        if (j.type == JS_EVENT_BUTTON)
        {
            if (j.number == WindowGlobal::gamePad.buttonA)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonA;
                }
            }
            else if (j.number == WindowGlobal::gamePad.buttonB)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonB;
                }
            }
            else if (j.number == WindowGlobal::gamePad.buttonX)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonX;
                }
            }
            else if (j.number == WindowGlobal::gamePad.buttonY)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonY;
                }
            }
            else if (j.number == WindowGlobal::gamePad.buttonStart)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonStart;
                }
            }
            else if (j.number == WindowGlobal::gamePad.buttonBack)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonBack;
                }
            }
            else
            {
                //std::cout << "pressed button " << (int)j.number << std::endl;
            }
        }
        else if (j.type == JS_EVENT_AXIS)
        {
            if (j.number == WindowGlobal::gamePad.leftThumbX)
            {
                float x = ProcessGamePadStickValue( j.value, WindowGlobal::gamePad.deadZone );
                WindowGlobal::IncEventIndex();
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadLeftThumbState;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].gamePadThumbX = x;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].gamePadThumbY = WindowGlobal::lastLeftThumbY;
                WindowGlobal::lastLeftThumbX = x;
            }
            else if (j.number == WindowGlobal::gamePad.leftThumbY)
            {
                float y = ProcessGamePadStickValue( j.value, WindowGlobal::gamePad.deadZone );
                WindowGlobal::IncEventIndex();
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadLeftThumbState;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].gamePadThumbX = WindowGlobal::lastLeftThumbX;
                WindowGlobal::eventStack[ WindowGlobal::eventIndex ].gamePadThumbY = y;
                WindowGlobal::lastLeftThumbY = y;
            }
            else if (j.number == WindowGlobal::gamePad.dpadXaxis)
            {
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonDPadRight;
                }
                if (j.value < 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonDPadLeft;
                }
            }
            else if (j.number == WindowGlobal::gamePad.dpadYaxis)
            {
                if (j.value < 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonDPadUp;
                }
                if (j.value > 0)
                {
                    WindowGlobal::IncEventIndex();
                    WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonDPadDown;
                }
            }
        }
    }
}
Пример #15
0
/**
 * Processing callback
 */
static void Demux (void *opaque)
{
    demux_t *demux = opaque;
    demux_sys_t *sys = demux->p_sys;
    xcb_connection_t *conn = sys->conn;

    /* Determine capture region */
    xcb_get_geometry_cookie_t gc;
    xcb_query_pointer_cookie_t qc;

    gc = xcb_get_geometry (conn, sys->window);
    if (sys->follow_mouse)
        qc = xcb_query_pointer (conn, sys->window);

    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, sys->window);
discard:
        if (sys->follow_mouse)
            xcb_discard_reply (conn, gc.sequence);
        return;
    }

    int w = sys->w;
    int h = sys->h;
    int x, y;

    if (sys->follow_mouse)
    {
        xcb_query_pointer_reply_t *ptr =
            xcb_query_pointer_reply (conn, qc, NULL);
        if (ptr == NULL)
        {
            free (geo);
            return;
        }

        if (w == 0 || w > geo->width)
            w = geo->width;
        x = ptr->win_x;
        if (x < w / 2)
            x = 0;
        else if (x >= (int)geo->width - (w / 2))
            x = geo->width - w;
        else
            x -= w / 2;

        if (h == 0 || h > geo->height)
            h = geo->height;
        y = ptr->win_y;
        if (y < h / 2)
            y = 0;
        else if (y >= (int)geo->height - (h / 2))
            y = geo->height - h;
        else
            y -= h / 2;
    }
    else
    {
        int max;

        x = sys->x;
        max = (int)geo->width - x;
        if (max <= 0)
            goto discard;
        if (w == 0 || w > max)
            w = max;

        y = sys->y;
        max = (int)geo->height - y;
        if (max <= 0)
            goto discard;
        if (h == 0 || h > max)
            h = max;
    }

    /* Update elementary stream format (if needed) */
    if (w != sys->cur_w || h != sys->cur_h)
    {
        if (sys->es != NULL)
            es_out_Del (demux->out, sys->es);

        /* Update composite pixmap */
        if (sys->window != geo->root)
        {
            xcb_free_pixmap (conn, sys->pixmap); /* no-op first time */
            xcb_composite_name_window_pixmap (conn, sys->window, sys->pixmap);
            xcb_create_pixmap (conn, geo->depth, sys->pixmap,
                               geo->root, geo->width, geo->height);
        }

        sys->es = InitES (demux, w, h, geo->depth, &sys->bpp);
        if (sys->es != NULL)
        {
            sys->cur_w = w;
            sys->cur_h = h;
            sys->bpp /= 8; /* bits -> bytes */
        }
    }

    /* Capture screen */
    xcb_drawable_t drawable =
        (sys->window != geo->root) ? sys->pixmap : sys->window;
    free (geo);

    block_t *block = NULL;
#if HAVE_SYS_SHM_H
    if (sys->shm)
    {   /* Capture screen through shared memory */
        size_t size = w * h * sys->bpp;
        int id = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777);
        if (id == -1) /* XXX: fallback */
        {
            msg_Err (demux, "shared memory allocation error: %m");
            goto noshm;
        }

        /* Attach the segment to X and capture */
        xcb_shm_get_image_reply_t *img;
        xcb_shm_get_image_cookie_t ck;

        xcb_shm_attach (conn, sys->segment, id, 0 /* read/write */);
        ck = xcb_shm_get_image (conn, drawable, x, y, w, h, ~0,
                                XCB_IMAGE_FORMAT_Z_PIXMAP, sys->segment, 0);
        xcb_shm_detach (conn, sys->segment);
        img = xcb_shm_get_image_reply (conn, ck, NULL);
        xcb_flush (conn); /* ensure eventual detach */

        if (img == NULL)
        {
            shmctl (id, IPC_RMID, 0);
            goto noshm;
        }
        free (img);

        /* Attach the segment to VLC */
        void *shm = shmat (id, NULL, 0 /* read/write */);
        shmctl (id, IPC_RMID, 0);
        if (-1 == (intptr_t)shm)
        {
            msg_Err (demux, "shared memory attachment error: %m");
            return;
        }

        block = block_shm_Alloc (shm, size);
        if (unlikely(block == NULL))
            shmdt (shm);
    }
noshm:
#endif
    if (block == NULL)
    {   /* Capture screen through socket (fallback) */
        xcb_get_image_reply_t *img;

        img = xcb_get_image_reply (conn,
            xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, drawable,
                           x, y, w, h, ~0), NULL);
        if (img == NULL)
            return;

        uint8_t *data = xcb_get_image_data (img);
        size_t datalen = xcb_get_image_data_length (img);
        block = block_heap_Alloc (img, data + datalen - (uint8_t *)img);
        if (block == NULL)
            return;
        block->p_buffer = data;
        block->i_buffer = datalen;
    }

    /* Send block - zero copy */
    if (sys->es != NULL)
    {
        block->i_pts = block->i_dts = mdate ();

        es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
        es_out_Send (demux->out, sys->es, block);
    }
}
Пример #16
0
Файл: swm.c Проект: JuliusP/swm
static void
events_loop (void) {
	uint32_t values[3];
	xcb_generic_event_t *ev;
	xcb_get_geometry_reply_t *geom;
	xcb_window_t win = 0;

	/* loop */
	for (;;) {
		ev = xcb_wait_for_event(conn);

		if (ev == NULL)
			errx(1, "xcb connection broken");

		switch (ev->response_type & ~0x80) {

		case XCB_CREATE_NOTIFY: {
			xcb_create_notify_event_t *e;
			e = (xcb_create_notify_event_t *)ev;

			if (!e->override_redirect) {
				setup_win(e->window);
				focus(e->window, ACTIVE);
			}
		} break;

		case XCB_DESTROY_NOTIFY: {
			xcb_destroy_notify_event_t *e;
			e = (xcb_destroy_notify_event_t *)ev;

			xcb_kill_client(conn, e->window);
		} break;

		case XCB_KEY_PRESS: {
			xcb_key_press_event_t *e;
			e = (xcb_key_press_event_t *)ev;

			xcb_keysym_t keysym = xcb_get_keysym(e->detail);

			for (unsigned int i=0; i < LENGTH(keys); i++) {
				if (keys[i].keysym == keysym
				&& CLEANMASK(keys[i].mod) == CLEANMASK(e->state)
				&& keys[i].mfunc) {
					keys[i].mfunc(keys[i].x, keys[i].y);
				}
				else if (keys[i].keysym == keysym
				&& CLEANMASK(keys[i].mod) == CLEANMASK(e->state)
				&& keys[i].func) {
					keys[i].func();
				}
			}
				} break;

		case XCB_ENTER_NOTIFY: {
			xcb_enter_notify_event_t *e;
			e = (xcb_enter_notify_event_t *)ev;

			focus(e->event, ACTIVE);
		} break;

		case XCB_MAP_NOTIFY: {
			xcb_map_notify_event_t *e;
			e = (xcb_map_notify_event_t *)ev;

			if (!e->override_redirect) {
				xcb_map_window(conn, e->window);
				xcb_set_input_focus(conn,
					XCB_INPUT_FOCUS_POINTER_ROOT,
					e->window, XCB_CURRENT_TIME);
			}
		} break;

		case XCB_BUTTON_PRESS: {
			xcb_button_press_event_t *e;
			e = ( xcb_button_press_event_t *)ev;
			win = e->child;
			if (!win || win == scr->root)
				break;
			values[0] = XCB_STACK_MODE_ABOVE;
			xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_STACK_MODE, values);
			geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
			if (1 == e->detail) {
				values[2] = 1;
				center_pointer(win);
			} else {
				values[2] = 3;
				xcb_warp_pointer(conn, XCB_NONE, win, 0, 0, 0,
						0, geom->width, geom->height);
			}
			xcb_grab_pointer(conn, 0, scr->root,
				XCB_EVENT_MASK_BUTTON_RELEASE
				| XCB_EVENT_MASK_BUTTON_MOTION
				| XCB_EVENT_MASK_POINTER_MOTION_HINT,
				XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
				scr->root, XCB_NONE, XCB_CURRENT_TIME);
			xcb_flush(conn);
		} break;

		case XCB_MOTION_NOTIFY: {
			xcb_query_pointer_reply_t *pointer;
			pointer = xcb_query_pointer_reply(conn,
					xcb_query_pointer(conn, scr->root), 0);
			if (values[2] == 1) {
				geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
				if (!geom) {
					break;
				}

				values[0] = (pointer->root_x + geom->width / 2
					> scr->width_in_pixels
					- (BORDERWIDTH*2))
					? scr->width_in_pixels - geom->width
					- (BORDERWIDTH*2)
					: pointer->root_x - geom->width / 2;
				values[1] = (pointer->root_y + geom->height / 2
					> scr->height_in_pixels
					- (BORDERWIDTH*2))
					? (scr->height_in_pixels - geom->height
					- (BORDERWIDTH*2))
					: pointer->root_y - geom->height / 2;

				if (pointer->root_x < geom->width/2)
					values[0] = 0;
				if (pointer->root_y < geom->height/2)
					values[1] = 0;

				xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_X
					| XCB_CONFIG_WINDOW_Y, values);
				xcb_flush(conn);
			} else if (values[2] == 3) {
				focus(win, RESIZE);
				geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
				values[0] = pointer->root_x - geom->x;
				values[1] = pointer->root_y - geom->y;
				xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_WIDTH
					| XCB_CONFIG_WINDOW_HEIGHT, values);
				xcb_flush(conn);
			}
		} break;

		case XCB_BUTTON_RELEASE:
			focus(win, ACTIVE);
			xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
			break;
		}

		xcb_flush(conn);
		free(ev);
	}
}
Пример #17
0
/**
 * Processing callback
 */
static void Demux (void *data)
{
    demux_t *demux = data;
    demux_sys_t *sys = demux->p_sys;
    xcb_connection_t *conn = sys->conn;

    /* Determine capture region */
    xcb_get_geometry_cookie_t gc;
    xcb_query_pointer_cookie_t qc;

    gc = xcb_get_geometry (conn, sys->window);
    if (sys->follow_mouse)
        qc = xcb_query_pointer (conn, sys->window);

    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, sys->window);
discard:
        if (sys->follow_mouse)
            xcb_discard_reply (conn, gc.sequence);
        return;
    }

    int w = sys->w;
    int h = sys->h;
    int x, y;

    if (sys->follow_mouse)
    {
        xcb_query_pointer_reply_t *ptr =
            xcb_query_pointer_reply (conn, qc, NULL);
        if (ptr == NULL)
        {
            free (geo);
            return;
        }

        if (w == 0 || w > geo->width)
            w = geo->width;
        x = ptr->win_x;
        if (x < w / 2)
            x = 0;
        else if (x >= (int)geo->width - (w / 2))
            x = geo->width - w;
        else
            x -= w / 2;

        if (h == 0 || h > geo->height)
            h = geo->height;
        y = ptr->win_y;
        if (y < h / 2)
            y = 0;
        else if (y >= (int)geo->height - (h / 2))
            y = geo->height - h;
        else
            y -= h / 2;
    }
    else
    {
        int max;

        x = sys->x;
        max = (int)geo->width - x;
        if (max <= 0)
            goto discard;
        if (w == 0 || w > max)
            w = max;

        y = sys->y;
        max = (int)geo->height - y;
        if (max <= 0)
            goto discard;
        if (h == 0 || h > max)
            h = max;
    }

    /* Update elementary stream format (if needed) */
    if (w != sys->cur_w || h != sys->cur_h)
    {
        if (sys->es != NULL)
            es_out_Del (demux->out, sys->es);

        /* Update composite pixmap */
        if (sys->window != geo->root)
        {
            xcb_free_pixmap (conn, sys->pixmap); /* no-op first time */
            xcb_composite_name_window_pixmap (conn, sys->window, sys->pixmap);
            xcb_create_pixmap (conn, geo->depth, sys->pixmap,
                               geo->root, geo->width, geo->height);
        }

        sys->es = InitES (demux, w, h, geo->depth);
        if (sys->es != NULL)
        {
            sys->cur_w = w;
            sys->cur_h = h;
        }
    }

    /* Capture screen */
    xcb_drawable_t drawable =
        (sys->window != geo->root) ? sys->pixmap : sys->window;
    free (geo);

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

    block_t *block = block_heap_Alloc (img, xcb_get_image_data (img),
                                       xcb_get_image_data_length (img));
    if (block == NULL)
        return;

    /* Send block - zero copy */
    if (sys->es != NULL)
    {
        if (sys->pts == VLC_TS_INVALID)
            sys->pts = mdate ();
        block->i_pts = block->i_dts = sys->pts;

        es_out_Control (demux->out, ES_OUT_SET_PCR, sys->pts);
        es_out_Send (demux->out, sys->es, block);
        sys->pts += sys->interval;
    }
}
Пример #18
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;
}