예제 #1
0
파일: ksnapshot.cpp 프로젝트: Berrrry/Qtqq
void KSnapshot::grabPointerImage(int offsetx, int offsety)
// Uses the X11_EXTENSIONS_XFIXES_H extension to grab the pointer image, and overlays it onto the snapshot.
{
#ifdef HAVE_X11_EXTENSIONS_XFIXES_H
    XFixesCursorImage *xcursorimg = XFixesGetCursorImage( QX11Info::display() );
    if ( !xcursorimg )
      return;

    //Annoyingly, xfixes specifies the data to be 32bit, but places it in an unsigned long *
    //which can be 64 bit.  So we need to iterate over a 64bit structure to put it in a 32bit
    //structure.
    QVarLengthArray< quint32 > pixels( xcursorimg->width * xcursorimg->height );
    for (int i = 0; i < xcursorimg->width * xcursorimg->height; ++i)
        pixels[i] = xcursorimg->pixels[i] & 0xffffffff;

    QImage qcursorimg((uchar *) pixels.data(), xcursorimg->width, xcursorimg->height,
                       QImage::Format_ARGB32_Premultiplied);

    QPainter painter(&snapshot);
    painter.drawImage(QPointF(xcursorimg->x - xcursorimg->xhot - offsetx, xcursorimg->y - xcursorimg ->yhot - offsety), qcursorimg);

    XFree(xcursorimg);
#else // HAVE_X11_EXTENSIONS_XFIXES_H
    Q_UNUSED(offsetx);
    Q_UNUSED(offsety);
    return;
#endif // HAVE_X11_EXTENSIONS_XFIXES_H
}
예제 #2
0
static void
xfixes_cursor_reset_image (ShellXFixesCursor *xfixes_cursor)
{
  XFixesCursorImage *cursor_image;
  CoglHandle sprite = COGL_INVALID_HANDLE;

  if (!xfixes_cursor->have_xfixes)
    return;

  cursor_image = XFixesGetCursorImage (clutter_x11_get_default_display ());
  sprite = cogl_texture_new_from_data (cursor_image->width,
                                       cursor_image->height,
                                       COGL_TEXTURE_NONE,
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
                                       COGL_PIXEL_FORMAT_BGRA_8888_PRE,
#else
                                       COGL_PIXEL_FORMAT_ARGB_8888_PRE,
#endif
                                       COGL_PIXEL_FORMAT_ANY,
                                       cursor_image->width * 4, /* stride */
                                       (const guint8 *) cursor_image->pixels);
  if (sprite != COGL_INVALID_HANDLE)
    {
      if (xfixes_cursor->cursor_sprite != NULL)
        cogl_handle_unref (xfixes_cursor->cursor_sprite);

      xfixes_cursor->cursor_sprite = sprite;
      xfixes_cursor->cursor_hot_x = cursor_image->xhot;
      xfixes_cursor->cursor_hot_y = cursor_image->yhot;
      g_signal_emit (xfixes_cursor, signals[CURSOR_CHANGED], 0);
    }
}
예제 #3
0
static void
byzanz_layer_cursor_read_cursor (ByzanzLayerCursor *clayer)
{
  Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_window_get_display (BYZANZ_LAYER (clayer)->recorder->window));

  clayer->cursor_next = XFixesGetCursorImage (dpy);
  if (clayer->cursor_next)
    g_hash_table_insert (clayer->cursors, clayer->cursor_next, clayer->cursor_next);
}
예제 #4
0
파일: x11grab.c 프로젝트: changbiao/libav
/**
 * Paint a mouse pointer in an X11 image.
 *
 * @param image image to paint the mouse pointer to
 * @param s context used to retrieve original grabbing rectangle
 *          coordinates
 */
