コード例 #1
0
ファイル: qxcbwindowsurface.cpp プロジェクト: Suneal/qt
QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
    : QXcbObject(screen->connection())
    , m_gc(0)
    , m_gc_window(0)
{
    Q_XCB_NOOP(connection());
    m_xcb_image = xcb_image_create_native(xcb_connection(),
                                          size.width(),
                                          size.height(),
                                          XCB_IMAGE_FORMAT_Z_PIXMAP,
                                          depth,
                                          0,
                                          ~0,
                                          0);

    m_shm_info.shmid = shmget (IPC_PRIVATE,
          m_xcb_image->stride * m_xcb_image->height, IPC_CREAT|0777);

    m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0);
    m_shm_info.shmseg = xcb_generate_id(xcb_connection());

    xcb_generic_error_t *error = xcb_request_check(xcb_connection(), xcb_shm_attach_checked(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false));
    if (error) {
        qWarning() << "QXcbWindowSurface: Unable to attach to shared memory segment";
        free(error);
    }

    if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
        qWarning() << "QXcbWindowSurface: Error while marking the shared memory segment to be destroyed";

    m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
}
コード例 #2
0
ファイル: screen.c プロジェクト: nkruglikov/remoteink
ExcCode screen_shm_init() {
	xcb_query_extension_cookie_t extension_cookie =
			xcb_query_extension(display,
			strlen(MIT_SHM_EXTENSION_NAME), MIT_SHM_EXTENSION_NAME);
	xcb_query_extension_reply_t *extension_reply =
			xcb_query_extension_reply(display, extension_cookie, NULL);
	if (extension_reply == NULL)
		PANIC(ERR_X_EXTENSION, MIT_SHM_EXTENSION_NAME);
	free(extension_reply);
	xcb_shm_query_version_cookie_t version_cookie =
			xcb_shm_query_version(display);
	xcb_shm_query_version_reply_t *version_reply =
			xcb_shm_query_version_reply(display, version_cookie, NULL);
	if (version_reply == NULL)
		PANIC(ERR_X_EXTENSION, MIT_SHM_EXTENSION_NAME);
	free(version_reply);
	
	size_t max_size = screen->width_in_pixels * screen->height_in_pixels *
			sizeof (unsigned);
	shmid = shmget(IPC_PRIVATE, max_size, IPC_CREAT | 0777);
	if (shmid < 0)
		PANIC(ERR_SHM_ALLOC);		
	shmaddr = shmat(shmid, 0, 0);
	if (shmaddr == (uint8_t *) -1)
		PANIC(ERR_SHM_ATTACH);
					
	shmseg = xcb_generate_id(display);
	xcb_void_cookie_t attach_cookie = xcb_shm_attach_checked(display,
			shmseg, shmid, 0);
	if (xcb_request_check(display, attach_cookie) != NULL)
		PANIC(ERR_SHM_ATTACH);
	return 0;
}
コード例 #3
0
ファイル: qxcbbackingstore.cpp プロジェクト: CodeDJ/qt5-hidpi
QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
    : QXcbObject(screen->connection())
    , m_gc(0)
    , m_gc_window(0)
{
    Q_XCB_NOOP(connection());
    m_xcb_image = xcb_image_create_native(xcb_connection(),
                                          size.width(),
                                          size.height(),
                                          XCB_IMAGE_FORMAT_Z_PIXMAP,
                                          depth,
                                          0,
                                          ~0,
                                          0);

    const int segmentSize = m_xcb_image->stride * m_xcb_image->height;
    if (!segmentSize)
        return;

    int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0600);
    if (id == -1)
        qWarning("QXcbShmImage: shmget() failed (%d) for size %d (%dx%d)",
                 errno, segmentSize, size.width(), size.height());
    else
        m_shm_info.shmid = id;
    m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0);
    m_shm_info.shmseg = xcb_generate_id(xcb_connection());

    const xcb_query_extension_reply_t *shm_reply = xcb_get_extension_data(xcb_connection(), &xcb_shm_id);
    bool shm_present = shm_reply != NULL && shm_reply->present;
    xcb_generic_error_t *error = NULL;
    if (shm_present)
        error = xcb_request_check(xcb_connection(), xcb_shm_attach_checked(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false));
    if (!shm_present || error) {
        free(error);

        shmdt(m_shm_info.shmaddr);
        shmctl(m_shm_info.shmid, IPC_RMID, 0);

        m_shm_info.shmaddr = 0;

        m_xcb_image->data = (uint8_t *)malloc(segmentSize);
    } else {
        if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
            qWarning() << "QXcbBackingStore: Error while marking the shared memory segment to be destroyed";
    }

    m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
}
コード例 #4
0
ファイル: common.c プロジェクト: BloodExecutioner/vlc
/**
 * Initialize a picture buffer as shared memory, according to the video output
 * format. If a attach is true, the segment is attached to
 * the X server (MIT-SHM extension).
 */
int PictureResourceAlloc (vout_display_t *vd, picture_resource_t *res, size_t size,
                          xcb_connection_t *conn, bool attach)
{
    res->p_sys = malloc (sizeof(*res->p_sys));
    if (!res->p_sys)
        return VLC_EGENERIC;

#ifdef HAVE_SYS_SHM_H
    /* Allocate shared memory segment */
    int id = shmget (IPC_PRIVATE, size, IPC_CREAT | S_IRWXU);
    if (id == -1)
    {
        msg_Err (vd, "shared memory allocation error: %m");
        free (res->p_sys);
        return VLC_EGENERIC;
    }

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

    xcb_shm_seg_t segment;
    if (attach)
    {
        /* Attach the segment to X */
        xcb_void_cookie_t ck;

        segment = xcb_generate_id (conn);
        ck = xcb_shm_attach_checked (conn, segment, id, 1);

        switch (CheckError (vd, conn, "shared memory server-side error", ck))
        {
            case 0:
                break;

            case XCB_ACCESS:
            {
                struct shmid_ds buf;
                /* Retry with promiscuous permissions */
                shmctl (id, IPC_STAT, &buf);
                buf.shm_perm.mode |= S_IRGRP|S_IROTH;
                shmctl (id, IPC_SET, &buf);
                ck = xcb_shm_attach_checked (conn, segment, id, 1);
                if (CheckError (vd, conn, "same error on retry", ck) == 0)
                    break;
                /* fall through */
            }

            default:
                msg_Info (vd, "using buggy X11 server - SSH proxying?");
                segment = 0;
        }
    }
    else
        segment = 0;

    shmctl (id, IPC_RMID, NULL);
    res->p_sys->segment = segment;
    res->p->p_pixels = shm;
#else
    assert (!attach);
    res->p_sys->segment = 0;

    /* XXX: align on 32 bytes for VLC chroma filters */
    res->p->p_pixels = malloc (size);
    if (unlikely(res->p->p_pixels == NULL))
    {
        free (res->p_sys);
        return VLC_EGENERIC;
    }
#endif
    return VLC_SUCCESS;
}