static void swrastGetImage(__DRIdrawable * read, int x, int y, int w, int h, char *data, void *loaderPrivate) { struct dri2_egl_surface *dri2_surf = loaderPrivate; struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); xcb_get_image_cookie_t cookie; xcb_get_image_reply_t *reply; xcb_generic_error_t *error; cookie = xcb_get_image (dri2_dpy->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, dri2_surf->drawable, x, y, w, h, ~0); reply = xcb_get_image_reply (dri2_dpy->conn, cookie, &error); if (reply == NULL) return; if (error != NULL) { _eglLog(_EGL_WARNING, "error in xcb_get_image"); free(error); } else { uint32_t bytes = xcb_get_image_data_length(reply); uint8_t *idata = xcb_get_image_data(reply); memcpy(data, idata, bytes); } free(reply); }
void _cairo_boilerplate_xcb_synchronize (void *closure) { xcb_target_closure_t *xtc = closure; free (xcb_get_image_reply (xtc->c, xcb_get_image (xtc->c, XCB_IMAGE_FORMAT_Z_PIXMAP, xtc->pixmap, 0, 0, 1, 1, /* AllPlanes */ ~0UL), 0)); }
static void _cairo_boilerplate_xcb_synchronize (void *closure) { xcb_target_closure_t *xtc = closure; cairo_status_t status; free (xcb_get_image_reply (xtc->c, xcb_get_image (xtc->c, XCB_IMAGE_FORMAT_Z_PIXMAP, xtc->drawable, 0, 0, 1, 1, /* AllPlanes */ -1), 0)); status = _cairo_boilerplate_xcb_handle_errors (xtc); assert (status == CAIRO_STATUS_SUCCESS); }
ExcCode screen_shot(int x, int y, int width, int height, Imlib_Image *res) { int x1 = x + width; int y1 = y + height; x = MAX(x, 0); y = MAX(y, 0); x1 = MIN(x1, screen->width_in_pixels); y1 = MIN(y1, screen->height_in_pixels); width = x1 - x; height = y1 - y; *res = NULL; if (shm_available) { xcb_shm_get_image_cookie_t cookie = xcb_shm_get_image(display, root, x, y, width, height, XCB_ALL_PLANES, XCB_IMAGE_FORMAT_Z_PIXMAP, shmseg, 0); xcb_shm_get_image_reply_t *reply = xcb_shm_get_image_reply(display, cookie, NULL); if (reply != NULL) { *res = imlib_create_image_using_copied_data(width, height, (unsigned *) shmaddr); free(reply); } } if (*res == NULL) { // If shm can't be used due to lack of the libraries or // because we connect to X11 on another machine (e.g. via SSH), // try to get an image via sockets. xcb_get_image_cookie_t cookie = xcb_get_image(display, XCB_IMAGE_FORMAT_Z_PIXMAP, root, x, y, width, height, XCB_ALL_PLANES); xcb_get_image_reply_t *reply = xcb_get_image_reply(display, cookie, NULL); if (reply == NULL) PANIC(ERR_X_REQUEST, "screen_shot (xcb_get_image_reply)"); *res = imlib_create_image_using_copied_data(width, height, (unsigned *) xcb_get_image_data(reply)); free(reply); } if (*res == NULL) PANIC(ERR_IMAGE); if (cursor_capturing_enabled && cursor_available) screen_cursor_blend(x, y, *res); return 0; }
xcb_get_image_reply_t * _cairo_xcb_connection_get_image (cairo_xcb_connection_t *connection, xcb_drawable_t src, int16_t src_x, int16_t src_y, uint16_t width, uint16_t height) { return xcb_get_image_reply (connection->xcb_connection, xcb_get_image (connection->xcb_connection, XCB_IMAGE_FORMAT_Z_PIXMAP, src, src_x, src_y, width, height, (uint32_t) -1), NULL); }
bool Shadow::init(const QVector< uint32_t > &data) { QVector<Xcb::WindowGeometry> pixmapGeometries(ShadowElementsCount); QVector<xcb_get_image_cookie_t> getImageCookies(ShadowElementsCount); auto *c = connection(); for (int i = 0; i < ShadowElementsCount; ++i) { pixmapGeometries[i] = Xcb::WindowGeometry(data[i]); } auto discardReplies = [&getImageCookies](int start) { for (int i = start; i < getImageCookies.size(); ++i) { xcb_discard_reply(connection(), getImageCookies.at(i).sequence); } }; for (int i = 0; i < ShadowElementsCount; ++i) { auto &geo = pixmapGeometries[i]; if (geo.isNull()) { discardReplies(0); return false; } getImageCookies[i] = xcb_get_image_unchecked(c, XCB_IMAGE_FORMAT_Z_PIXMAP, data[i], 0, 0, geo->width, geo->height, ~0); } for (int i = 0; i < ShadowElementsCount; ++i) { auto *reply = xcb_get_image_reply(c, getImageCookies.at(i), nullptr); if (!reply) { discardReplies(i+1); return false; } auto &geo = pixmapGeometries[i]; QImage image(xcb_get_image_data(reply), geo->width, geo->height, QImage::Format_ARGB32); m_shadowElements[i] = QPixmap::fromImage(image); free(reply); } m_topOffset = data[ShadowElementsCount]; m_rightOffset = data[ShadowElementsCount+1]; m_bottomOffset = data[ShadowElementsCount+2]; m_leftOffset = data[ShadowElementsCount+3]; updateShadowRegion(); if (!prepareBackend()) { return false; } buildQuads(); return true; }
ExcCode screen_shot(int x, int y, int width, int height, Imlib_Image *res) { int x1 = x + width; int y1 = y + height; x = MAX(x, 0); y = MAX(y, 0); x1 = MIN(x1, screen->width_in_pixels); y1 = MIN(y1, screen->height_in_pixels); width = x1 - x; height = y1 - y; if (shm_available) { xcb_shm_get_image_cookie_t cookie = xcb_shm_get_image(display, root, x, y, width, height, XCB_ALL_PLANES, XCB_IMAGE_FORMAT_Z_PIXMAP, shmseg, 0); xcb_shm_get_image_reply_t *reply = xcb_shm_get_image_reply(display, cookie, NULL); if (reply == NULL) PANIC(ERR_X_REQUEST, "screen_shot (xcb_shm_get_image_reply)"); *res = imlib_create_image_using_copied_data(width, height, (unsigned *) shmaddr); free(reply); } else { xcb_get_image_cookie_t cookie = xcb_get_image(display, XCB_IMAGE_FORMAT_Z_PIXMAP, root, x, y, width, height, XCB_ALL_PLANES); xcb_get_image_reply_t *reply = xcb_get_image_reply(display, cookie, NULL); if (reply == NULL) PANIC(ERR_X_REQUEST, "screen_shot (xcb_get_image_reply)"); *res = imlib_create_image_using_copied_data(width, height, (unsigned *) xcb_get_image_data(reply)); free(reply); } if (*res == NULL) PANIC(ERR_IMAGE); if (cursor_capturing_enabled && cursor_available) screen_cursor_blend(x, y, *res); return 0; }
xcb_image_t * xcb_image_get (xcb_connection_t * conn, xcb_drawable_t draw, int16_t x, int16_t y, uint16_t width, uint16_t height, uint32_t plane_mask, xcb_image_format_t format) { xcb_get_image_cookie_t image_cookie; xcb_get_image_reply_t * imrep; xcb_image_t * image = 0; uint32_t bytes; uint8_t * data; image_cookie = xcb_get_image(conn, format, draw, x, y, width, height, plane_mask); imrep = xcb_get_image_reply(conn, image_cookie, 0); if (!imrep) return 0; bytes = xcb_get_image_data_length(imrep); data = xcb_get_image_data(imrep); switch (format) { case XCB_IMAGE_FORMAT_XY_PIXMAP: plane_mask &= xcb_mask(imrep->depth); if (plane_mask != xcb_mask(imrep->depth)) { xcb_image_t * tmp_image = xcb_image_create_native(conn, width, height, format, imrep->depth, 0, 0, 0); if (!tmp_image) { free(imrep); return 0; } int i; uint32_t rpm = plane_mask; uint8_t * src_plane = image->data; uint8_t * dst_plane = tmp_image->data; uint32_t size = image->height * image->stride; if (tmp_image->bit_order == XCB_IMAGE_ORDER_MSB_FIRST) rpm = xcb_bit_reverse(plane_mask, imrep->depth); for (i = 0; i < imrep->depth; i++) { if (rpm & 1) { memcpy(dst_plane, src_plane, size); src_plane += size; } else { memset(dst_plane, 0, size); } dst_plane += size; } tmp_image->plane_mask = plane_mask; image = tmp_image; free(imrep); break; } /* fall through */ case XCB_IMAGE_FORMAT_Z_PIXMAP: image = xcb_image_create_native(conn, width, height, format, imrep->depth, imrep, bytes, data); if (!image) { free(imrep); return 0; } break; default: assert(0); } assert(bytes == image->size); return image; }
void draw_gc(xcb_window_t win) { // the only problem to draw bgr24 it bps=4 but 3, if depth=24, /* fmt depth bps 32 32 4 bgr24 24 4 16 16 2 8 8 1 0 0 0 */ //draw something in parent window for test //w = s->root; xcb_gcontext_t g_solid; uint32_t mask; uint32_t values[2]; xcb_rectangle_t r = { 0, 0, 10,10 }; xcb_rectangle_t r2 = { 20, 20, 100,100 }; xcb_connection_t *c = G.conn; if(win==0) { win=G.root; // atach to root will cause error=Resource temporary unavailable } xcb_map_window(c, win); xcb_flush(c); g_solid = xcb_generate_id(c); mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; values[0] = G.s->white_pixel; values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS; xcb_create_gc(c, g_solid, win, 0,NULL); xcb_change_gc(c, g_solid, mask, values); xcb_poly_fill_rectangle(c, win, g_solid, 1, &r2); xcb_flush(c); xcb_free_gc(c,g_solid); if(1){ //getimage xcb_get_image_cookie_t cookie; xcb_get_image_reply_t *reply; xcb_generic_error_t *error; int psize= r.width * r.height * G.s->root_depth/8; psize = r.width * r.height * 4; //correct static uint8_t *pbuf = NULL; xcb_void_cookie_t ck; if( pbuf == NULL){ pbuf = malloc(psize); printf("malloc pbuf=0x%x size=%d\n",pbuf, psize); memset(pbuf, 0x18, psize); } #if 0 cookie = xcb_get_image (c, XCB_IMAGE_FORMAT_Z_PIXMAP, win, r.x, r.y, r.width, r.height, ~0); reply = xcb_get_image_reply (c, cookie, &error); if (reply == NULL){ perror("get_image_replay"); return; } if (error != NULL) { perror("error in xcb_get_image"); free(error); } else { uint32_t bytes = xcb_get_image_data_length(reply); uint8_t *idata = xcb_get_image_data(reply); printf("get_image size=%d p=%p\n", bytes, idata); memcpy(pbuf, idata, bytes); printf("root_depth=%d\n", G.s->root_depth); psize=bytes; } free(reply); #endif //draw image with xcb_put_image // creat gc and draw to parent window xcb_gcontext_t g; g = xcb_generate_id(c); xcb_create_gc(c, g, win, 0,NULL); memset(pbuf, 0xf8, psize); int i=0; uint8_t *p2=pbuf; //fmt = bgr24 for( i=0; i<psize; ){ *(p2+i)= 0; i++; //blue *(p2+i)= 0xff; i++; //green *(p2+i)= 0; i++; //red *(p2+i)= 0x80; i++; //?? } ck = xcb_put_image_checked(c, XCB_IMAGE_FORMAT_Z_PIXMAP, win, g, r.width, r.height, r.x,r.y, 0, G.s->root_depth, psize, pbuf); xcb_flush(c); #if 0 //BadMatch=8 BadLength=16 xcb_generic_error_t *err; err = xcb_request_check (c, ck); if (err) { int code = err->error_code; free (err); printf("put image error %d\n", code); assert (code != 0); } xcb_free_gc(c, g); #endif } }
/** * 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; } }
/** * 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); }
/** * 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); } }