static void paint_mouse_pointer(XImage *image, X11GrabContext *s)
{
    int x_off    = s->x_off;
    int y_off    = s->y_off;
    int width    = s->width;
    int height   = s->height;
    Display *dpy = s->dpy;
    XFixesCursorImage *xcim;
    int x, y;
    int line, column;
    int to_line, to_column;
    int pixstride = image->bits_per_pixel >> 3;
    /* Warning: in its insanity, xlib provides unsigned image data through a
     * char* pointer, so we have to make it uint8_t to make things not break.
     * Anyone who performs further investigation of the xlib API likely risks
     * permanent brain damage. */
    uint8_t *pix = image->data;

    /* Code doesn't currently support 16-bit or PAL8 */
    if (image->bits_per_pixel != 24 && image->bits_per_pixel != 32)
        return;

    xcim = XFixesGetCursorImage(dpy);
    if (!xcim)
        return;

    x = xcim->x - xcim->xhot;
    y = xcim->y - xcim->yhot;

    to_line   = FFMIN((y + xcim->height), (height + y_off));
    to_column = FFMIN((x + xcim->width),  (width  + x_off));

    for (line = FFMAX(y, y_off); line < to_line; line++) {
        for (column = FFMAX(x, x_off); column < to_column; column++) {
            int xcim_addr  = (line  - y)     * xcim->width + column - x;
            int image_addr = ((line - y_off) * width       + column - x_off) * pixstride;
            int r          = (uint8_t)(xcim->pixels[xcim_addr] >>  0);
            int g          = (uint8_t)(xcim->pixels[xcim_addr] >>  8);
            int b          = (uint8_t)(xcim->pixels[xcim_addr] >> 16);
            int a          = (uint8_t)(xcim->pixels[xcim_addr] >> 24);

            if (a == 255) {
                pix[image_addr + 0] = r;
                pix[image_addr + 1] = g;
                pix[image_addr + 2] = b;
            } else if (a) {
                /* pixel values from XFixesGetCursorImage come premultiplied by alpha */
                pix[image_addr + 0] = r + (pix[image_addr + 0] * (255 - a) + 255 / 2) / 255;
                pix[image_addr + 1] = g + (pix[image_addr + 1] * (255 - a) + 255 / 2) / 255;
                pix[image_addr + 2] = b + (pix[image_addr + 2] * (255 - a) + 255 / 2) / 255;
            }
        }
    }

    XFree(xcim);
    xcim = NULL;
}
예제 #5
0
void xcursor_tick(xcursor_t *data) {
	XFixesCursorImage *xc = XFixesGetCursorImage(data->dpy);

	if (!data->tex || data->last_serial != xc->cursor_serial)
		xcursor_create(data, xc);
	data->pos_x = -1.0 * (xc->x - xc->xhot - data->x_org);
	data->pos_y = -1.0 * (xc->y - xc->yhot - data->y_org);

	XFree(xc);
}
예제 #6
0
static void tc_x11source_acquire_cursor_fixes(TCX11Source *handle,
                                              uint8_t *data, int maxdata)
{
    XFixesCursorImage *cursor = XFixesGetCursorImage(handle->dpy);

    if (cursor == NULL) {
        /* this MUST be noisy! */
        tc_log_warn(__FILE__, "failed to get cursor image");
    } else {
        /* FIXME: this has to be rewritten and need significant
         * internal refactoring :( */
    }
}
예제 #7
0
void xcursor_tick(xcursor_t *data) {
	XFixesCursorImage *xc = XFixesGetCursorImage(data->dpy);

	if (!data->tex || data->last_serial != xc->cursor_serial)
		xcursor_create(data, xc);

	data->x = (int_fast32_t)xc->x - (int_fast32_t)data->x_org;
	data->y = (int_fast32_t)xc->y - (int_fast32_t)data->y_org;
	data->render_x = xc->x - xc->xhot - data->x_org;
	data->render_y = xc->y - xc->yhot - data->y_org;

	XFree(xc);
}
예제 #8
0
int main(int argc, char** argv) {
    if (argc != 2 || !argv[1][0] || !argv[1][1]) {
        fprintf(stderr, "Usage: %s chrootdisplay\n", argv[0]);
        return 2;
    }
    /* Make sure the displays aren't equal */
    char *cros_n = XDisplayName(NULL);
    if (cros_n[1] == argv[1][1]) {
        fprintf(stderr, "You must specify a different display.\n");
        return 2;
    }
    /* Open the displays */
    Display *cros_d, *chroot_d;
    Window cros_w, chroot_w;
    if (!(cros_d = XOpenDisplay(NULL))) {
        fprintf(stderr, "Failed to open Chromium OS display\n");
        return 1;
    }
    if (!(chroot_d = XOpenDisplay(argv[1]))) {
        fprintf(stderr, "Failed to open chroot display %s\n", argv[1]);
        return 1;
    }
    /* Get the XFixes extension for the chroot to monitor the cursor */
    int xfixes_event, xfixes_error;
    if (!XFixesQueryExtension(chroot_d, &xfixes_event, &xfixes_error)) {
        fprintf(stderr, "chroot is missing XFixes extension\n");
        return 1;

    }
    XSetErrorHandler(error_handler);
    /* Get the root windows */
    cros_w = DefaultRootWindow(cros_d);
    chroot_w = DefaultRootWindow(chroot_d);
    /* Monitor the chroot root window for cursor changes */
    XFixesSelectCursorInput(chroot_d, chroot_w, XFixesDisplayCursorNotifyMask);
    XEvent e;
    while (!error) {
        XNextEvent(chroot_d, &e);
        if (error) break;
        if (e.type != xfixes_event + XFixesCursorNotify) continue;
        /* Grab the new cursor and apply it to the Chromium OS X11 server */
        XFixesCursorImage *img = XFixesGetCursorImage(chroot_d);
        apply_cursor(cros_d, cros_w, img);
        XFree(img);
    }
    /* Clean up */
    apply_cursor(cros_d, cros_w, NULL);
    XCloseDisplay(cros_d);
    XCloseDisplay(chroot_d);
    return 0;
}
예제 #9
0
			Utilities::Point GetCursorPos()
			{
				auto display = XOpenDisplay(NULL);
				auto root = DefaultRootWindow(display);
				auto img = XFixesGetCursorImage(display);

				// Get the mouse cursor position
				int x, y, root_x, root_y = 0;
				unsigned int mask = 0;
				Window child_win, root_win;
				XQueryPointer(display, root, &child_win, &root_win, &root_x, &root_y, &x, &y, &mask);
				x -= img->xhot;
				y -= img->yhot;
				XFree(img);
				XCloseDisplay(display);

				return Utilities::Point(x, y);
			}
