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; }
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_init(void) { LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_XINPUT xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_input_id); #endif }
void _ecore_xcb_screensaver_init(void) { LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_SCREENSAVER xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_screensaver_id); #endif }
void _ecore_xcb_gesture_init(void) { LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_XGESTURE xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_gesture_id); #endif }
void _ecore_xcb_render_init(void) { LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_RENDER xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_render_id); #endif }
void _ecore_xcb_composite_init(void) { LOGFN(__FILE__, __LINE__, __FUNCTION__); #ifdef ECORE_XCB_COMPOSITE xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_composite_id); #endif }
bool QXcbConnection::hasSupportForDri2() const { if (!m_dri2_support_probed) { xcb_generic_error_t *error = 0; xcb_prefetch_extension_data (m_connection, &xcb_xfixes_id); xcb_prefetch_extension_data (m_connection, &xcb_dri2_id); xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION); xcb_dri2_query_version_cookie_t dri2_query_cookie = xcb_dri2_query_version (m_connection, XCB_DRI2_MAJOR_VERSION, XCB_DRI2_MINOR_VERSION); xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection, xfixes_query_cookie, &error); if (!xfixes_query || error || xfixes_query->major_version < 2) { delete error; delete xfixes_query; return false; } delete xfixes_query; xcb_dri2_query_version_reply_t *dri2_query = xcb_dri2_query_version_reply (m_connection, dri2_query_cookie, &error); if (!dri2_query || error) { delete error; delete dri2_query; return false; } QXcbConnection *that = const_cast<QXcbConnection *>(this); that->m_dri2_major = dri2_query->major_version; that->m_dri2_minor = dri2_query->minor_version; that->m_has_support_for_dri2 = true; that->m_dri2_support_probed = true; } return m_has_support_for_dri2; }
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; }
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; }
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; }
/** Hello, this is main. * \param argc Who knows. * \param argv Who knows. * \return EXIT_SUCCESS I hope. */ int main(int argc, char **argv) { char *confpath = NULL; int xfd, i, screen_nbr, opt, colors_nbr; xcolor_init_request_t colors_reqs[2]; ssize_t cmdlen = 1; xdgHandle xdg; xcb_generic_event_t *event; static struct option long_options[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'v' }, { "config", 1, NULL, 'c' }, { "check", 0, NULL, 'k' }, { NULL, 0, NULL, 0 } }; /* event loop watchers */ ev_io xio = { .fd = -1 }; ev_check xcheck; ev_prepare a_refresh; ev_signal sigint; ev_signal sigterm; ev_signal sighup; /* clear the globalconf structure */ p_clear(&globalconf, 1); globalconf.keygrabber = LUA_REFNIL; globalconf.mousegrabber = LUA_REFNIL; buffer_init(&globalconf.startup_errors); /* save argv */ for(i = 0; i < argc; i++) cmdlen += a_strlen(argv[i]) + 1; globalconf.argv = p_new(char, cmdlen); a_strcpy(globalconf.argv, cmdlen, argv[0]); for(i = 1; i < argc; i++) { a_strcat(globalconf.argv, cmdlen, " "); a_strcat(globalconf.argv, cmdlen, argv[i]); } /* Text won't be printed correctly otherwise */ setlocale(LC_CTYPE, ""); /* Get XDG basedir data */ xdgInitHandle(&xdg); /* init lua */ luaA_init(&xdg); /* check args */ while((opt = getopt_long(argc, argv, "vhkc:", long_options, NULL)) != -1) switch(opt) { case 'v': eprint_version(); break; case 'h': exit_help(EXIT_SUCCESS); break; case 'k': if(!luaA_parserc(&xdg, confpath, false)) { fprintf(stderr, "✘ Configuration file syntax error.\n"); return EXIT_FAILURE; } else { fprintf(stderr, "✔ Configuration file syntax OK.\n"); return EXIT_SUCCESS; } case 'c': if(a_strlen(optarg)) confpath = a_strdup(optarg); else fatal("-c option requires a file name"); break; } globalconf.loop = ev_default_loop(0); ev_timer_init(&globalconf.timer, &luaA_on_timer, 0., 0.); /* register function for signals */ ev_signal_init(&sigint, exit_on_signal, SIGINT); ev_signal_init(&sigterm, exit_on_signal, SIGTERM); ev_signal_init(&sighup, restart_on_signal, SIGHUP); ev_signal_start(globalconf.loop, &sigint); ev_signal_start(globalconf.loop, &sigterm); ev_signal_start(globalconf.loop, &sighup); ev_unref(globalconf.loop); ev_unref(globalconf.loop); ev_unref(globalconf.loop); struct sigaction sa = { .sa_handler = signal_fatal, .sa_flags = 0 }; sigemptyset(&sa.sa_mask); sigaction(SIGSEGV, &sa, 0); /* XLib sucks */ XkbIgnoreExtension(True); /* X stuff */ globalconf.display = XOpenDisplay(NULL); if (globalconf.display == NULL) fatal("cannot open display"); globalconf.default_screen = XDefaultScreen(globalconf.display); globalconf.connection = XGetXCBConnection(globalconf.display); /* Double checking then everything is OK. */ if(xcb_connection_has_error(globalconf.connection)) fatal("cannot open display"); /* Prefetch all the extensions we might need */ xcb_prefetch_extension_data(globalconf.connection, &xcb_big_requests_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_test_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_randr_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_shape_id); /* initialize dbus */ a_dbus_init(); /* Get the file descriptor corresponding to the X connection */ xfd = xcb_get_file_descriptor(globalconf.connection); ev_io_init(&xio, &a_xcb_io_cb, xfd, EV_READ); ev_io_start(globalconf.loop, &xio); ev_check_init(&xcheck, &a_xcb_check_cb); ev_check_start(globalconf.loop, &xcheck); ev_unref(globalconf.loop); ev_prepare_init(&a_refresh, &a_refresh_cb); ev_prepare_start(globalconf.loop, &a_refresh); ev_unref(globalconf.loop); /* Grab server */ xcb_grab_server(globalconf.connection); /* Make sure there are no pending events. Since we didn't really do anything * at all yet, we will just discard all events which we received so far. * The above GrabServer should make sure no new events are generated. */ xcb_aux_sync(globalconf.connection); while ((event = xcb_poll_for_event(globalconf.connection)) != NULL) { /* Make sure errors are printed */ uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(event); if(response_type == 0) event_handle(event); p_delete(&event); } for(screen_nbr = 0; screen_nbr < xcb_setup_roots_length(xcb_get_setup(globalconf.connection)); screen_nbr++) { const uint32_t select_input_val = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT; /* This causes an error if some other window manager is running */ xcb_change_window_attributes(globalconf.connection, xutil_screen_get(globalconf.connection, screen_nbr)->root, XCB_CW_EVENT_MASK, &select_input_val); } /* Need to xcb_flush to validate error handler */ xcb_aux_sync(globalconf.connection); /* Process all errors in the queue if any. There can be no events yet, so if * this function returns something, it must be an error. */ if (xcb_poll_for_event(globalconf.connection) != NULL) fatal("another window manager is already running"); /* Prefetch the maximum request length */ xcb_prefetch_maximum_request_length(globalconf.connection); /* check for xtest extension */ const xcb_query_extension_reply_t *xtest_query; xtest_query = xcb_get_extension_data(globalconf.connection, &xcb_test_id); globalconf.have_xtest = xtest_query->present; /* Allocate the key symbols */ globalconf.keysyms = xcb_key_symbols_alloc(globalconf.connection); xcb_get_modifier_mapping_cookie_t xmapping_cookie = xcb_get_modifier_mapping_unchecked(globalconf.connection); /* init atom cache */ atoms_init(globalconf.connection); /* init screens information */ screen_scan(); /* init default font and colors */ colors_reqs[0] = xcolor_init_unchecked(&globalconf.colors.fg, "black", sizeof("black") - 1); colors_reqs[1] = xcolor_init_unchecked(&globalconf.colors.bg, "white", sizeof("white") - 1); globalconf.font = draw_font_new("sans 8"); for(colors_nbr = 0; colors_nbr < 2; colors_nbr++) xcolor_init_reply(colors_reqs[colors_nbr]); xutil_lock_mask_get(globalconf.connection, xmapping_cookie, globalconf.keysyms, &globalconf.numlockmask, &globalconf.shiftlockmask, &globalconf.capslockmask, &globalconf.modeswitchmask); /* Get the window tree associated to this screen */ const int screen_max = xcb_setup_roots_length(xcb_get_setup(globalconf.connection)); xcb_query_tree_cookie_t tree_c[screen_max]; /* do this only for real screen */ for(screen_nbr = 0; screen_nbr < screen_max; screen_nbr++) { /* select for events */ const uint32_t change_win_vals[] = { XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_FOCUS_CHANGE }; tree_c[screen_nbr] = xcb_query_tree_unchecked(globalconf.connection, xutil_screen_get(globalconf.connection, screen_nbr)->root); xcb_change_window_attributes(globalconf.connection, xutil_screen_get(globalconf.connection, screen_nbr)->root, XCB_CW_EVENT_MASK, change_win_vals); ewmh_init(screen_nbr); systray_init(screen_nbr); } /* init spawn (sn) */ spawn_init(); /* we will receive events, stop grabbing server */ xcb_ungrab_server(globalconf.connection); /* Parse and run configuration file */ if (!luaA_parserc(&xdg, confpath, true)) fatal("couldn't find any rc file"); scan(tree_c); xcb_flush(globalconf.connection); /* main event loop */ ev_loop(globalconf.loop, 0); /* cleanup event loop */ ev_ref(globalconf.loop); ev_check_stop(globalconf.loop, &xcheck); ev_ref(globalconf.loop); ev_prepare_stop(globalconf.loop, &a_refresh); ev_ref(globalconf.loop); ev_io_stop(globalconf.loop, &xio); awesome_atexit(false); return EXIT_SUCCESS; }
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; xcb_xfixes_query_version_cookie_t xfixes_cookie; xcb_xfixes_query_version_reply_t *xfixes_reply; xcb_generic_error_t *error; 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); xcb_prefetch_extension_data (scrn->conn, &xcb_xfixes_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; extension = xcb_get_extension_data(scrn->conn, &xcb_xfixes_id); if (!(extension && extension->present)) goto free_screen; xfixes_cookie = xcb_xfixes_query_version(scrn->conn, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION); xfixes_reply = xcb_xfixes_query_version_reply(scrn->conn, xfixes_cookie, &error); if (!xfixes_reply || error || xfixes_reply->major_version < 2) { free(error); free(xfixes_reply); goto free_screen; } free(xfixes_reply); 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, &scrn->is_different_gpu); 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; scrn->base.xcb_screen = dri3_get_screen_for_root(scrn->conn, geom_reply->root); if (!scrn->base.xcb_screen) { free(geom_reply); goto close_fd; } /* TODO support depth other than 24 or 30 */ if (geom_reply->depth != 24 && geom_reply->depth != 30) { free(geom_reply); goto close_fd; } scrn->base.color_depth = geom_reply->depth; 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->pipe = scrn->base.pscreen->context_create(scrn->base.pscreen, NULL, 0); if (!scrn->pipe) goto no_context; 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; scrn->base.set_back_texture_from_output = vl_dri3_screen_set_back_texture_from_output; scrn->next_back = 1; return &scrn->base; no_context: scrn->base.pscreen->destroy(scrn->base.pscreen); 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; }
struct vl_screen * vl_dri2_screen_create(Display *display, int screen) { struct vl_dri_screen *scrn; const xcb_query_extension_reply_t *extension; xcb_dri2_query_version_cookie_t dri2_query_cookie; xcb_dri2_query_version_reply_t *dri2_query = NULL; xcb_dri2_connect_cookie_t connect_cookie; xcb_dri2_connect_reply_t *connect = NULL; xcb_dri2_authenticate_cookie_t authenticate_cookie; xcb_dri2_authenticate_reply_t *authenticate = NULL; xcb_screen_iterator_t s; xcb_generic_error_t *error = NULL; char *device_name; int fd, device_name_length; unsigned driverType; drm_magic_t magic; assert(display); scrn = CALLOC_STRUCT(vl_dri_screen); if (!scrn) return NULL; scrn->conn = XGetXCBConnection(display); if (!scrn->conn) goto free_screen; xcb_prefetch_extension_data(scrn->conn, &xcb_dri2_id); extension = xcb_get_extension_data(scrn->conn, &xcb_dri2_id); if (!(extension && extension->present)) goto free_screen; dri2_query_cookie = xcb_dri2_query_version (scrn->conn, XCB_DRI2_MAJOR_VERSION, XCB_DRI2_MINOR_VERSION); dri2_query = xcb_dri2_query_version_reply (scrn->conn, dri2_query_cookie, &error); if (dri2_query == NULL || error != NULL || dri2_query->minor_version < 2) goto free_query; s = xcb_setup_roots_iterator(xcb_get_setup(scrn->conn)); scrn->base.xcb_screen = get_xcb_screen(s, screen); if (!scrn->base.xcb_screen) goto free_query; driverType = XCB_DRI2_DRIVER_TYPE_DRI; { char *prime = getenv("DRI_PRIME"); if (prime) { unsigned primeid; errno = 0; primeid = strtoul(prime, NULL, 0); if (errno == 0) driverType |= ((primeid & DRI2DriverPrimeMask) << DRI2DriverPrimeShift); } } connect_cookie = xcb_dri2_connect_unchecked( scrn->conn, ((xcb_screen_t *)(scrn->base.xcb_screen))->root, driverType); connect = xcb_dri2_connect_reply(scrn->conn, connect_cookie, NULL); if (connect == NULL || connect->driver_name_length + connect->device_name_length == 0) goto free_connect; device_name_length = xcb_dri2_connect_device_name_length(connect); device_name = CALLOC(1, device_name_length + 1); if (!device_name) goto free_connect; memcpy(device_name, xcb_dri2_connect_device_name(connect), device_name_length); fd = loader_open_device(device_name); free(device_name); if (fd < 0) goto free_connect; if (drmGetMagic(fd, &magic)) goto close_fd; authenticate_cookie = xcb_dri2_authenticate_unchecked( scrn->conn, ((xcb_screen_t *)(scrn->base.xcb_screen))->root, magic); authenticate = xcb_dri2_authenticate_reply(scrn->conn, authenticate_cookie, NULL); if (authenticate == NULL || !authenticate->authenticated) goto free_authenticate; 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_dri2_screen_destroy; scrn->base.texture_from_drawable = vl_dri2_screen_texture_from_drawable; scrn->base.get_dirty_area = vl_dri2_screen_get_dirty_area; scrn->base.get_timestamp = vl_dri2_screen_get_timestamp; scrn->base.set_next_timestamp = vl_dri2_screen_set_next_timestamp; scrn->base.get_private = vl_dri2_screen_get_private; scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer; vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]); vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]); /* The pipe loader duplicates the fd */ close(fd); free(authenticate); free(connect); free(dri2_query); free(error); return &scrn->base; release_pipe: if (scrn->base.dev) pipe_loader_release(&scrn->base.dev, 1); free_authenticate: free(authenticate); close_fd: close(fd); free_connect: free(connect); free_query: free(dri2_query); free(error); free_screen: FREE(scrn); return NULL; }
virtual void prefetch_extension_data(xcb_extension_t * ext) const { xcb_prefetch_extension_data(m_c.get(), ext); }
/** Hello, this is main. * \param argc Who knows. * \param argv Who knows. * \return EXIT_SUCCESS I hope. */ int main(int argc, char **argv) { char *confpath = NULL; int xfd, i, opt; ssize_t cmdlen = 1; xdgHandle xdg; bool no_argb = false; xcb_generic_event_t *event; xcb_query_tree_cookie_t tree_c; static struct option long_options[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'v' }, { "config", 1, NULL, 'c' }, { "check", 0, NULL, 'k' }, { "no-argb", 0, NULL, 'a' }, { NULL, 0, NULL, 0 } }; /* event loop watchers */ ev_io xio = { .fd = -1 }; ev_check xcheck; ev_prepare a_refresh; ev_signal sigint; ev_signal sigterm; ev_signal sighup; /* clear the globalconf structure */ p_clear(&globalconf, 1); globalconf.keygrabber = LUA_REFNIL; globalconf.mousegrabber = LUA_REFNIL; buffer_init(&globalconf.startup_errors); /* save argv */ for(i = 0; i < argc; i++) cmdlen += a_strlen(argv[i]) + 1; awesome_argv = p_new(char, cmdlen); a_strcpy(awesome_argv, cmdlen, argv[0]); for(i = 1; i < argc; i++) { a_strcat(awesome_argv, cmdlen, " "); a_strcat(awesome_argv, cmdlen, argv[i]); } /* Text won't be printed correctly otherwise */ setlocale(LC_CTYPE, ""); /* Get XDG basedir data */ xdgInitHandle(&xdg); /* init lua */ luaA_init(&xdg); /* check args */ while((opt = getopt_long(argc, argv, "vhkc:a", long_options, NULL)) != -1) switch(opt) { case 'v': eprint_version(); break; case 'h': exit_help(EXIT_SUCCESS); break; case 'k': if(!luaA_parserc(&xdg, confpath, false)) { fprintf(stderr, "✘ Configuration file syntax error.\n"); return EXIT_FAILURE; } else { fprintf(stderr, "✔ Configuration file syntax OK.\n"); return EXIT_SUCCESS; } case 'c': if(a_strlen(optarg)) confpath = a_strdup(optarg); else fatal("-c option requires a file name"); break; case 'a': no_argb = true; break; } globalconf.loop = ev_default_loop(EVFLAG_NOSIGFD); /* register function for signals */ ev_signal_init(&sigint, exit_on_signal, SIGINT); ev_signal_init(&sigterm, exit_on_signal, SIGTERM); ev_signal_init(&sighup, restart_on_signal, SIGHUP); ev_signal_start(globalconf.loop, &sigint); ev_signal_start(globalconf.loop, &sigterm); ev_signal_start(globalconf.loop, &sighup); ev_unref(globalconf.loop); ev_unref(globalconf.loop); ev_unref(globalconf.loop); struct sigaction sa = { .sa_handler = signal_fatal, .sa_flags = 0 }; sigemptyset(&sa.sa_mask); sigaction(SIGSEGV, &sa, 0); /* X stuff */ globalconf.connection = xcb_connect(NULL, &globalconf.default_screen); if(xcb_connection_has_error(globalconf.connection)) fatal("cannot open display"); globalconf.screen = xcb_aux_get_screen(globalconf.connection, globalconf.default_screen); /* FIXME The following two assignments were swapped on purpose */ if(!no_argb) globalconf.visual = a_default_visual(globalconf.screen); if(!globalconf.visual) globalconf.visual = a_argb_visual(globalconf.screen); globalconf.default_depth = a_visual_depth(globalconf.screen, globalconf.visual->visual_id); globalconf.default_cmap = globalconf.screen->default_colormap; if(globalconf.default_depth != globalconf.screen->root_depth) { // We need our own color map if we aren't using the default depth globalconf.default_cmap = xcb_generate_id(globalconf.connection); xcb_create_colormap(globalconf.connection, XCB_COLORMAP_ALLOC_NONE, globalconf.default_cmap, globalconf.screen->root, globalconf.visual->visual_id); } /* Prefetch all the extensions we might need */ xcb_prefetch_extension_data(globalconf.connection, &xcb_big_requests_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_test_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_randr_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_xinerama_id); /* initialize dbus */ a_dbus_init(); /* Get the file descriptor corresponding to the X connection */ xfd = xcb_get_file_descriptor(globalconf.connection); ev_io_init(&xio, &a_xcb_io_cb, xfd, EV_READ); ev_io_start(globalconf.loop, &xio); ev_check_init(&xcheck, &a_xcb_check_cb); ev_check_start(globalconf.loop, &xcheck); ev_unref(globalconf.loop); ev_prepare_init(&a_refresh, &a_refresh_cb); ev_prepare_start(globalconf.loop, &a_refresh); ev_unref(globalconf.loop); /* Grab server */ xcb_grab_server(globalconf.connection); /* Make sure there are no pending events. Since we didn't really do anything * at all yet, we will just discard all events which we received so far. * The above GrabServer should make sure no new events are generated. */ xcb_aux_sync(globalconf.connection); while ((event = xcb_poll_for_event(globalconf.connection)) != NULL) { /* Make sure errors are printed */ uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(event); if(response_type == 0) event_handle(event); p_delete(&event); } { const uint32_t select_input_val = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT; /* This causes an error if some other window manager is running */ xcb_change_window_attributes(globalconf.connection, globalconf.screen->root, XCB_CW_EVENT_MASK, &select_input_val); } /* Need to xcb_flush to validate error handler */ xcb_aux_sync(globalconf.connection); /* Process all errors in the queue if any. There can be no events yet, so if * this function returns something, it must be an error. */ if (xcb_poll_for_event(globalconf.connection) != NULL) fatal("another window manager is already running"); /* Prefetch the maximum request length */ xcb_prefetch_maximum_request_length(globalconf.connection); /* check for xtest extension */ const xcb_query_extension_reply_t *xtest_query; xtest_query = xcb_get_extension_data(globalconf.connection, &xcb_test_id); globalconf.have_xtest = xtest_query->present; /* Allocate the key symbols */ globalconf.keysyms = xcb_key_symbols_alloc(globalconf.connection); xcb_get_modifier_mapping_cookie_t xmapping_cookie = xcb_get_modifier_mapping_unchecked(globalconf.connection); /* init atom cache */ atoms_init(globalconf.connection); /* init screens information */ screen_scan(); xutil_lock_mask_get(globalconf.connection, xmapping_cookie, globalconf.keysyms, &globalconf.numlockmask, &globalconf.shiftlockmask, &globalconf.capslockmask, &globalconf.modeswitchmask); /* do this only for real screen */ ewmh_init(); systray_init(); /* init spawn (sn) */ spawn_init(); /* The default GC is just a newly created associated with a window with * depth globalconf.default_depth */ xcb_window_t tmp_win = xcb_generate_id(globalconf.connection); globalconf.gc = xcb_generate_id(globalconf.connection); xcb_create_window(globalconf.connection, globalconf.default_depth, tmp_win, globalconf.screen->root, -1, -1, 1, 1, 0, XCB_COPY_FROM_PARENT, globalconf.visual->visual_id, XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP, (const uint32_t []) { globalconf.screen->black_pixel, globalconf.screen->black_pixel, globalconf.default_cmap }); xcb_create_gc(globalconf.connection, globalconf.gc, tmp_win, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, (const uint32_t[]) { globalconf.screen->black_pixel, globalconf.screen->white_pixel }); xcb_destroy_window(globalconf.connection, tmp_win); /* Get the window tree associated to this screen */ tree_c = xcb_query_tree_unchecked(globalconf.connection, globalconf.screen->root); xcb_change_window_attributes(globalconf.connection, globalconf.screen->root, XCB_CW_EVENT_MASK, ROOT_WINDOW_EVENT_MASK); /* we will receive events, stop grabbing server */ xcb_ungrab_server(globalconf.connection); /* Parse and run configuration file */ if (!luaA_parserc(&xdg, confpath, true)) fatal("couldn't find any rc file"); p_delete(&confpath); xdgWipeHandle(&xdg); /* scan existing windows */ scan(tree_c); xcb_flush(globalconf.connection); /* main event loop */ ev_loop(globalconf.loop, 0); /* cleanup event loop */ ev_ref(globalconf.loop); ev_check_stop(globalconf.loop, &xcheck); ev_ref(globalconf.loop); ev_prepare_stop(globalconf.loop, &a_refresh); ev_ref(globalconf.loop); ev_io_stop(globalconf.loop, &xio); awesome_atexit(false); return EXIT_SUCCESS; }
void _ecore_xcb_extensions_init(void) { LOGFN(__FILE__, __LINE__, __FUNCTION__); xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_big_requests_id); xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_shm_id); #ifdef ECORE_XCB_SHAPE _ecore_xcb_shape_init(); #endif #ifdef ECORE_XCB_SCREENSAVER _ecore_xcb_screensaver_init(); #endif #ifdef ECORE_XCB_SYNC _ecore_xcb_sync_init(); #endif #ifdef ECORE_XCB_RANDR _ecore_xcb_randr_init(); #endif #ifdef ECORE_XCB_XFIXES _ecore_xcb_xfixes_init(); #endif #ifdef ECORE_XCB_DAMAGE _ecore_xcb_damage_init(); #endif #ifdef ECORE_XCB_RENDER _ecore_xcb_render_init(); #endif #ifdef ECORE_XCB_COMPOSITE _ecore_xcb_composite_init(); #endif #ifdef ECORE_XCB_DPMS _ecore_xcb_dpms_init(); #endif #ifdef ECORE_XCB_DPMS _ecore_xcb_dpms_init(); #endif #ifdef ECORE_XCB_CURSOR _ecore_xcb_cursor_init(); #endif #ifdef ECORE_XCB_XINERAMA _ecore_xcb_xinerama_init(); #endif #ifdef ECORE_XCB_XINPUT _ecore_xcb_input_init(); #endif #ifdef ECORE_XCB_GESTURE _ecore_xcb_gesture_init(); #endif #ifdef ECORE_XCB_XPRESENT _ecore_xcb_present_init(); #endif /* #ifdef ECORE_XCB_DRI */ /* _ecore_xcb_dri_init(); */ /* #endif */ #ifdef ECORE_XCB_XTEST _ecore_xcb_xtest_init(); #endif xcb_prefetch_maximum_request_length(_ecore_xcb_conn); }
IdlenessWatcher::IdlenessWatcher(QObject* parent): Watcher(parent), mPSettings(), mErrorNotification(tr("LxQt Idleness watcher failed to start")), mDBusWatcher(this), mInhibitorCookie(0), mIsLocked(false) { qDebug() << "Starting idlenesswatcher"; mConn = X11Helper::connection(); xcb_prefetch_extension_data(mConn, &xcb_screensaver_id); xcb_prefetch_extension_data(mConn, &xcb_dpms_id); xcb_screensaver_query_version_cookie_t verCookie = xcb_screensaver_query_version_unchecked(mConn, XCB_SCREENSAVER_MAJOR_VERSION, XCB_SCREENSAVER_MINOR_VERSION); xcb_dpms_get_version_cookie_t dpmsVerCookie = xcb_dpms_get_version_unchecked(mConn, XCB_DPMS_MAJOR_VERSION, XCB_DPMS_MINOR_VERSION); // Note that XCB is asynchronous, so we want to make requests ASAP and get the responses as late as possible. mScreen = screenOfDisplay(mConn, 0); mErrorNotification.setUrgencyHint(LxQt::Notification::UrgencyCritical); mErrorNotification.setIcon("object-unlocked"); mErrorNotification.setTimeout(0); new ScreenSaverAdaptor(this); QDBusConnection sessionBus = QDBusConnection::sessionBus(); if (!sessionBus.registerService("org.freedesktop.ScreenSaver") || !sessionBus.registerObject("/ScreenSaver", this)) { mErrorNotification.setBody(tr("D-Bus interface org.freedesktop.ScreenSaver is already registered")); mErrorNotification.update(); qWarning() << "ERROR: D-Bus interface org.freedesktop.ScreenSaver is already registered"; } mDBusWatcher.setConnection(QDBusConnection::sessionBus()); mDBusWatcher.setWatchMode(QDBusServiceWatcher::WatchForUnregistration); connect(&mTimer, SIGNAL(timeout()), SLOT(idleTimeout())); connect(&mPSettings, SIGNAL(settingsChanged()), SLOT(restartTimer())); connect(&mDBusWatcher, SIGNAL(serviceUnregistered(QString)), SLOT(serviceUnregistered(QString))); connect(&mLockProcess, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(screenUnlocked(int,QProcess::ExitStatus))); connect(&mErrorNotification, SIGNAL(actionActivated(int)), SLOT(notificationAction(int))); // Get XCB responses ... const xcb_query_extension_reply_t* extReply = xcb_get_extension_data(mConn, &xcb_screensaver_id); const xcb_query_extension_reply_t* dpmsExtReply = xcb_get_extension_data(mConn, &xcb_dpms_id); xcb_screensaver_query_version_reply_t* verReply = xcb_screensaver_query_version_reply(mConn, verCookie, NULL); xcb_dpms_get_version_reply_t* dpmsVerReply = xcb_dpms_get_version_reply(mConn, dpmsVerCookie, NULL); if (mScreen && extReply && extReply->present && dpmsExtReply && dpmsExtReply->present && verReply && dpmsVerReply && verReply->server_major_version == XCB_SCREENSAVER_MAJOR_VERSION && verReply->server_minor_version >= XCB_SCREENSAVER_MINOR_VERSION //&& dpmsVerReply->server_major_version == XCB_DPMS_MAJOR_VERSION //&& dpmsVerReply->server_minor_version >= XCB_DPMS_MINOR_VERSION ) { free(verReply); free(dpmsVerReply); } else { mErrorNotification.setBody(tr("The X11 Screensaver extension is not usable")); mErrorNotification.update(); if (verReply) free(verReply); qCritical() << "ERROR: Can't use the X11 Screensaver Extension!"; } mErrorNotification.setActions(QStringList(tr("Configure..."))); qDebug() << "LxQt Screenlocker started."; qDebug() << "timeout:" << getMaxIdleTimeoutMs() << "ms, lock command:" << mLockCommand; restartTimer(); }
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; }
int main(int argc, char **argv) { memset(&globalconf, 0, sizeof(globalconf)); globalconf.connection = xcb_connect(NULL, &globalconf.screen_nbr); if(xcb_connection_has_error(globalconf.connection)) fatal("Cannot open display"); /* Get the root window */ globalconf.screen = xcb_aux_get_screen(globalconf.connection, globalconf.screen_nbr); /* Set up signal handlers and function called on normal exit */ struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_handler = exit_on_signal; sa.sa_flags = 0; sigaction(SIGHUP, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); atexit(exit_cleanup); /** * First round-trip */ /* Send requests for EWMH atoms initialisation */ xcb_intern_atom_cookie_t *ewmh_cookies = atoms_init(); parse_command_line_parameters(argc, argv); /* Prefetch the extensions data */ xcb_prefetch_extension_data(globalconf.connection, &xcb_composite_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_damage_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_xfixes_id); /* Initialise errors handlers */ xcb_event_handlers_init(globalconf.connection, &globalconf.evenths); event_init_start_handlers(); /* Pre-initialisation of the rendering backend */ if(!rendering_load()) { free(ewmh_cookies); fatal("Can't initialise rendering backend"); } /* Get replies for EWMH atoms initialisation */ if(!atoms_init_finalise(ewmh_cookies)) /* No need to free ewmh_cookies in case of error as it's already handles by xcb-ewmh when getting the replies */ fatal("Cannot initialise atoms"); /* First check whether there is already a Compositing Manager (ICCCM) */ xcb_get_selection_owner_cookie_t wm_cm_owner_cookie = xcb_ewmh_get_wm_cm_owner(&globalconf.ewmh, globalconf.screen_nbr); /** * Second round-trip */ /* Initialise extensions based on the cache and perform initialisation of the rendering backend */ display_init_extensions(); if(!(*globalconf.rendering->init)()) return EXIT_FAILURE; /* Check ownership for WM_CM_Sn before actually claiming it (ICCCM) */ xcb_window_t wm_cm_owner_win; if(xcb_ewmh_get_wm_cm_owner_reply(&globalconf.ewmh, wm_cm_owner_cookie, &wm_cm_owner_win, NULL) && wm_cm_owner_win != XCB_NONE) fatal("A compositing manager is already active (window=%jx)", (uintmax_t) wm_cm_owner_win); /* Now send requests to register the CM */ display_register_cm(); /** * Third round-trip */ /* Check extensions version and finish initialisation of the rendering backend */ display_init_extensions_finalise(); if(!(*globalconf.rendering->init_finalise)()) return EXIT_FAILURE; /* All the plugins given in the configuration file */ plugin_load_all(); /* Validate errors and get PropertyNotify needed to acquire _NET_WM_CM_Sn ownership */ xcb_aux_sync(globalconf.connection); xcb_event_poll_for_event_loop(&globalconf.evenths); globalconf.keysyms = xcb_key_symbols_alloc(globalconf.connection); xcb_get_modifier_mapping_cookie_t key_mapping_cookie = xcb_get_modifier_mapping_unchecked(globalconf.connection); /* Finish CM X registration */ if(!display_register_cm_finalise()) fatal("Could not acquire _NET_WM_CM_Sn ownership"); /** * Last initialisation round-trip */ /* Grab the server before performing redirection and get the tree of windows to ensure there won't be anything else at the same time */ xcb_grab_server(globalconf.connection); /* Now redirect windows and add existing windows */ display_init_redirect(); /* Validate errors handlers during redirect */ xcb_aux_sync(globalconf.connection); xcb_event_poll_for_event_loop(&globalconf.evenths); /* Manage existing windows */ display_init_redirect_finalise(); xcb_ungrab_server(globalconf.connection); /* Check the plugin requirements which will disable plugins which don't meet the requirements */ plugin_check_requirements(); /* Get the lock masks reply of the request previously sent */ key_lock_mask_get_reply(key_mapping_cookie); /* Initialise normal errors and events handlers */ event_init_handlers(); xcb_generic_event_t *event; /* Flush existing requests before the loop as DamageNotify events may have been received in the meantime */ xcb_flush(globalconf.connection); globalconf.do_repaint = true; /* Main event and error loop */ do { /* Block until an event is received */ event = xcb_wait_for_event(globalconf.connection); /* Check X connection to avoid SIGSEGV */ if(xcb_connection_has_error(globalconf.connection)) fatal("X connection invalid"); xcb_event_handle(&globalconf.evenths, event); free(event); /* Then process all remaining events in the queue because before painting, all the DamageNotify have to be received */ xcb_event_poll_for_event_loop(&globalconf.evenths); /* Now paint the windows */ if(globalconf.do_repaint) { window_t *windows = NULL; for(plugin_t *plugin = globalconf.plugins; plugin; plugin = plugin->next) if(plugin->enable && plugin->vtable->render_windows && (windows = (*plugin->vtable->render_windows)())) break; if(!windows) windows = globalconf.windows; window_paint_all(windows); xcb_aux_sync(globalconf.connection); } globalconf.do_repaint = false; } while(true); return EXIT_SUCCESS; }
void Extensions::init() { xcb_connection_t *c = connection(); xcb_prefetch_extension_data(c, &xcb_shape_id); xcb_prefetch_extension_data(c, &xcb_randr_id); xcb_prefetch_extension_data(c, &xcb_damage_id); xcb_prefetch_extension_data(c, &xcb_composite_id); xcb_prefetch_extension_data(c, &xcb_xfixes_id); xcb_prefetch_extension_data(c, &xcb_render_id); xcb_prefetch_extension_data(c, &xcb_sync_id); m_shape.name = QByteArray("SHAPE"); m_randr.name = QByteArray("RANDR"); m_damage.name = QByteArray("DAMAGE"); m_composite.name = QByteArray("Composite"); m_fixes.name = QByteArray("XFIXES"); m_render.name = QByteArray("RENDER"); m_sync.name = QByteArray("SYNC"); extensionQueryReply(xcb_get_extension_data(c, &xcb_shape_id), &m_shape); extensionQueryReply(xcb_get_extension_data(c, &xcb_randr_id), &m_randr); extensionQueryReply(xcb_get_extension_data(c, &xcb_damage_id), &m_damage); extensionQueryReply(xcb_get_extension_data(c, &xcb_composite_id), &m_composite); extensionQueryReply(xcb_get_extension_data(c, &xcb_xfixes_id), &m_fixes); extensionQueryReply(xcb_get_extension_data(c, &xcb_render_id), &m_render); extensionQueryReply(xcb_get_extension_data(c, &xcb_sync_id), &m_sync); // extension specific queries xcb_shape_query_version_cookie_t shapeVersion; xcb_randr_query_version_cookie_t randrVersion; xcb_damage_query_version_cookie_t damageVersion; xcb_composite_query_version_cookie_t compositeVersion; xcb_xfixes_query_version_cookie_t xfixesVersion; xcb_render_query_version_cookie_t renderVersion; xcb_sync_initialize_cookie_t syncVersion; if (m_shape.present) { shapeVersion = xcb_shape_query_version_unchecked(c); } if (m_randr.present) { randrVersion = xcb_randr_query_version_unchecked(c, RANDR_MAX_MAJOR, RANDR_MAX_MINOR); } if (m_damage.present) { damageVersion = xcb_damage_query_version_unchecked(c, DAMAGE_MAX_MAJOR, DAMAGE_MIN_MAJOR); } if (m_composite.present) { compositeVersion = xcb_composite_query_version_unchecked(c, COMPOSITE_MAX_MAJOR, COMPOSITE_MAX_MINOR); } if (m_fixes.present) { xfixesVersion = xcb_xfixes_query_version_unchecked(c, XFIXES_MAX_MAJOR, XFIXES_MAX_MINOR); } if (m_render.present) { renderVersion = xcb_render_query_version_unchecked(c, RENDER_MAX_MAJOR, RENDER_MAX_MINOR); } if (m_sync.present) { syncVersion = xcb_sync_initialize(c, SYNC_MAX_MAJOR, SYNC_MAX_MINOR); } // handle replies if (m_shape.present) { initVersion<xcb_shape_query_version_reply_t>(shapeVersion, &xcb_shape_query_version_reply, &m_shape); } if (m_randr.present) { initVersion<xcb_randr_query_version_reply_t>(randrVersion, &xcb_randr_query_version_reply, &m_randr); } if (m_damage.present) { initVersion<xcb_damage_query_version_reply_t>(damageVersion, &xcb_damage_query_version_reply, &m_damage); } if (m_composite.present) { initVersion<xcb_composite_query_version_reply_t>(compositeVersion, &xcb_composite_query_version_reply, &m_composite); } if (m_fixes.present) { initVersion<xcb_xfixes_query_version_reply_t>(xfixesVersion, &xcb_xfixes_query_version_reply, &m_fixes); } if (m_render.present) { initVersion<xcb_render_query_version_reply_t>(renderVersion, &xcb_render_query_version_reply, &m_render); } if (m_sync.present) { initVersion<xcb_sync_initialize_reply_t>(syncVersion, &xcb_sync_initialize_reply, &m_sync); } kDebug(1212) << "Extensions: shape: 0x" << QString::number(m_shape.version, 16) << " composite: 0x" << QString::number(m_composite.version, 16) << " render: 0x" << QString::number(m_render.version, 16) << " fixes: 0x" << QString::number(m_fixes.version, 16) << " randr: 0x" << QString::number(m_randr.version, 16) << " sync: 0x" << QString::number(m_sync.version, 16) << " damage: 0x " << QString::number(m_damage.version, 16) << endl; }