void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &source) { Q_XCB_NOOP(connection()); if (m_gc_window != window) { if (m_gc) Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc)); m_gc = xcb_generate_id(xcb_connection()); Q_XCB_CALL(xcb_create_gc(xcb_connection(), m_gc, window, 0, 0)); m_gc_window = window; } Q_XCB_NOOP(connection()); xcb_image_shm_put(xcb_connection(), window, m_gc, m_xcb_image, m_shm_info, source.x(), source.y(), target.x(), target.y(), source.width(), source.height(), false); Q_XCB_NOOP(connection()); m_dirty = m_dirty | source; xcb_flush(xcb_connection()); Q_XCB_NOOP(connection()); }
void ZLEwlViewWidget::invertRegion(int x0, int y0, int x1, int y1, bool flush) { unsigned int pixel; for(int i = x0; i <= x1; i++) { for(int j = y0; j <= y1; j++) { pixel = 0xffffff & xcb_image_get_pixel(im, i, j); for(int idx = 0; idx < 4; idx++) { if(pixel == (0xffffff & pal[idx])) { xcb_image_put_pixel(im, i, j, pal[3 - idx]); break; } } } } uint8_t send_event; if(flush) send_event = 1; else send_event = 0; xcb_image_shm_put (connection, window, gc, im, shminfo, x0, y0, x0, y0, x1 - x0, y1 - y0, send_event); if(flush) xcb_flush(connection); }
void ZLEwlViewWidget::doPaint() { ZLEwlPaintContext &pContext = (ZLEwlPaintContext&)view()->context(); pContext.image = im; pContext.myWidth = w; pContext.myHeight = h; view()->paint(); xcb_image_shm_put (connection, window, gc, pContext.image, shminfo, 0, 0, 0, 0, w, h, 0); xcb_flush(connection); }
void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &source) { Q_XCB_NOOP(connection()); if (m_gc_window != window) { if (m_gc) Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc)); m_gc = xcb_generate_id(xcb_connection()); Q_XCB_CALL(xcb_create_gc(xcb_connection(), m_gc, window, 0, 0)); m_gc_window = window; } Q_XCB_NOOP(connection()); if (m_shm_info.shmaddr) { xcb_image_shm_put(xcb_connection(), window, m_gc, m_xcb_image, m_shm_info, source.x(), source.y(), target.x(), target.y(), source.width(), source.height(), false); } else { // If we upload the whole image in a single chunk, the result might be // larger than the server's maximum request size and stuff breaks. // To work around that, we upload the image in chunks where each chunk // is small enough for a single request. int src_x = source.x(); int src_y = source.y(); int target_x = target.x(); int target_y = target.y(); int width = source.width(); int height = source.height(); // We must make sure that each request is not larger than max_req_size. // Each request takes req_size + m_xcb_image->stride * height bytes. uint32_t max_req_size = xcb_get_maximum_request_length(xcb_connection()); uint32_t req_size = sizeof(xcb_put_image_request_t); int rows_per_put = (max_req_size - req_size) / m_xcb_image->stride; // This assert could trigger if a single row has more pixels than fit in // a single PutImage request. However, max_req_size is guaranteed to be // at least 16384 bytes. That should be enough for quite large images. Q_ASSERT(rows_per_put > 0); while (height > 0) { int rows = std::min(height, rows_per_put); xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, src_x, src_y, width, rows, 0, 0, 0); xcb_image_put(xcb_connection(), window, m_gc, subimage, target_x, target_y, 0); xcb_image_destroy(subimage); src_y += rows; target_y += rows; height -= rows; } } Q_XCB_NOOP(connection()); m_dirty = m_dirty | source; xcb_flush(xcb_connection()); Q_XCB_NOOP(connection()); }