예제 #10
0
			std::shared_ptr<Utilities::Image> CaptureMouseImage()
			{
				auto display = XOpenDisplay(NULL);
				auto img = XFixesGetCursorImage(display);

				if (sizeof(img->pixels[0]) == 8) {
					auto pixels = (int *)img->pixels;
					for (auto i = 0; i < img->width * img->height; ++i) {
						pixels[i] = pixels[i * 2];
					}
				}

				auto i = Utilities::Image::CreateImage(img->height, img->width, (char*)img->pixels, 4);

				XFree(img);
				XCloseDisplay(display);
				return i;
			}
예제 #11
0
void MouseCursor::update()
{
#ifdef Q_OS_LINUX
    XFixesCursorImage *img = XFixesGetCursorImage(QX11Info::display());

    // realloc enough buffer
    size_ = QSize(img->width, img->height);
    int pixels = size_.width() * size_.height();
    if(pixels > reserved_) {
        delete pixmap_data_;
        reserved_ = pixels;
        pixmap_data_ = new uint32_t[reserved_];
    }

    /* copy Data removing redundant bits if needed
     * Note: sizeof(unsigned long) is 8 bytes in 64bit unix,
     *       but only bottom 4 bytes are used. (00000000AARRGGBB)
     *       So we have to remove top 4 bytes.
     */
    unsigned long *data = img->pixels;
    for(int i = 0; i < pixels; ++i) {
        pixmap_data_[i] = data[i];
    }

    // calc mouse pos
    pos_ = QCursor::pos();
    pos_ -= QPoint(img->xhot, img->yhot);

    free(img);
#else
    return;
    // TODO: write Platform dependent code for other than X11
    //       such as MS_Windows and Mac_OSX
#endif

}
예제 #12
0
void
updateCursor (CompCursor    *c,
	      int	    x,
	      int	    y,
	      unsigned long serial)
{
    /* new current cursor */
    if (!c->image || c->image->serial != serial)
    {
	CompCursorImage *cursorImage;

	cursorImage = findCursorImageAtScreen (c->screen, serial);
	if (!cursorImage)
	{
	    Display	      *dpy = c->screen->display->display;
	    XFixesCursorImage *image;

	    image = XFixesGetCursorImage (dpy);
	    if (!image)
		return;

	    cursorImage = malloc (sizeof (CompCursorImage));
	    if (!cursorImage)
	    {
		XFree (image);
		return;
	    }

	    x = image->x;
	    y = image->y;

	    cursorImage->serial = image->cursor_serial;
	    cursorImage->xhot   = image->xhot;
	    cursorImage->yhot   = image->yhot;
	    cursorImage->width  = image->width;
	    cursorImage->height = image->height;

	    initTexture (c->screen, &cursorImage->texture);

	    if (!imageBufferToTexture (c->screen,
				       &cursorImage->texture,
				       (char *) image->pixels,
				       image->width,
				       image->height))
	    {
		free (cursorImage);
		XFree (image);
		return;
	    }

	    XFree (image);

	    cursorImage->next = c->screen->cursorImages;
	    c->screen->cursorImages = cursorImage;
	}

	if (c->image)
	    addCursorDamage (c);

	c->image = cursorImage;

	c->x = x - c->image->xhot;
	c->y = y - c->image->yhot;

	setCursorMatrix (c);

	addCursorDamage (c);
    }
    else
    {
	int newX, newY;

	newX = x - c->image->xhot;
	newY = y - c->image->yhot;

	if (c->x != newX || c->y != newY)
	{
	    addCursorDamage (c);

	    c->x = newX;
	    c->y = newY;

	    setCursorMatrix (c);

	    addCursorDamage (c);
	}
    }
}
예제 #13
0
파일: x11_shadow.c 프로젝트: DavBfr/FreeRDP
int x11_shadow_query_cursor(x11ShadowSubsystem* subsystem, BOOL getImage)
{
	int x, y, n, k;
	rdpShadowServer* server;
	rdpShadowSurface* surface;

	server = subsystem->server;
	surface = server->surface;

	if (getImage)
	{
#ifdef WITH_XFIXES
		UINT32* pDstPixel;
		XFixesCursorImage* ci;

		XLockDisplay(subsystem->display);
		ci = XFixesGetCursorImage(subsystem->display);
		XUnlockDisplay(subsystem->display);

		if (!ci)
			return -1;

		x = ci->x;
		y = ci->y;

		if (ci->width > subsystem->cursorMaxWidth)
			return -1;

		if (ci->height > subsystem->cursorMaxHeight)
			return -1;

		subsystem->cursorHotX = ci->xhot;
		subsystem->cursorHotY = ci->yhot;

		subsystem->cursorWidth = ci->width;
		subsystem->cursorHeight = ci->height;

		subsystem->cursorId = ci->cursor_serial;

		n = ci->width * ci->height;
		pDstPixel = (UINT32*) subsystem->cursorPixels;

		for (k = 0; k < n; k++)
		{
			/* XFixesCursorImage.pixels is in *unsigned long*, which may be 8 bytes */
			*pDstPixel++ = (UINT32) ci->pixels[k];
		}

		XFree(ci);

		x11_shadow_pointer_alpha_update(subsystem);
#endif
	}
	else
	{
		UINT32 mask;
		int win_x, win_y;
		int root_x, root_y;
		Window root, child;

		XLockDisplay(subsystem->display);

		if (!XQueryPointer(subsystem->display, subsystem->root_window,
				&root, &child, &root_x, &root_y, &win_x, &win_y, &mask))
		{
			XUnlockDisplay(subsystem->display);
			return -1;
		}

		XUnlockDisplay(subsystem->display);

		x = root_x;
		y = root_y;
	}

	/* Convert to offset based on current surface */
	if (surface)
	{
		x -= surface->x;
		y -= surface->y;
	}

	if ((x != subsystem->pointerX) || (y != subsystem->pointerY))
	{
		subsystem->pointerX = x;
		subsystem->pointerY = y;

		x11_shadow_pointer_position_update(subsystem);
	}

	return 1;
}
static void
xfixes_cursor_reset_image (ShellXFixesCursor *xfixes_cursor)
{
  XFixesCursorImage *cursor_image;
  CoglHandle sprite = COGL_INVALID_HANDLE;
  guint8 *cursor_data;
  gboolean free_cursor_data;

  if (!xfixes_cursor->have_xfixes)
    return;

  cursor_image = XFixesGetCursorImage (clutter_x11_get_default_display ());
  if (!cursor_image)
    return;

  /* Like all X APIs, XFixesGetCursorImage() returns arrays of 32-bit
   * quantities as arrays of long; we need to convert on 64 bit */
  if (sizeof(long) == 4)
    {
      cursor_data = (guint8 *)cursor_image->pixels;
      free_cursor_data = FALSE;
    }
  else
    {
      int i, j;
      guint32 *cursor_words;
      gulong *p;
      guint32 *q;

      cursor_words = g_new (guint32, cursor_image->width * cursor_image->height);
      cursor_data = (guint8 *)cursor_words;

      p = cursor_image->pixels;
      q = cursor_words;
      for (j = 0; j < cursor_image->height; j++)
        for (i = 0; i < cursor_image->width; i++)
          *(q++) = *(p++);

      free_cursor_data = TRUE;
    }

  sprite = cogl_texture_new_from_data (cursor_image->width,
                                       cursor_image->height,
                                       COGL_TEXTURE_NONE,
                                       CLUTTER_CAIRO_FORMAT_ARGB32,
                                       COGL_PIXEL_FORMAT_ANY,
                                       cursor_image->width * 4, /* stride */
                                       cursor_data);

  if (free_cursor_data)
    g_free (cursor_data);

  if (sprite != COGL_INVALID_HANDLE)
    {
      if (xfixes_cursor->cursor_sprite != NULL)
        cogl_handle_unref (xfixes_cursor->cursor_sprite);

      xfixes_cursor->cursor_sprite = sprite;
      xfixes_cursor->cursor_hot_x = cursor_image->xhot;
      xfixes_cursor->cursor_hot_y = cursor_image->yhot;
      g_signal_emit (xfixes_cursor, signals[CURSOR_CHANGED], 0);
    }
  XFree (cursor_image);
}
예제 #15
0
/* Finds NaCl/Chromium shm memory using external handler.
 * Reply must be in the form PID:file */
