/** Check whether the needed X extensions are present on the * server-side (all the data have been previously pre-fetched in the * extension cache). Then send requests to check their version by * sending QueryVersion requests which is compulsory because the * client MUST negotiate the version of the extension before * executing extension requests */ void display_init_extensions(void) { globalconf.extensions.composite = xcb_get_extension_data(globalconf.connection, &xcb_composite_id); globalconf.extensions.xfixes = xcb_get_extension_data(globalconf.connection, &xcb_xfixes_id); globalconf.extensions.damage = xcb_get_extension_data(globalconf.connection, &xcb_damage_id); globalconf.extensions.randr = xcb_get_extension_data(globalconf.connection, &xcb_randr_id); if(!globalconf.extensions.composite || !globalconf.extensions.composite->present) fatal("No Composite extension"); debug("Composite: major_opcode=%ju", (uintmax_t) globalconf.extensions.composite->major_opcode); if(!globalconf.extensions.xfixes || !globalconf.extensions.xfixes->present) fatal("No XFixes extension"); debug("XFixes: major_opcode=%ju", (uintmax_t) globalconf.extensions.xfixes->major_opcode); if(!globalconf.extensions.damage || !globalconf.extensions.damage->present) fatal("No Damage extension"); debug("Damage: major_opcode=%ju", (uintmax_t) globalconf.extensions.damage->major_opcode); _init_extensions_cookies.composite = xcb_composite_query_version_unchecked(globalconf.connection, XCB_COMPOSITE_MAJOR_VERSION, XCB_COMPOSITE_MINOR_VERSION); _init_extensions_cookies.damage = xcb_damage_query_version_unchecked(globalconf.connection, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION); _init_extensions_cookies.xfixes = xcb_xfixes_query_version_unchecked(globalconf.connection, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION); if(globalconf.extensions.randr && globalconf.extensions.randr->present) _init_extensions_cookies.randr = xcb_randr_query_version(globalconf.connection, XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION); else globalconf.extensions.randr = NULL; }
/** * Check if the xserver supports all the extensions we need */ static bool xshm_check_extensions(xcb_connection_t *xcb) { bool ok = true; if (!xcb_get_extension_data(xcb, &xcb_shm_id)->present) { blog(LOG_ERROR, "Missing SHM extension !"); ok = false; } if (!xcb_get_extension_data(xcb, &xcb_xinerama_id)->present) blog(LOG_INFO, "Missing Xinerama extension !"); return ok; }
BOOL PRESENTCheckExtension(Display *dpy, int major, int minor) { xcb_connection_t *xcb_connection = XGetXCBConnection(dpy); xcb_present_query_version_cookie_t present_cookie; xcb_present_query_version_reply_t *present_reply; xcb_generic_error_t *error; const xcb_query_extension_reply_t *extension; xcb_prefetch_extension_data(xcb_connection, &xcb_present_id); extension = xcb_get_extension_data(xcb_connection, &xcb_present_id); if (!(extension && extension->present)) { ERR("PRESENT extension is not present\n"); return FALSE; } present_cookie = xcb_present_query_version(xcb_connection, major, minor); present_reply = xcb_present_query_version_reply(xcb_connection, present_cookie, &error); if (!present_reply) { free(error); ERR("Issue getting requested version of PRESENT: %d,%d\n", major, minor); return FALSE; } TRACE("PRESENT version %d,%d found. %d %d requested\n", major, minor, (int)present_reply->major_version, (int)present_reply->minor_version); free(present_reply); return TRUE; }
/* Set up RANDR extension */ void randr_init(xcb_connection_t * conn,xcb_screen_t * screen) { const xcb_query_extension_reply_t *extension; extension = xcb_get_extension_data(conn, &xcb_randr_id); if (!extension->present) { PDEBUG("No RANDR extension.\n"); return; } else { randr_get(conn,screen); } randrbase = extension->first_event; PDEBUG("randrbase is %d.\n", randrbase); xcb_randr_select_input(conn, screen->root, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE | XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE | XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE | XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY); }
void xinerama_test(void) { /* check for xinerama extension */ if (xcb_get_extension_data(wm_conf.connection, &xcb_xinerama_id)->present) { xcb_xinerama_is_active_reply_t *r; r = xcb_xinerama_is_active_reply(wm_conf.connection, xcb_xinerama_is_active(wm_conf.connection), NULL); wm_conf.xinerama_is_active = r->state; free(r); } fprintf(stderr, "xinerama is %sactive\n", (wm_conf.xinerama_is_active ? "" : "NOT ")); if (wm_conf.xinerama_is_active) { xcb_xinerama_query_screens_reply_t *r; xcb_xinerama_screen_info_t *screen_info; int num_screens; r = xcb_xinerama_query_screens_reply(wm_conf.connection, xcb_xinerama_query_screens_unchecked(wm_conf.connection), NULL); screen_info = xcb_xinerama_query_screens_screen_info(r); num_screens = xcb_xinerama_query_screens_screen_info_length(r); fprintf(stderr, "xinerama: num_screens=%d\n", num_screens); int screen; for (screen = 0; screen < num_screens; ++screen) { xcb_xinerama_screen_info_t *info = &screen_info[screen]; fprintf(stderr, "xinerama: screen %d\n", screen); fprintf(stderr, " x_org = %d\n", info->x_org); fprintf(stderr, " y_org = %d\n", info->y_org); fprintf(stderr, " width = %u\n", info->width); fprintf(stderr, " height = %u\n", info->height); } free(r); } }
void _ecore_xcb_dpms_finalize(void) { #ifdef ECORE_XCB_DPMS const xcb_query_extension_reply_t *ext_reply; #endif LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_DPMS ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_dpms_id); if ((ext_reply) && (ext_reply->present)) { xcb_dpms_get_version_cookie_t cookie; xcb_dpms_get_version_reply_t *reply; cookie = xcb_dpms_get_version_unchecked(_ecore_xcb_conn, XCB_DPMS_MAJOR_VERSION, XCB_DPMS_MINOR_VERSION); reply = xcb_dpms_get_version_reply(_ecore_xcb_conn, cookie, NULL); if (reply) { if (reply->server_major_version >= 1) _dpms_avail = EINA_TRUE; free(reply); } } #endif }
/* * This sets up the DAMAGE extentsion to receive damage events on all * child windows * */ static void set_up_damage_notifications(xcb_connection_t *conn, xcb_screen_t *scr) { xcb_damage_query_version_unchecked(conn, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION); dam_ext_data = xcb_get_extension_data(conn, &xcb_damage_id); xcb_query_tree_reply_t *reply = xcb_query_tree_reply(conn, xcb_query_tree(conn, scr->root), NULL); xcb_window_t *children = xcb_query_tree_children(reply); xcb_get_window_attributes_cookie_t *attribs = (xcb_get_window_attributes_cookie_t *)malloc( sizeof(xcb_get_window_attributes_cookie_t) * reply->children_len); if (!attribs) { errx(EXIT_FAILURE, "Failed to allocate memory"); } for (int i = 0; i < reply->children_len; ++i) { attribs[i] = xcb_get_window_attributes_unchecked(conn, children[i]); } for (int i = 0; i < reply->children_len; ++i) { /* Get attributes to check if input-only window */ xcb_get_window_attributes_reply_t *attrib = xcb_get_window_attributes_reply(conn, attribs[i], NULL); create_damage(conn, children[i], attrib); } free(attribs); free(reply); }
bool QXcbGlxIntegration::initialize(QXcbConnection *connection) { m_connection = connection; #ifdef XCB_HAS_XCB_GLX const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection->xcb_connection(), &xcb_glx_id); if (!reply || !reply->present) return false; m_glx_first_event = reply->first_event; xcb_generic_error_t *error = 0; xcb_glx_query_version_cookie_t xglx_query_cookie = xcb_glx_query_version(m_connection->xcb_connection(), XCB_GLX_MAJOR_VERSION, XCB_GLX_MINOR_VERSION); xcb_glx_query_version_reply_t *xglx_query = xcb_glx_query_version_reply(m_connection->xcb_connection(), xglx_query_cookie, &error); if (!xglx_query || error) { qCWarning(QT_XCB_GLINTEGRATION) << "QXcbConnection: Failed to initialize GLX"; free(error); return false; } free(xglx_query); #endif m_native_interface_handler.reset(new QXcbGlxNativeInterfaceHandler(connection->nativeInterface())); qCDebug(QT_XCB_GLINTEGRATION) << "Xcb GLX gl-integration successfully initialized"; return true; }
FdoSelectionManager::FdoSelectionManager(): QObject(), m_selectionOwner(new KSelectionOwner(Xcb::atoms->selectionAtom, -1, this)) { qCDebug(SNIPROXY) << "starting"; //load damage extension xcb_connection_t *c = QX11Info::connection(); xcb_prefetch_extension_data(c, &xcb_damage_id); const auto *reply = xcb_get_extension_data(c, &xcb_damage_id); if (reply->present) { m_damageEventBase = reply->first_event; xcb_damage_query_version_unchecked(c, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION); } else { //no XDamage means qCCritical(SNIPROXY) << "could not load damage extension. Quitting"; qApp->exit(-1); } qApp->installNativeEventFilter(this); m_selectionOwner->claim(false); connect(m_selectionOwner, &KSelectionOwner::claimedOwnership, this, &FdoSelectionManager::onClaimedOwnership); connect(m_selectionOwner, &KSelectionOwner::failedToClaimOwnership, this, &FdoSelectionManager::onFailedToClaimOwnership); connect(m_selectionOwner, &KSelectionOwner::lostOwnership, this, &FdoSelectionManager::onLostOwnership); }
void _ecore_xcb_input_finalize(void) { #ifdef ECORE_XCB_XINPUT xcb_input_get_extension_version_cookie_t cookie; xcb_input_get_extension_version_reply_t *reply; char buff[128]; #endif LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_XINPUT cookie = xcb_input_get_extension_version_unchecked(_ecore_xcb_conn, 127, buff); reply = xcb_input_get_extension_version_reply(_ecore_xcb_conn, cookie, NULL); if (reply) { _input_avail = EINA_TRUE; free(reply); } if (_input_avail) { const xcb_query_extension_reply_t *ext_reply; ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_input_id); if (ext_reply) _ecore_xcb_event_input = ext_reply->first_event; } #endif }
void _ecore_xcb_gesture_finalize(void) { #ifdef ECORE_XCB_XGESTURE xcb_gesture_query_version_cookie_t cookie; xcb_gesture_query_version_reply_t *reply; #endif LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_XGESTURE cookie = xcb_gesture_query_version_unchecked(_ecore_xcb_conn); reply = xcb_gesture_query_version_reply(_ecore_xcb_conn, cookie, NULL); if (reply) { _gesture_available = EINA_TRUE; free(reply); } if (_gesture_available) { const xcb_query_extension_reply_t *ext_reply; ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_gesture_id); if (ext_reply) _ecore_xcb_event_gesture = ext_reply->first_event; } #endif }
Bool hostx_has_extension(xcb_extension_t *extension) { const xcb_query_extension_reply_t *rep; rep = xcb_get_extension_data(HostX.conn, extension); return rep && rep->present; }
void _ecore_xcb_render_finalize(void) { #ifdef ECORE_XCB_RENDER const xcb_query_extension_reply_t *ext_reply; #endif LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_RENDER ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_render_id); if ((ext_reply) && (ext_reply->present)) { xcb_render_query_version_cookie_t cookie; xcb_render_query_version_reply_t *reply; cookie = xcb_render_query_version_unchecked(_ecore_xcb_conn, XCB_RENDER_MAJOR_VERSION, XCB_RENDER_MINOR_VERSION); reply = xcb_render_query_version_reply(_ecore_xcb_conn, cookie, NULL); if (reply) { // if ((reply->major_version >= XCB_RENDER_MAJOR_VERSION) && if (reply->minor_version >= XCB_RENDER_MINOR_VERSION) { char *v = NULL; _render_avail = EINA_TRUE; _ecore_xcb_xdefaults_init(); if ((reply->major_version > 0) || (reply->minor_version >= 5)) { _render_argb = EINA_TRUE; v = getenv("XCURSOR_CORE"); if (!v) v = _ecore_xcb_xdefaults_string_get("Xcursor", "core"); if ((v) && (_ecore_xcb_render_parse_boolean(v))) _render_argb = EINA_FALSE; } if ((_render_argb) && ((reply->major_version > 0) || (reply->minor_version >= 8))) { _render_anim = EINA_TRUE; v = getenv("XCURSOR_ANIM"); if (!v) v = _ecore_xcb_xdefaults_string_get("Xcursor", "anim"); if ((v) && (_ecore_xcb_render_parse_boolean(v))) _render_anim = EINA_FALSE; } _ecore_xcb_xdefaults_shutdown(); } } free(reply); } #endif }
static int get_xkb_event_id(xcb_connection_t *c) { const xcb_query_extension_reply_t *extdata; if (!(extdata = xcb_get_extension_data(c, &xcb_xkb_id))) return -1; return extdata->first_event; }
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); }
/* * Initialize yabar */ void ya_init() { signal(SIGTERM, ya_sighandler); signal(SIGINT, ya_sighandler); signal(SIGKILL, ya_sighandler); signal(SIGHUP, ya_sighandler); ya.depth = 32; ya.c = xcb_connect(NULL, NULL); ya.scr = xcb_setup_roots_iterator(xcb_get_setup(ya.c)).data; ya.visualtype = ya_get_visualtype(); if (ya.visualtype == NULL) { // if depth=32 not found, fallback to depth=24 ya.depth = 24; ya.visualtype = ya_get_visualtype(); } ya.colormap = xcb_generate_id(ya.c); xcb_create_colormap(ya.c, XCB_COLORMAP_ALLOC_NONE, ya.colormap, ya.scr->root, ya.visualtype->visual_id); const xcb_query_extension_reply_t *ya_reply; ya_reply = xcb_get_extension_data(ya.c, &xcb_randr_id); if (ya_reply->present) { ya.gen_flag |= GEN_RANDR; ya_init_randr(); } #ifdef YA_INTERNAL_EWMH ya.ewmh = malloc(sizeof(xcb_ewmh_connection_t)); if (xcb_ewmh_init_atoms_replies(ya.ewmh, xcb_ewmh_init_atoms(ya.c, ya.ewmh), NULL)==0) { fprintf(stderr, "Cannot use EWMH\n"); //Should exit program or not? //To be decided. } ya.lstwin = XCB_NONE; uint32_t evm = XCB_EVENT_MASK_PROPERTY_CHANGE; xcb_change_window_attributes(ya.c, ya.curwin, XCB_CW_EVENT_MASK, &evm); xcb_change_window_attributes(ya.c, ya.scr->root, XCB_CW_EVENT_MASK, &evm); xcb_get_property_cookie_t prop_ck = xcb_ewmh_get_active_window(ya.ewmh, 0); xcb_ewmh_get_active_window_reply(ya.ewmh, prop_ck, &ya.curwin, NULL); xcb_get_property_cookie_t ws_ck = xcb_ewmh_get_current_desktop(ya.ewmh, 0); xcb_ewmh_get_current_desktop_reply(ya.ewmh, ws_ck, &ya.curws, NULL); //fprintf(stderr, "WINNN = %x DESK= %x\n", ya.curwin, ya.curws); #endif //YA_INTERNAL_EWMH ya_config_parse(); }
void _ecore_xcb_composite_finalize(void) { #ifdef ECORE_XCB_COMPOSITE const xcb_query_extension_reply_t *ext_reply; #endif LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_COMPOSITE ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_composite_id); if ((ext_reply) && (ext_reply->present)) { xcb_composite_query_version_cookie_t cookie; xcb_composite_query_version_reply_t *reply; cookie = xcb_composite_query_version_unchecked(_ecore_xcb_conn, XCB_COMPOSITE_MAJOR_VERSION, XCB_COMPOSITE_MINOR_VERSION); reply = xcb_composite_query_version_reply(_ecore_xcb_conn, cookie, NULL); if (reply) { // if ((reply->major_version >= XCB_COMPOSITE_MAJOR_VERSION) && if (reply->minor_version >= XCB_COMPOSITE_MINOR_VERSION) { # ifdef ECORE_XCB_RENDER if (_ecore_xcb_render_avail_get()) { # ifdef ECORE_XCB_XFIXES if (_ecore_xcb_xfixes_avail_get()) _composite_avail = EINA_TRUE; # endif } # endif } free(reply); } } #endif }
uint32_t xcb_generate_id(xcb_connection_t *c) { uint32_t ret; if(c->has_error) return -1; pthread_mutex_lock(&c->xid.lock); if(c->xid.last >= c->xid.max - c->xid.inc + 1) { xcb_xc_misc_get_xid_range_reply_t *range; assert(c->xid.last == c->xid.max); if (c->xid.last == 0) { /* finish setting up initial range */ c->xid.max = c->setup->resource_id_mask; } else { /* check for extension */ const xcb_query_extension_reply_t *xc_misc_reply = xcb_get_extension_data(c, &xcb_xc_misc_id); if (!xc_misc_reply) { pthread_mutex_unlock(&c->xid.lock); return -1; } /* get new range */ range = xcb_xc_misc_get_xid_range_reply(c, xcb_xc_misc_get_xid_range(c), 0); /* XXX The latter disjunct is what the server returns when it is out of XIDs. Sweet. */ if(!range || (range->start_id == 0 && range->count == 1)) { pthread_mutex_unlock(&c->xid.lock); return -1; } assert(range->count > 0 && range->start_id > 0); c->xid.last = range->start_id; c->xid.max = range->start_id + (range->count - 1) * c->xid.inc; free(range); } } else { c->xid.last += c->xid.inc; } ret = c->xid.last | c->xid.base; pthread_mutex_unlock(&c->xid.lock); return ret; }
bool ScreenManager::configureRandR(xcb_connection_t *conn) { const xcb_query_extension_reply_t *ext = xcb_get_extension_data(conn, &xcb_randr_id); if (!ext->present) { return false; } xcb_randr_query_version_reply_t *ver = xcb_randr_query_version_reply( conn, xcb_randr_query_version(conn, 1, 1), 0); if (!ver) { return false; } _randrBase = ext->first_event; xcb_randr_select_input(conn, _rootWindow, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE | XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE | XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE | XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY); xcb_flush(conn); return true; }
void xcb_prefetch_maximum_request_length(xcb_connection_t *c) { if(c->has_error) return; pthread_mutex_lock(&c->out.reqlenlock); if(c->out.maximum_request_length_tag == LAZY_NONE) { const xcb_query_extension_reply_t *ext; ext = xcb_get_extension_data(c, &xcb_big_requests_id); if(ext && ext->present) { c->out.maximum_request_length_tag = LAZY_COOKIE; c->out.maximum_request_length.cookie = xcb_big_requests_enable(c); } else { c->out.maximum_request_length_tag = LAZY_FORCED; c->out.maximum_request_length.value = c->setup->maximum_request_length; } } pthread_mutex_unlock(&c->out.reqlenlock); }
bool xinerama(void) { bool is_active = false; if (xcb_get_extension_data(cfg.conn, &xcb_xinerama_id)->present) { xcb_xinerama_is_active_reply_t *reply = xcb_xinerama_is_active_reply(cfg.conn, xcb_xinerama_is_active(cfg.conn), (void *)0); if (!reply) return false; is_active = reply->state; free(reply); } if (!is_active) { warn("xinerama is not present\n"); return false; } const xcb_xinerama_query_screens_cookie_t cookie = xcb_xinerama_query_screens_unchecked(cfg.conn); xcb_xinerama_query_screens_reply_t *reply = xcb_xinerama_query_screens_reply(cfg.conn, cookie, (void *)0); if (!reply) return false; const xcb_xinerama_screen_info_t *info = xcb_xinerama_query_screens_screen_info(reply); int screens = xcb_xinerama_query_screens_screen_info_length(reply); PRINTF("xinerama screens: %d\n", screens); for (int screen = 0; screen < screens; screen++) { PRINTF("adding screen: %d\n", screen); monitor_add(info[screen].x_org, info[screen].y_org, info[screen].width, info[screen].height); } free(reply); return true; }
BOOL DRI3CheckExtension(Display *dpy, int major, int minor) { xcb_connection_t *xcb_connection = XGetXCBConnection(dpy); xcb_dri3_query_version_cookie_t dri3_cookie; xcb_dri3_query_version_reply_t *dri3_reply; xcb_generic_error_t *error; const xcb_query_extension_reply_t *extension; int fd; xcb_prefetch_extension_data(xcb_connection, &xcb_dri3_id); extension = xcb_get_extension_data(xcb_connection, &xcb_dri3_id); if (!(extension && extension->present)) { ERR("DRI3 extension is not present\n"); return FALSE; } dri3_cookie = xcb_dri3_query_version(xcb_connection, major, minor); dri3_reply = xcb_dri3_query_version_reply(xcb_connection, dri3_cookie, &error); if (!dri3_reply) { free(error); ERR("Issue getting requested version of DRI3: %d,%d\n", major, minor); return FALSE; } if (!DRI3Open(dpy, DefaultScreen(dpy), &fd)) { ERR("DRI3 advertised, but not working\n"); return FALSE; } close(fd); TRACE("DRI3 version %d,%d found. %d %d requested\n", major, minor, (int)dri3_reply->major_version, (int)dri3_reply->minor_version); free(dri3_reply); return TRUE; }
void _ecore_xcb_xfixes_finalize(void) { #ifdef ECORE_XCB_XFIXES const xcb_query_extension_reply_t *ext_reply; #endif LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_XFIXES ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xfixes_id); if ((ext_reply) && (ext_reply->present)) { xcb_xfixes_query_version_cookie_t cookie; xcb_xfixes_query_version_reply_t *reply; cookie = xcb_xfixes_query_version_unchecked(_ecore_xcb_conn, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION); reply = xcb_xfixes_query_version_reply(_ecore_xcb_conn, cookie, NULL); if (reply) { /* NB: XFixes Extension >= 3 needed for shape stuff. * for now, I am removing this check so that it matches the * xlib code closer. If the extension version ends up being * that important, then re-enable this */ /* if (reply->major_version >= 3) */ _xfixes_avail = EINA_TRUE; free(reply); } if (_xfixes_avail) _ecore_xcb_event_xfixes = ext_reply->first_event; } #endif }
bool randr(void) { if (!xcb_get_extension_data(cfg.conn, &xcb_randr_id)->present) { warn("randr is not present\n"); return false; } const xcb_randr_get_screen_resources_cookie_t cookie = xcb_randr_get_screen_resources_unchecked(cfg.conn, cfg.screen->root); xcb_randr_get_screen_resources_reply_t *reply = xcb_randr_get_screen_resources_reply(cfg.conn, cookie, (void *)0); if (!reply) return false; const xcb_randr_crtc_t *info = xcb_randr_get_screen_resources_crtcs(reply); PRINTF("randr num crtcs: %u\n", reply->num_crtcs); xcb_randr_get_crtc_info_cookie_t cookies[reply->num_crtcs]; for (uint16_t crtc = 0; crtc < reply->num_crtcs; crtc++) cookies[crtc] = xcb_randr_get_crtc_info_unchecked(cfg.conn, info[crtc], XCB_CURRENT_TIME); for (uint16_t crtc = 0; crtc < reply->num_crtcs; crtc++) { xcb_randr_get_crtc_info_reply_t *reply = xcb_randr_get_crtc_info_reply(cfg.conn, cookies[crtc], (void *)0); if (!reply) continue; PRINTF("adding crtc: %u\n", crtc); monitor_add(reply->x, reply->y, reply->width, reply->height); free(reply); } free(reply); return true; }
void _ecore_xcb_screensaver_finalize(void) { #ifdef ECORE_XCB_SCREENSAVER const xcb_query_extension_reply_t *ext_reply; #endif LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_SCREENSAVER ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_screensaver_id); if ((ext_reply) && (ext_reply->present)) { xcb_screensaver_query_version_cookie_t cookie; xcb_screensaver_query_version_reply_t *reply; cookie = xcb_screensaver_query_version_unchecked(_ecore_xcb_conn, XCB_SCREENSAVER_MAJOR_VERSION, XCB_SCREENSAVER_MINOR_VERSION); reply = xcb_screensaver_query_version_reply(_ecore_xcb_conn, cookie, NULL); if (reply) { if ((reply->server_major_version >= XCB_SCREENSAVER_MAJOR_VERSION) && (reply->server_minor_version >= XCB_SCREENSAVER_MINOR_VERSION)) _screensaver_avail = EINA_TRUE; free(reply); } if (_screensaver_avail) _ecore_xcb_event_screensaver = ext_reply->first_event; } #endif }
/* @brief Attempts to find secondary displays and updates settings.screen_* data * with the dimensions of the found screens. * * Note: failure is somewhat expected and is handled by simply using the default * xcb screen's dimension parameters. * * @param connection A connection to the Xorg server. * @param screen A screen created by xcb's xcb_setup_roots function. * @return 0 on success and 1 on failure. */ static int32_t get_multiscreen_settings(xcb_connection_t *connection, xcb_screen_t *screen) { /* First check randr. */ const xcb_query_extension_reply_t *extension_reply = xcb_get_extension_data(connection, &xcb_randr_id); if (extension_reply && extension_reply->present) { debug("Found randr support, searching for displays.\n"); /* Find x, y and width, height. */ xcb_randr_get_screen_resources_current_reply_t *randr_reply = xcb_randr_get_screen_resources_current_reply(connection, xcb_randr_get_screen_resources_current(connection, screen->root), NULL); if (!randr_reply) { fprintf(stderr, "Failed to get randr set up.\n"); } else { int32_t num_outputs = xcb_randr_get_screen_resources_current_outputs_length(randr_reply); if (num_outputs < settings.screen) { fprintf(stderr, "Screen selected not found.\n"); /* Default back to the first screen. */ settings.screen = 0; } xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_current_outputs(randr_reply); uint32_t output_index = settings.screen; xcb_randr_get_output_info_reply_t *randr_output = NULL; do { if (randr_output) { free(randr_output); } randr_output = xcb_randr_get_output_info_reply(connection, xcb_randr_get_output_info(connection, outputs[output_index], XCB_CURRENT_TIME), NULL); output_index++; } while ((randr_output->connection != XCB_RANDR_CONNECTION_CONNECTED) && (output_index < num_outputs)); if (randr_output) { xcb_randr_get_crtc_info_reply_t *randr_crtc = xcb_randr_get_crtc_info_reply(connection, xcb_randr_get_crtc_info(connection, randr_output->crtc, XCB_CURRENT_TIME), NULL); if (!randr_crtc) { fprintf(stderr, "Unable to connect to randr crtc\n"); free(randr_output); free(randr_reply); goto xinerama; } settings.screen_width = randr_crtc->width; settings.screen_height = randr_crtc->height; settings.screen_x = randr_crtc->x; settings.screen_y = randr_crtc->y; debug("randr screen initialization successful, x: %u y: %u w: %u h: %u.\n", settings.screen_x, settings.screen_y, settings.screen_width, settings.screen_height); free(randr_crtc); free(randr_output); free(randr_reply); return 0; } free(randr_output); free(randr_reply); } } xinerama: debug("Did not find randr support, attempting xinerama\n"); /* Still here? Let's try xinerama! */ extension_reply = xcb_get_extension_data(connection, &xcb_xinerama_id); if (extension_reply && extension_reply->present) { debug("Found xinerama support, searching for displays.\n"); xcb_xinerama_is_active_reply_t *xinerama_is_active_reply = xcb_xinerama_is_active_reply(connection, xcb_xinerama_is_active(connection), NULL); if (xinerama_is_active_reply && xinerama_is_active_reply->state) { free(xinerama_is_active_reply); /* Find x, y and width, height. */ xcb_xinerama_query_screens_reply_t *screen_reply = xcb_xinerama_query_screens_reply(connection, xcb_xinerama_query_screens_unchecked(connection), NULL); xcb_xinerama_screen_info_iterator_t iter = xcb_xinerama_query_screens_screen_info_iterator(screen_reply); free(screen_reply); if (iter.rem < settings.screen) { fprintf(stderr, "Screen selected not found.\n"); /* Default back to the first screen. */ settings.screen = 0; } /* Jump to the appropriate screen. */ int32_t i = 0; while (i < settings.screen) { xcb_xinerama_screen_info_next(&iter); i++; } settings.screen_width = iter.data->width; settings.screen_height = iter.data->height; settings.screen_x = iter.data->x_org; settings.screen_y = iter.data->y_org; debug("xinerama screen initialization successful, x: %u y: %u w: %u h: %u.\n", settings.screen_x, settings.screen_y, settings.screen_width, settings.screen_height); return 0; } } debug("Multiscreen search failed.\n"); return 1; }
static EGLBoolean dri2_connect(struct dri2_egl_display *dri2_dpy) { xcb_xfixes_query_version_reply_t *xfixes_query; xcb_xfixes_query_version_cookie_t xfixes_query_cookie; xcb_dri2_query_version_reply_t *dri2_query; xcb_dri2_query_version_cookie_t dri2_query_cookie; xcb_dri2_connect_reply_t *connect; xcb_dri2_connect_cookie_t connect_cookie; xcb_generic_error_t *error; xcb_screen_iterator_t s; char *driver_name, *device_name; const xcb_query_extension_reply_t *extension; xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_xfixes_id); xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri2_id); extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_xfixes_id); if (!(extension && extension->present)) return EGL_FALSE; extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_dri2_id); if (!(extension && extension->present)) return EGL_FALSE; xfixes_query_cookie = xcb_xfixes_query_version(dri2_dpy->conn, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION); dri2_query_cookie = xcb_dri2_query_version (dri2_dpy->conn, XCB_DRI2_MAJOR_VERSION, XCB_DRI2_MINOR_VERSION); s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); connect_cookie = xcb_dri2_connect_unchecked (dri2_dpy->conn, s.data->root, XCB_DRI2_DRIVER_TYPE_DRI); xfixes_query = xcb_xfixes_query_version_reply (dri2_dpy->conn, xfixes_query_cookie, &error); if (xfixes_query == NULL || error != NULL || xfixes_query->major_version < 2) { _eglLog(_EGL_WARNING, "DRI2: failed to query xfixes version"); free(error); return EGL_FALSE; } free(xfixes_query); dri2_query = xcb_dri2_query_version_reply (dri2_dpy->conn, dri2_query_cookie, &error); if (dri2_query == NULL || error != NULL) { _eglLog(_EGL_WARNING, "DRI2: failed to query version"); free(error); return EGL_FALSE; } dri2_dpy->dri2_major = dri2_query->major_version; dri2_dpy->dri2_minor = dri2_query->minor_version; free(dri2_query); connect = xcb_dri2_connect_reply (dri2_dpy->conn, connect_cookie, NULL); if (connect == NULL || connect->driver_name_length + connect->device_name_length == 0) { _eglLog(_EGL_WARNING, "DRI2: failed to authenticate"); return EGL_FALSE; } driver_name = xcb_dri2_connect_driver_name (connect); dri2_dpy->driver_name = dri2_strndup(driver_name, xcb_dri2_connect_driver_name_length (connect)); device_name = xcb_dri2_connect_device_name (connect); dri2_dpy->device_name = dri2_strndup(device_name, xcb_dri2_connect_device_name_length (connect)); if (dri2_dpy->device_name == NULL || dri2_dpy->driver_name == NULL) { free(dri2_dpy->device_name); free(dri2_dpy->driver_name); free(connect); return EGL_FALSE; } free(connect); return EGL_TRUE; }
struct vl_screen * vl_dri3_screen_create(Display *display, int screen) { struct vl_dri3_screen *scrn; const xcb_query_extension_reply_t *extension; xcb_dri3_open_cookie_t open_cookie; xcb_dri3_open_reply_t *open_reply; xcb_get_geometry_cookie_t geom_cookie; xcb_get_geometry_reply_t *geom_reply; int is_different_gpu; int fd; assert(display); scrn = CALLOC_STRUCT(vl_dri3_screen); if (!scrn) return NULL; scrn->conn = XGetXCBConnection(display); if (!scrn->conn) goto free_screen; xcb_prefetch_extension_data(scrn->conn , &xcb_dri3_id); xcb_prefetch_extension_data(scrn->conn, &xcb_present_id); extension = xcb_get_extension_data(scrn->conn, &xcb_dri3_id); if (!(extension && extension->present)) goto free_screen; extension = xcb_get_extension_data(scrn->conn, &xcb_present_id); if (!(extension && extension->present)) goto free_screen; open_cookie = xcb_dri3_open(scrn->conn, RootWindow(display, screen), None); open_reply = xcb_dri3_open_reply(scrn->conn, open_cookie, NULL); if (!open_reply) goto free_screen; if (open_reply->nfd != 1) { free(open_reply); goto free_screen; } fd = xcb_dri3_open_reply_fds(scrn->conn, open_reply)[0]; if (fd < 0) { free(open_reply); goto free_screen; } fcntl(fd, F_SETFD, FD_CLOEXEC); free(open_reply); fd = loader_get_user_preferred_fd(fd, &is_different_gpu); /* TODO support different GPU */ if (is_different_gpu) goto close_fd; geom_cookie = xcb_get_geometry(scrn->conn, RootWindow(display, screen)); geom_reply = xcb_get_geometry_reply(scrn->conn, geom_cookie, NULL); if (!geom_reply) goto close_fd; /* TODO support depth other than 24 */ if (geom_reply->depth != 24) { free(geom_reply); goto close_fd; } free(geom_reply); if (pipe_loader_drm_probe_fd(&scrn->base.dev, fd)) scrn->base.pscreen = pipe_loader_create_screen(scrn->base.dev); if (!scrn->base.pscreen) goto release_pipe; scrn->base.destroy = vl_dri3_screen_destroy; scrn->base.texture_from_drawable = vl_dri3_screen_texture_from_drawable; scrn->base.get_dirty_area = vl_dri3_screen_get_dirty_area; scrn->base.get_timestamp = vl_dri3_screen_get_timestamp; scrn->base.set_next_timestamp = vl_dri3_screen_set_next_timestamp; scrn->base.get_private = vl_dri3_screen_get_private; scrn->base.pscreen->flush_frontbuffer = vl_dri3_flush_frontbuffer; return &scrn->base; release_pipe: if (scrn->base.dev) { pipe_loader_release(&scrn->base.dev, 1); fd = -1; } close_fd: if (fd != -1) close(fd); free_screen: FREE(scrn); return NULL; }
int main ( int argc, char *argv[] ) { TIMINGS_START (); cmd_set_arguments ( argc, argv ); // Version if ( find_arg ( "-v" ) >= 0 || find_arg ( "-version" ) >= 0 ) { #ifdef GIT_VERSION fprintf ( stdout, "Version: "GIT_VERSION "\n" ); #else fprintf ( stdout, "Version: "VERSION "\n" ); #endif exit ( EXIT_SUCCESS ); } // Detect if we are in dmenu mode. // This has two possible causes. // 1 the user specifies it on the command-line. if ( find_arg ( "-dmenu" ) >= 0 ) { dmenu_mode = TRUE; } // 2 the binary that executed is called dmenu (e.g. symlink to rofi) else{ // Get the base name of the executable called. char *base_name = g_path_get_basename ( argv[0] ); const char * const dmenu_str = "dmenu"; dmenu_mode = ( strcmp ( base_name, dmenu_str ) == 0 ); // Free the basename for dmenu detection. g_free ( base_name ); } TICK (); // Get the path to the cache dir. cache_dir = g_get_user_cache_dir (); // Create pid file path. const char *path = g_get_user_runtime_dir (); if ( path ) { pidfile = g_build_filename ( path, "rofi.pid", NULL ); } config_parser_add_option ( xrm_String, "pid", (void * *) &pidfile, "Pidfile location" ); if ( find_arg ( "-config" ) < 0 ) { const char *cpath = g_get_user_config_dir (); if ( cpath ) { config_path = g_build_filename ( cpath, "rofi", "config", NULL ); } } else { char *c = NULL; find_arg_str ( "-config", &c ); config_path = rofi_expand_path ( c ); } TICK (); // Register cleanup function. atexit ( cleanup ); TICK (); // Get DISPLAY, first env, then argument. char *display_str = getenv ( "DISPLAY" ); find_arg_str ( "-display", &display_str ); if ( setlocale ( LC_ALL, "" ) == NULL ) { fprintf ( stderr, "Failed to set locale.\n" ); return EXIT_FAILURE; } xcb->connection = xcb_connect ( display_str, &xcb->screen_nbr ); if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Failed to open display: %s", display_str ); return EXIT_FAILURE; } TICK_N ( "Open Display" ); xcb->screen = xcb_aux_get_screen ( xcb->connection, xcb->screen_nbr ); xcb_intern_atom_cookie_t *ac = xcb_ewmh_init_atoms ( xcb->connection, &xcb->ewmh ); xcb_generic_error_t *errors = NULL; xcb_ewmh_init_atoms_replies ( &xcb->ewmh, ac, &errors ); if ( errors ) { fprintf ( stderr, "Failed to create EWMH atoms\n" ); free ( errors ); } if ( xkb_x11_setup_xkb_extension ( xcb->connection, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION, XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, NULL, NULL, &xkb.first_event, NULL ) < 0 ) { fprintf ( stderr, "cannot setup XKB extension!\n" ); return EXIT_FAILURE; } xkb.context = xkb_context_new ( XKB_CONTEXT_NO_FLAGS ); if ( xkb.context == NULL ) { fprintf ( stderr, "cannot create XKB context!\n" ); return EXIT_FAILURE; } xkb.xcb_connection = xcb->connection; xkb.device_id = xkb_x11_get_core_keyboard_device_id ( xcb->connection ); enum { required_events = ( XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY | XCB_XKB_EVENT_TYPE_STATE_NOTIFY ), required_nkn_details = ( XCB_XKB_NKN_DETAIL_KEYCODES ), required_map_parts = ( XCB_XKB_MAP_PART_KEY_TYPES | XCB_XKB_MAP_PART_KEY_SYMS | XCB_XKB_MAP_PART_MODIFIER_MAP | XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS | XCB_XKB_MAP_PART_KEY_ACTIONS | XCB_XKB_MAP_PART_VIRTUAL_MODS | XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP ), required_state_details = ( XCB_XKB_STATE_PART_MODIFIER_BASE | XCB_XKB_STATE_PART_MODIFIER_LATCH | XCB_XKB_STATE_PART_MODIFIER_LOCK | XCB_XKB_STATE_PART_GROUP_BASE | XCB_XKB_STATE_PART_GROUP_LATCH | XCB_XKB_STATE_PART_GROUP_LOCK ), }; static const xcb_xkb_select_events_details_t details = { .affectNewKeyboard = required_nkn_details, .newKeyboardDetails = required_nkn_details, .affectState = required_state_details, .stateDetails = required_state_details, }; xcb_xkb_select_events ( xcb->connection, xkb.device_id, required_events, /* affectWhich */ 0, /* clear */ required_events, /* selectAll */ required_map_parts, /* affectMap */ required_map_parts, /* map */ &details ); xkb.keymap = xkb_x11_keymap_new_from_device ( xkb.context, xcb->connection, xkb.device_id, XKB_KEYMAP_COMPILE_NO_FLAGS ); if ( xkb.keymap == NULL ) { fprintf ( stderr, "Failed to get Keymap for current keyboard device.\n" ); return EXIT_FAILURE; } xkb.state = xkb_x11_state_new_from_device ( xkb.keymap, xcb->connection, xkb.device_id ); if ( xkb.state == NULL ) { fprintf ( stderr, "Failed to get state object for current keyboard device.\n" ); return EXIT_FAILURE; } xkb.compose.table = xkb_compose_table_new_from_locale ( xkb.context, setlocale ( LC_CTYPE, NULL ), 0 ); if ( xkb.compose.table != NULL ) { xkb.compose.state = xkb_compose_state_new ( xkb.compose.table, 0 ); } else { fprintf ( stderr, "Failed to get keyboard compose table. Trying to limp on.\n" ); } if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); exit ( EXIT_FAILURE ); } x11_setup ( &xkb ); if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); exit ( EXIT_FAILURE ); } const xcb_query_extension_reply_t *er = xcb_get_extension_data ( xcb->connection, &xcb_xinerama_id ); if ( er ) { if ( er->present ) { xcb_xinerama_is_active_cookie_t is_active_req = xcb_xinerama_is_active ( xcb->connection ); xcb_xinerama_is_active_reply_t *is_active = xcb_xinerama_is_active_reply ( xcb->connection, is_active_req, NULL ); xcb->has_xinerama = is_active->state; free ( is_active ); } } main_loop = g_main_loop_new ( NULL, FALSE ); TICK_N ( "Setup mainloop" ); // startup not. xcb->sndisplay = sn_xcb_display_new ( xcb->connection, error_trap_push, error_trap_pop ); if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); exit ( EXIT_FAILURE ); } if ( xcb->sndisplay != NULL ) { xcb->sncontext = sn_launchee_context_new_from_environment ( xcb->sndisplay, xcb->screen_nbr ); } if ( xcb_connection_has_error ( xcb->connection ) ) { fprintf ( stderr, "Connection has error\n" ); exit ( EXIT_FAILURE ); } TICK_N ( "Startup Notification" ); // Initialize Xresources subsystem. config_parse_xresource_init (); TICK_N ( "Initialize Xresources system" ); // Setup keybinding setup_abe (); TICK_N ( "Setup abe" ); if ( find_arg ( "-no-config" ) < 0 ) { load_configuration ( ); } if ( !dmenu_mode ) { // setup_modi setup_modi (); } if ( find_arg ( "-no-config" ) < 0 ) { // Reload for dynamic part. load_configuration_dynamic ( ); } // Dump. // catch help request if ( find_arg ( "-h" ) >= 0 || find_arg ( "-help" ) >= 0 || find_arg ( "--help" ) >= 0 ) { help ( argc, argv ); exit ( EXIT_SUCCESS ); } if ( find_arg ( "-dump-xresources" ) >= 0 ) { config_parse_xresource_dump (); exit ( EXIT_SUCCESS ); } if ( find_arg ( "-dump-xresources-theme" ) >= 0 ) { config_parse_xresources_theme_dump (); exit ( EXIT_SUCCESS ); } main_loop_source = g_water_xcb_source_new_for_connection ( NULL, xcb->connection, main_loop_x11_event_handler, NULL, NULL ); TICK_N ( "X11 Setup " ); rofi_view_workers_initialize (); // Setup signal handling sources. // SIGINT g_unix_signal_add ( SIGINT, main_loop_signal_handler_int, NULL ); g_idle_add ( startup, NULL ); // Start mainloop. g_main_loop_run ( main_loop ); return return_code; }
static EGLBoolean dri2_x11_connect(struct dri2_egl_display *dri2_dpy) { xcb_xfixes_query_version_reply_t *xfixes_query; xcb_xfixes_query_version_cookie_t xfixes_query_cookie; xcb_dri2_query_version_reply_t *dri2_query; xcb_dri2_query_version_cookie_t dri2_query_cookie; xcb_dri2_connect_reply_t *connect; xcb_dri2_connect_cookie_t connect_cookie; xcb_generic_error_t *error; xcb_screen_iterator_t s; xcb_screen_t *screen; char *driver_name, *loader_driver_name, *device_name; const xcb_query_extension_reply_t *extension; xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_xfixes_id); xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri2_id); extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_xfixes_id); if (!(extension && extension->present)) return EGL_FALSE; extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_dri2_id); if (!(extension && extension->present)) return EGL_FALSE; xfixes_query_cookie = xcb_xfixes_query_version(dri2_dpy->conn, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION); dri2_query_cookie = xcb_dri2_query_version (dri2_dpy->conn, XCB_DRI2_MAJOR_VERSION, XCB_DRI2_MINOR_VERSION); s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); screen = get_xcb_screen(s, dri2_dpy->screen); if (!screen) { _eglLog(_EGL_WARNING, "DRI2: failed to get xcb screen"); return EGL_FALSE; } connect_cookie = xcb_dri2_connect_unchecked(dri2_dpy->conn, screen->root, XCB_DRI2_DRIVER_TYPE_DRI); xfixes_query = xcb_xfixes_query_version_reply (dri2_dpy->conn, xfixes_query_cookie, &error); if (xfixes_query == NULL || error != NULL || xfixes_query->major_version < 2) { _eglLog(_EGL_WARNING, "DRI2: failed to query xfixes version"); free(error); return EGL_FALSE; } free(xfixes_query); dri2_query = xcb_dri2_query_version_reply (dri2_dpy->conn, dri2_query_cookie, &error); if (dri2_query == NULL || error != NULL) { _eglLog(_EGL_WARNING, "DRI2: failed to query version"); free(error); return EGL_FALSE; } dri2_dpy->dri2_major = dri2_query->major_version; dri2_dpy->dri2_minor = dri2_query->minor_version; free(dri2_query); connect = xcb_dri2_connect_reply (dri2_dpy->conn, connect_cookie, NULL); if (connect == NULL || connect->driver_name_length + connect->device_name_length == 0) { _eglLog(_EGL_WARNING, "DRI2: failed to authenticate"); return EGL_FALSE; } device_name = xcb_dri2_connect_device_name (connect); dri2_dpy->device_name = strndup(device_name, xcb_dri2_connect_device_name_length(connect)); dri2_dpy->fd = loader_open_device(dri2_dpy->device_name); if (dri2_dpy->fd == -1) { _eglLog(_EGL_WARNING, "DRI2: could not open %s (%s)", dri2_dpy->device_name, strerror(errno)); free(dri2_dpy->device_name); free(connect); return EGL_FALSE; } if (!dri2_x11_local_authenticate(dri2_dpy)) { close(dri2_dpy->fd); free(dri2_dpy->device_name); free(connect); return EGL_FALSE; } driver_name = xcb_dri2_connect_driver_name (connect); /* If Mesa knows about the appropriate driver for this fd, then trust it. * Otherwise, default to the server's value. */ loader_driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0); if (loader_driver_name) { dri2_dpy->driver_name = loader_driver_name; } else { dri2_dpy->driver_name = strndup(driver_name, xcb_dri2_connect_driver_name_length(connect)); } if (dri2_dpy->device_name == NULL || dri2_dpy->driver_name == NULL) { close(dri2_dpy->fd); free(dri2_dpy->device_name); free(dri2_dpy->driver_name); free(connect); return EGL_FALSE; } free(connect); return EGL_TRUE; }