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; }
/** Checks MIT-SHM shared memory support */ static bool CheckSHM (xcb_connection_t *conn) { #ifdef HAVE_SYS_SHM_H xcb_shm_query_version_cookie_t ck = xcb_shm_query_version (conn); xcb_shm_query_version_reply_t *r; r = xcb_shm_query_version_reply (conn, ck, NULL); free (r); return r != NULL; #else (void) conn; return false; #endif }
void ZLEwlViewWidget::resize(int w, int h) { if(w == this->w && h == this->h) return; this->w = w; this->h = h; xcb_shm_detach(connection, shminfo.shmseg); shmdt(im->data); xcb_image_destroy(im); xcb_shm_query_version_reply_t *rep_shm; rep_shm = xcb_shm_query_version_reply (connection, xcb_shm_query_version (connection), NULL); if(rep_shm) { xcb_image_format_t format; int shmctl_status; if (rep_shm->shared_pixmaps && (rep_shm->major_version > 1 || rep_shm->minor_version > 0)) format = (xcb_image_format_t)rep_shm->pixmap_format; else format = (xcb_image_format_t)0; uint8_t depth = xcb_aux_get_depth (connection, screen); im = xcb_image_create_native (connection, w, h, format, depth, NULL, ~0, NULL); assert(im); shminfo.shmid = shmget (IPC_PRIVATE, im->stride*im->height, IPC_CREAT | 0777); assert(shminfo.shmid != -1); shminfo.shmaddr = (uint8_t*)shmat (shminfo.shmid, 0, 0); assert(shminfo.shmaddr); im->data = shminfo.shmaddr; shminfo.shmseg = xcb_generate_id (connection); xcb_shm_attach (connection, shminfo.shmseg, shminfo.shmid, 0); shmctl_status = shmctl(shminfo.shmid, IPC_RMID, 0); assert(shmctl_status != -1); free (rep_shm); } }
X11BufferSurface::X11BufferSurface(X11WindowContext& wc) : windowContext_(&wc) { gc_ = xcb_generate_id(&xConnection()); std::uint32_t value[] = {0, 0}; auto c = xcb_create_gc_checked(&xConnection(), gc_, wc.xWindow(), XCB_GC_FOREGROUND, value); windowContext().errorCategory().checkThrow(c, "ny::X11BufferSurface: create_gc"); //query the format //this is needed because the xserver may need a different bpp for an image //with the depth of the window. //For 24-bit depth images the xserver often required 32 bpp. auto setup = xcb_get_setup(&xConnection()); auto fmtit = xcb_setup_pixmap_formats(setup); auto fmtend = fmtit + xcb_setup_pixmap_formats_length(setup); xcb_format_t* fmt {}; while(fmtit != fmtend) { if(fmtit->depth == windowContext().visualDepth()) { fmt = fmtit; break; } ++fmtit; } if(!fmt) throw std::runtime_error("ny::X11BufferSurface: couldn't query depth format bpp"); format_ = visualToFormat(*windowContext().xVisualType(), fmt->bits_per_pixel); if(format_ == ImageDataFormat::none) throw std::runtime_error("ny::X11BufferSurface: couldn't parse visual format"); //check if the server has shm suport //it is also implemented without shm but the performance might be worse auto cookie = xcb_shm_query_version(&xConnection()); auto reply = xcb_shm_query_version_reply(&xConnection(), cookie, nullptr); shm_ = reply; if(reply) free(reply); if(!shm_) warning("ny::X11BufferSurface: shm server does not support shm extension"); }
/** Check MIT-SHM shared memory support */ bool CheckSHM (vlc_object_t *obj, xcb_connection_t *conn) { #ifdef HAVE_SYS_SHM_H xcb_shm_query_version_cookie_t ck; xcb_shm_query_version_reply_t *r; ck = xcb_shm_query_version (conn); r = xcb_shm_query_version_reply (conn, ck, NULL); if (r != NULL) { free (r); return true; } msg_Err (obj, "shared memory (MIT-SHM) not available"); msg_Warn (obj, "display will be slow"); #else msg_Warn (obj, "shared memory (MIT-SHM) not implemented"); (void) conn; #endif return false; }
ZLEwlViewWidget::ZLEwlViewWidget(ZLApplication *application, ZLView::Angle initialAngle) : ZLViewWidget(initialAngle) { myApplication = application; w = 600; h = 800; xcb_screen_iterator_t screen_iter; const xcb_setup_t *setup; xcb_generic_event_t *e; xcb_generic_error_t *error; xcb_void_cookie_t cookie_window; xcb_void_cookie_t cookie_map; uint32_t mask; uint32_t values[2]; int screen_number; uint8_t is_hand = 0; xcb_rectangle_t rect_coord = { 0, 0, 600, 800}; /* getting the connection */ connection = xcb_connect (NULL, &screen_number); if (xcb_connection_has_error(connection)) { fprintf (stderr, "ERROR: can't connect to an X server\n"); exit(-1); } screen = xcb_aux_get_screen (connection, screen_number); gc = xcb_generate_id (connection); mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; values[0] = screen->black_pixel; values[1] = 0; /* no graphics exposures */ xcb_create_gc (connection, gc, screen->root, mask, values); bgcolor = xcb_generate_id (connection); mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; values[0] = screen->white_pixel; values[1] = 0; /* no graphics exposures */ xcb_create_gc (connection, bgcolor, screen->root, mask, values); /* creating the window */ window = xcb_generate_id(connection); mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; values[0] = screen->white_pixel; values[1] = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE; uint8_t depth = xcb_aux_get_depth (connection, screen); xcb_create_window(connection, depth, window, screen->root, 0, 0, 600, 800, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, mask, values); rect = xcb_generate_id (connection); xcb_create_pixmap (connection, depth, rect, window, 600, 800); xcb_map_window(connection, window); xcb_colormap_t colormap; colormap = screen->default_colormap; xcb_alloc_color_reply_t *rep; rep = xcb_alloc_color_reply (connection, xcb_alloc_color (connection, colormap, 0, 0, 0), NULL); pal_[0] = rep->pixel; free(rep); rep = xcb_alloc_color_reply (connection, xcb_alloc_color (connection, colormap, 0x55<<8, 0x55<<8, 0x55<<8), NULL); pal_[1] = rep->pixel; free(rep); rep = xcb_alloc_color_reply (connection, xcb_alloc_color (connection, colormap, 0xaa<<8, 0xaa<<8, 0xaa<<8), NULL); pal_[2] = rep->pixel; free(rep); rep = xcb_alloc_color_reply (connection, xcb_alloc_color (connection, colormap, 0xff<<8, 0xff<<8, 0xff<<8), NULL); pal_[3] = rep->pixel; free(rep); pal = pal_; xcb_shm_query_version_reply_t *rep_shm; rep_shm = xcb_shm_query_version_reply (connection, xcb_shm_query_version (connection), NULL); if(rep_shm) { xcb_image_format_t format; int shmctl_status; if (rep_shm->shared_pixmaps && (rep_shm->major_version > 1 || rep_shm->minor_version > 0)) format = (xcb_image_format_t)rep_shm->pixmap_format; else format = (xcb_image_format_t)0; im = xcb_image_create_native (connection, 600, 800, format, depth, NULL, ~0, NULL); assert(im); shminfo.shmid = shmget (IPC_PRIVATE, im->stride*im->height, IPC_CREAT | 0777); assert(shminfo.shmid != -1); shminfo.shmaddr = (uint8_t*)shmat (shminfo.shmid, 0, 0); assert(shminfo.shmaddr); im->data = shminfo.shmaddr; shminfo.shmseg = xcb_generate_id (connection); xcb_shm_attach (connection, shminfo.shmseg, shminfo.shmid, 0); shmctl_status = shmctl(shminfo.shmid, IPC_RMID, 0); assert(shmctl_status != -1); free (rep_shm); } xcb_flush(connection); }