struct cache_entry* find_shm(uint64_t paddr, uint64_t sig, size_t length) {
    struct cache_entry* entry = NULL;

    /* Find entry in cache */
    if (cache[0].paddr == paddr) {
        entry = &cache[0];
    } else if (cache[1].paddr == paddr) {
        entry = &cache[1];
    } else {
        /* Not found: erase an existing entry. */
        entry = &cache[next_entry];
        next_entry = (next_entry + 1) % 2;
        close_mmap(entry);
    }

    int try;
    for (try = 0; try < 2; try++) {
        /* Check signature */
        if (entry->map) {
            if (*((uint64_t*)entry->map) == sig)
                return entry;

            log(1, "Invalid signature, fetching new shm!");
            close_mmap(entry);
        }

        /* Setup parameters and run command */
        char arg1[32], arg2[32];
        int c;

        c = snprintf(arg1, sizeof(arg1), "%08lx", (long)paddr & 0xffffffff);
        trueorabort(c > 0, "snprintf");
        int i, p = 0;
        for (i = 0; i < 8; i++) {
            c = snprintf(arg2 + p, sizeof(arg2) - p, "%02x",
                         ((uint8_t*)&sig)[i]);
            trueorabort(c > 0, "snprintf");
            p += c;
        }

        char* cmd = "croutonfindnacl";
        char* args[] = {cmd, arg1, arg2, NULL};
        char buffer[256];
        log(2, "Running %s %s %s", cmd, arg1, arg2);
        c = popen2(cmd, args, NULL, 0, buffer, sizeof(buffer));
        if (c <= 0) {
            error("Error running helper.");
            return NULL;
        }
        buffer[c < sizeof(buffer) ? c : (sizeof(buffer)-1)] = 0;
        log(2, "Result: %s", buffer);

        /* Parse PID:file output */
        char* cut = strchr(buffer, ':');
        if (!cut) {
            error("No ':' in helper reply: %s.", cut);
            return NULL;
        }
        *cut = 0;

        char* endptr;
        long pid = strtol(buffer, &endptr, 10);
        if(buffer == endptr || *endptr != '\0') {
            error("Invalid pid: %s", buffer);
            return NULL;
        }
        char* file = cut+1;
        log(2, "PID:%ld, FILE:%s", pid, file);

        entry->paddr = paddr;
        entry->fd = open(file, O_RDWR);
        if (entry->fd < 0) {
            error("Cannot open file %s\n", file);
            return NULL;
        }

        entry->length = length;
        entry->map = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED,
                          entry->fd, 0);
        if (!entry->map) {
            error("Cannot mmap %s\n", file);
            close(entry->fd);
            return NULL;
        }

        log(2, "mmap ok %p %zu %d", entry->map, entry->length, entry->fd);
    }

    error("Cannot find shm.");
    return NULL;
}

/* WebSocket functions */

XImage* img = NULL;
XShmSegmentInfo shminfo;

/* Writes framebuffer image to websocket/shm */
int write_image(const struct screen* screen) {
    char reply_raw[FRAMEMAXHEADERSIZE + sizeof(struct screen_reply)];
    struct screen_reply* reply =
        (struct screen_reply*)(reply_raw + FRAMEMAXHEADERSIZE);
    int refresh = 0;

    memset(reply_raw, 0, sizeof(reply_raw));

    reply->type = 'S';
    reply->width = screen->width;
    reply->height = screen->height;

    /* Allocate XShmImage */
    if (!img || img->width != screen->width || img->height != screen->height) {
        if (img) {
            XDestroyImage(img);
            shmdt(shminfo.shmaddr);
            shmctl(shminfo.shmid, IPC_RMID, 0);
        }

        /* FIXME: Some error checking should happen here... */
        img = XShmCreateImage(dpy, DefaultVisual(dpy, 0), 24,
                              ZPixmap, NULL, &shminfo,
                              screen->width, screen->height);
        trueorabort(img, "XShmCreateImage");
        shminfo.shmid = shmget(IPC_PRIVATE, img->bytes_per_line*img->height,
                               IPC_CREAT|0777);
        trueorabort(shminfo.shmid != -1, "shmget");
        shminfo.shmaddr = img->data = shmat(shminfo.shmid, 0, 0);
        trueorabort(shminfo.shmaddr != (void*)-1, "shmat");
        shminfo.readOnly = False;
        int ret = XShmAttach(dpy, &shminfo);
        trueorabort(ret, "XShmAttach");
        /* Force refresh */
        refresh = 1;
    }

    if (screen->refresh) {
        log(1, "Force refresh from client.");
        /* refresh forced by the client */
        refresh = 1;
    }

    XEvent ev;
    /* Register damage on new windows */
    while (XCheckTypedEvent(dpy, MapNotify, &ev)) {
        register_damage(dpy, ev.xcreatewindow.window);
        refresh = 1;
    }

    /* Check for damage */
    while (XCheckTypedEvent(dpy, damageEvent + XDamageNotify, &ev)) {
        refresh = 1;
    }

    /* Check for cursor events */
    reply->cursor_updated = 0;
    while (XCheckTypedEvent(dpy, fixesEvent + XFixesCursorNotify, &ev)) {
        XFixesCursorNotifyEvent* curev = (XFixesCursorNotifyEvent*)&ev;
        if (verbose >= 2) {
            char* name = XGetAtomName(dpy, curev->cursor_name);
            log(2, "cursor! %ld %s", curev->cursor_serial, name);
            XFree(name);
        }
        reply->cursor_updated = 1;
        reply->cursor_serial = curev->cursor_serial;
    }

    /* No update */
    if (!refresh) {
        reply->shm = 0;
        reply->updated = 0;
        socket_client_write_frame(reply_raw, sizeof(*reply),
                                  WS_OPCODE_BINARY, 1);
        return 0;
    }

    /* Get new image from framebuffer */
    XShmGetImage(dpy, DefaultRootWindow(dpy), img, 0, 0, AllPlanes);

    int size = img->bytes_per_line * img->height;

    trueorabort(size == screen->width*screen->height*4,
                "Invalid screen byte count");

    trueorabort(screen->shm, "Non-SHM rendering is not supported");

    struct cache_entry* entry = find_shm(screen->paddr, screen->sig, size);

    reply->shm = 1;
    reply->updated = 1;
    reply->shmfailed = 0;

    if (entry && entry->map) {
        if (size == entry->length) {
            memcpy(entry->map, img->data, size);
            msync(entry->map, size, MS_SYNC);
        } else {
            /* This should never happen (it means the client passed an
             * outdated buffer to us). */
            error("Invalid shm entry length (client bug!).");
            reply->shmfailed = 1;
        }
    } else {
        /* Keep the flow going, even if we cannot find the shm. Next time
         * the NaCl client reallocates the buffer, we are likely to be able
         * to find it. */
        error("Cannot find shm, moving on...");
        reply->shmfailed = 1;
    }

    /* Confirm write is done */
    socket_client_write_frame(reply_raw, sizeof(*reply),
                              WS_OPCODE_BINARY, 1);

    return 0;
}

/* Writes cursor image to websocket */
int write_cursor() {
    XFixesCursorImage *img = XFixesGetCursorImage(dpy);
    if (!img) {
        error("XFixesGetCursorImage returned NULL");
        return -1;
    }
    int size = img->width*img->height;
    const int replylength = sizeof(struct cursor_reply) + size*sizeof(uint32_t);
    char reply_raw[FRAMEMAXHEADERSIZE + replylength];
    struct cursor_reply* reply =
        (struct cursor_reply*)(reply_raw + FRAMEMAXHEADERSIZE);

    memset(reply_raw, 0, sizeof(*reply_raw));

    reply->type = 'P';
    reply->width = img->width;
    reply->height = img->height;
    reply->xhot = img->xhot;
    reply->yhot = img->yhot;
    reply->cursor_serial = img->cursor_serial;
    /* This casts long[] to uint32_t[] */
    int i;
    for (i = 0; i < size; i++)
        reply->pixels[i] = img->pixels[i];

    socket_client_write_frame(reply_raw, replylength, WS_OPCODE_BINARY, 1);
    XFree(img);

    return 0;
}
예제 #16
0
static void
ensure_xfixes_cursor (MetaCursorTracker *tracker)
{
  MetaDisplay *display = meta_get_display ();
  XFixesCursorImage *cursor_image;
  CoglTexture2D *sprite;
  guint8 *cursor_data;
  gboolean free_cursor_data;
  CoglContext *ctx;
  CoglError *error = NULL;

  if (tracker->xfixes_cursor)
    return;

  cursor_image = XFixesGetCursorImage (display->xdisplay);
  if (!cursor_image)
    return;

  /* Like all X APIs, XFixesGetCursorImage() returns arrays of 32-bit
   * quantities as arrays of long; we need to convert on 64 bit */
  if (sizeof(long) == 4)
    {
      cursor_data = (guint8 *)cursor_image->pixels;
      free_cursor_data = FALSE;
    }
  else
    {
      int i, j;
      guint32 *cursor_words;
      gulong *p;
      guint32 *q;

      cursor_words = g_new (guint32, cursor_image->width * cursor_image->height);
      cursor_data = (guint8 *)cursor_words;

      p = cursor_image->pixels;
      q = cursor_words;
      for (j = 0; j < cursor_image->height; j++)
        for (i = 0; i < cursor_image->width; i++)
          *(q++) = *(p++);

      free_cursor_data = TRUE;
    }

  ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
  sprite = cogl_texture_2d_new_from_data (ctx,
                                          cursor_image->width,
                                          cursor_image->height,
                                          CLUTTER_CAIRO_FORMAT_ARGB32,
                                          cursor_image->width * 4, /* stride */
                                          cursor_data,
                                          &error);

  if (free_cursor_data)
    g_free (cursor_data);

  if (error != NULL)
    {
      meta_warning ("Failed to allocate cursor sprite texture: %s\n", error->message);
      cogl_error_free (error);
    }

  if (sprite != NULL)
    {
      MetaCursorSprite *cursor_sprite = meta_cursor_sprite_new ();
      meta_cursor_sprite_set_texture (cursor_sprite,
                                      sprite,
                                      cursor_image->xhot,
                                      cursor_image->yhot);
      cogl_object_unref (sprite);
      tracker->xfixes_cursor = cursor_sprite;
    }
  XFree (cursor_image);
}
예제 #17
0
static void
ensure_xfixes_cursor (MetaCursorTracker *tracker)
{
  XFixesCursorImage *cursor_image;
  CoglTexture2D *sprite;
  guint8 *cursor_data;
  gboolean free_cursor_data;
  CoglContext *ctx;

  if (tracker->sprite)
    return;

  cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay);
  if (!cursor_image)
    return;

  /* Like all X APIs, XFixesGetCursorImage() returns arrays of 32-bit
   * quantities as arrays of long; we need to convert on 64 bit */
  if (sizeof(long) == 4)
    {
      cursor_data = (guint8 *)cursor_image->pixels;
      free_cursor_data = FALSE;
    }
  else
    {
      int i, j;
      guint32 *cursor_words;
      gulong *p;
      guint32 *q;

      cursor_words = g_new (guint32, cursor_image->width * cursor_image->height);
      cursor_data = (guint8 *)cursor_words;

      p = cursor_image->pixels;
      q = cursor_words;
      for (j = 0; j < cursor_image->height; j++)
        for (i = 0; i < cursor_image->width; i++)
          *(q++) = *(p++);

      free_cursor_data = TRUE;
    }

  ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
  sprite = cogl_texture_2d_new_from_data (ctx,
                                          cursor_image->width,
                                          cursor_image->height,
                                          CLUTTER_CAIRO_FORMAT_ARGB32,
                                          cursor_image->width * 4, /* stride */
                                          cursor_data,
                                          NULL);

  if (free_cursor_data)
    g_free (cursor_data);

  if (sprite != NULL)
    {
      tracker->sprite = sprite;
      tracker->hot_x = cursor_image->xhot;
      tracker->hot_y = cursor_image->yhot;
    }
  XFree (cursor_image);
}
예제 #18
0
int x11_shadow_query_cursor(x11ShadowSubsystem* subsystem, BOOL getImage)
{
	int x, y, n, k;
	rdpShadowServer* server;
	rdpShadowSurface* surface;

	server = subsystem->server;
	surface = server->surface;

	if (getImage)
	{
#ifdef WITH_XFIXES
		UINT32* pDstPixel;
		XFixesCursorImage* ci;

		ci = XFixesGetCursorImage(subsystem->display);

		x = ci->x;
		y = ci->y;

		if (ci->width > subsystem->cursorMaxWidth)
			return -1;

		if (ci->height > subsystem->cursorMaxHeight)
			return -1;

		subsystem->cursorHotX = ci->xhot;
		subsystem->cursorHotY = ci->yhot;

		subsystem->cursorWidth = ci->width;
		subsystem->cursorHeight = ci->height;

		subsystem->cursorId = ci->cursor_serial;

		n = ci->width * ci->height;
		pDstPixel = (UINT32*) subsystem->cursorPixels;

		for (k = 0; k < n; k++)
		{
			/* XFixesCursorImage.pixels is in *unsigned long*, which may be 8 bytes */
			*pDstPixel++ = (UINT32) ci->pixels[k];
		}

		XFree(ci);
#endif
	}
	else
	{
		UINT32 mask;
		int win_x, win_y;
		int root_x, root_y;
		Window root, child;

		if (!XQueryPointer(subsystem->display, subsystem->root_window,
				&root, &child, &root_x, &root_y, &win_x, &win_y, &mask))
		{
			return -1;
		}

		x = root_x;
		y = root_y;
	}

	subsystem->cursorX = x;
	subsystem->cursorY = y;

	return 1;
}