/** * gst_gl_display_x11_new: * @name: (allow-none): a display name * * Create a new #GstGLDisplayX11 from the x11 display name. See XOpenDisplay() * for details on what is a valid name. * * Returns: (transfer full): a new #GstGLDisplayX11 or %NULL */ GstGLDisplayX11 * gst_gl_display_x11_new (const gchar * name) { GstGLDisplayX11 *ret; GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay"); ret = g_object_new (GST_TYPE_GL_DISPLAY_X11, NULL); ret->name = g_strdup (name); ret->display = XOpenDisplay (ret->name); if (!ret->display) { GST_ERROR ("Failed to open X11 display connection with name, \'%s\'", name); gst_object_unref (ret); return NULL; } ret->xcb_connection = XGetXCBConnection (ret->display); if (!ret->xcb_connection) { GST_ERROR ("Failed to open retieve XCB connection from X11 Display"); gst_object_unref (ret); return NULL; } XSetEventQueueOwner (ret->display, XCBOwnsEventQueue); GST_GL_DISPLAY (ret)->event_source = xcb_event_source_new (ret); g_source_attach (GST_GL_DISPLAY (ret)->event_source, GST_GL_DISPLAY (ret)->main_context); return ret; }
void initScreen() { /* Open Xlib Display */ display = XOpenDisplay(0); if (!display) printf("Can't open display"); default_screen = ((_XPrivDisplay)display)->default_screen; /* Get the XCB connection from the display */ connection = XGetXCBConnection(display); if (!connection) printf("Can't get xcb connection from display"); /* Acquire event queue ownership */ XSetEventQueueOwner(display, XCBOwnsEventQueue); /* Find XCB screen */ screen = 0; xcb_screen_iterator_t screen_iter = xcb_setup_roots_iterator(xcb_get_setup(connection)); for (int screen_num = default_screen; screen_iter.rem && screen_num > 0; --screen_num, xcb_screen_next(&screen_iter)); screen = screen_iter.data; /* width = screen->width_in_pixels; height = screen->height_in_pixels; */ width = 250; height = 260; }
struct rutabaga * window_impl_rtb_alloc(void) { struct xcb_rutabaga *self; Display *dpy; if (!(self = calloc(1, sizeof(*self)))) goto err_malloc; if (!(self->dpy = dpy = XOpenDisplay(NULL))) { ERR("can't open X display\n"); goto err_dpy; } if (!(self->xcb_conn = XGetXCBConnection(dpy))) { ERR("can't get XCB connection for display\n"); goto err_get_conn; } if (xrtb_keyboard_init(self)) { ERR("can't initialize keyboard\n"); goto err_keyboard_init; } XSetEventQueueOwner(dpy, XCBOwnsEventQueue); self->xkb_event = get_xkb_event_id(self->xcb_conn); self->xkb_core_kbd_id = get_core_kbd_id(self->xcb_conn); if (self->xkb_event >= 0 && self->xkb_core_kbd_id >= 0 && !receive_xkb_events(self->xcb_conn)) self->xkb_supported = 1; self->running_in_xwayland = intern_atom(self->xcb_conn, "WL_SURFACE_ID", 1) != XCB_NONE; #define INTERN_ATOM(atom, name) \ self->atoms.atom = intern_atom(self->xcb_conn, name, 0); INTERN_ATOM(wm_protocols, "WM_PROTOCOLS"); INTERN_ATOM(wm_delete_window, "WM_DELETE_WINDOW"); #undef INTERN_ATOM self->empty_cursor = create_empty_cursor(self); return (struct rutabaga *) self; err_keyboard_init: err_get_conn: XCloseDisplay(self->dpy); err_dpy: free(self); err_malloc: return NULL; }
xcb_connection_t * ephyr_glamor_connect(void) { dpy = XOpenDisplay(NULL); if (!dpy) return NULL; XSetEventQueueOwner(dpy, XCBOwnsEventQueue); return XGetXCBConnection(dpy); }
QXcbConnection::QXcbConnection(const char *displayName) : m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) #ifdef XCB_USE_DRI2 , m_dri2_major(0) , m_dri2_minor(0) , m_dri2_support_probed(false) , m_has_support_for_dri2(false) #endif { int primaryScreen = 0; #ifdef XCB_USE_XLIB Display *dpy = XOpenDisplay(m_displayName.constData()); primaryScreen = DefaultScreen(dpy); m_connection = XGetXCBConnection(dpy); XSetEventQueueOwner(dpy, XCBOwnsEventQueue); m_xlib_display = dpy; #ifdef XCB_USE_EGL EGLDisplay eglDisplay = eglGetDisplay(dpy); m_egl_display = eglDisplay; EGLint major, minor; eglBindAPI(EGL_OPENGL_ES_API); m_has_egl = eglInitialize(eglDisplay,&major,&minor); #endif //XCB_USE_EGL #else m_connection = xcb_connect(m_displayName.constData(), &primaryScreen); #endif //XCB_USE_XLIB m_setup = xcb_get_setup(xcb_connection()); initializeAllAtoms(); xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup); int screenNumber = 0; while (it.rem) { m_screens << new QXcbScreen(this, it.data, screenNumber++); xcb_screen_next(&it); } m_keyboard = new QXcbKeyboard(this); #ifdef XCB_USE_DRI2 initializeDri2(); #endif QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this); connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents())); QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance(qApp->thread()); connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents())); sync(); }
extern struct gl_platform *gl_platform_create(gs_device_t *device, uint32_t adapter) { /* There's some trickery here... we're mixing libX11, xcb, and GLX For an explanation see here: http://xcb.freedesktop.org/MixingCalls/ Essentially, GLX requires Xlib. Everything else we use xcb. */ struct gl_platform * plat = bmalloc(sizeof(struct gl_platform)); Display * display = open_windowless_display(); if (!display) { goto fail_display_open; } XSetEventQueueOwner(display, XCBOwnsEventQueue); XSetErrorHandler(x_error_handler); /* We assume later that cur_swap is already set. */ device->plat = plat; plat->display = display; if (!gl_context_create(plat)) { blog(LOG_ERROR, "Failed to create context!"); goto fail_context_create; } if (!glXMakeContextCurrent(plat->display, plat->pbuffer, plat->pbuffer, plat->context)) { blog(LOG_ERROR, "Failed to make context current."); goto fail_make_current; } if (!gladLoadGL()) { blog(LOG_ERROR, "Failed to load OpenGL entry functions."); goto fail_load_gl; } blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION)); goto success; fail_make_current: gl_context_destroy(plat); fail_context_create: fail_load_gl: XCloseDisplay(display); fail_display_open: bfree(plat); plat = NULL; success: UNUSED_PARAMETER(adapter); return plat; }
bool AppFrontend::Start() { if(IsRunning()) return false; SetCurrent(); #if CE_FRONTEND_USEXLIB Display *xDisplay = XOpenDisplay(NULL); if(!xDisplay) { error("[Error] AppFrontend::start - Unable to open Xlib Display.\n"); XCloseDisplay(xDisplay); return false; } int xDefaultScreen = DefaultScreen(xDisplay); #if CE_FRONTEND_USEXCB xcb_connection_t *xcbConnection = XGetXCBConnection(xDisplay); if(!xcbConnection) { error("[Error] AppFrontend::start - Unable to get XCB connection from Xlib Display.\n"); XCloseDisplay(xDisplay); return false; } XSetEventQueueOwner(xDisplay, XCBOwnsEventQueue); xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xcbConnection, 0, 16, "WM_DELETE_WINDOW"); xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(xcbConnection, cookie, 0); xcb_atom_t wmDeleteMessage = reply->atom; #else Atom wmDeleteMessage = XInternAtom(xDisplay, "WM_DELETE_WINDOW", False); #endif #endif #if CE_FRONTEND_USEXLIB m_wmDeleteMessage = wmDeleteMessage; m_xDefaultScreen = xDefaultScreen; m_xDisplay = xDisplay; #if CE_FRONTEND_USEXCB m_xcbConnection = xcbConnection; #endif #endif #if CE_FRONTEND_USEWIN m_hInstance = GetModuleHandle(NULL); #endif return App::Start(); }
void ae3d::Window::Create( int width, int height, WindowCreateFlags flags ) { WindowGlobal::display = XOpenDisplay( nullptr ); if (!WindowGlobal::display) { std::cerr << "Can't open display" << std::endl; return; } int default_screen = DefaultScreen( WindowGlobal::display ); WindowGlobal::connection = XGetXCBConnection( WindowGlobal::display ); LoadAtoms(); if (!WindowGlobal::connection) { XCloseDisplay( WindowGlobal::display ); std::cerr << "Can't get xcb connection from display" << std::endl; return; } XSetEventQueueOwner( WindowGlobal::display, XCBOwnsEventQueue ); xcb_screen_t* screen = nullptr; xcb_screen_iterator_t screen_iter = xcb_setup_roots_iterator( xcb_get_setup( WindowGlobal::connection ) ); for (int screen_num = default_screen; screen_iter.rem && screen_num > 0; --screen_num, xcb_screen_next( &screen_iter )); screen = screen_iter.data; WindowGlobal::key_symbols = xcb_key_symbols_alloc( WindowGlobal::connection ); if (CreateWindowAndContext( WindowGlobal::display, WindowGlobal::connection, default_screen, screen, width, height, flags ) == -1) { return; } GfxDevice::Init( WindowGlobal::windowWidth, WindowGlobal::windowHeight ); const char *title = "Aether3D Game Engine"; xcb_change_property(WindowGlobal::connection, XCB_PROP_MODE_REPLACE, WindowGlobal::window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, strlen (title), title ); WindowGlobal::isOpen = true; }
krad_x11_t *krad_x11_create () { krad_x11_t *krad_x11; int s; if ((krad_x11 = calloc (1, sizeof (krad_x11_t))) == NULL) { failfast ("krad_x11 mem alloc fail"); } if (KRAD_X11_XCB_ONLY) { krad_x11->connection = xcb_connect (NULL, &krad_x11->screen_number); } else { krad_x11->display = XOpenDisplay (0); if (!krad_x11->display) { failfast ("Can't open display"); } krad_x11->connection = XGetXCBConnection (krad_x11->display); if (!krad_x11->connection) { XCloseDisplay (krad_x11->display); failfast ("Can't get xcb connection from display\n"); } XSetEventQueueOwner (krad_x11->display, XCBOwnsEventQueue); } krad_x11->iter = xcb_setup_roots_iterator (xcb_get_setup (krad_x11->connection)); for (s = krad_x11->screen_number; krad_x11->iter.rem; --s, xcb_screen_next (&krad_x11->iter)) { if (s == 0) { krad_x11->screen = krad_x11->iter.data; krad_x11->screen_width = krad_x11->screen->width_in_pixels; krad_x11->screen_height = krad_x11->screen->height_in_pixels; krad_x11->screen_bit_depth = krad_x11->screen->root_depth; } } printk ("Krad X11 created for %d x %d", krad_x11->screen_width, krad_x11->screen_height); return krad_x11; }
int main(int argc, char *argv[]) { Display *display; int default_screen, screen_num; parseArgs(argc, argv); /* Open Xlib Display */ display = XOpenDisplay(0); if (!display) { fprintf(stderr, "Can't open display\n"); return -1; } //font_for_text = XLoadFont(display, font_name_pattern); default_screen = DefaultScreen(display); /* Get the XCB connection from the display */ xcb_connection_t *connection = XGetXCBConnection(display); if (!connection) { XCloseDisplay(display); fprintf(stderr, "Can't get xcb connection from display\n"); return -1; } /* Acquire event ownership */ XSetEventQueueOwner(display, XCBOwnsEventQueue); /* Find XCB screen */ xcb_screen_t *screen = 0; xcb_screen_iterator_t screen_iter = xcb_setup_roots_iterator(xcb_get_setup(connection)); for (screen_num = default_screen; screen_iter.rem && screen_num > 0; --screen_num, xcb_screen_next(&screen_iter)); screen = screen_iter.data; /* Initialize window and OpenGL context, run main loop and deinitialize */ int retval = setup_and_run(display, connection, default_screen, screen); //XUnloadFont(display, font_for_text); /* Cleanup */ XCloseDisplay(display); return retval; }
void QEglFSX11Hooks::platformInit() { m_display = XOpenDisplay(0); if (!m_display) qFatal("Could not open display"); XSetEventQueueOwner(m_display, XCBOwnsEventQueue); m_connection = XGetXCBConnection(m_display); running.ref(); xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(m_connection)); m_connectionEventListener = xcb_generate_id(m_connection); xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, m_connectionEventListener, it.data->root, 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY, it.data->root_visual, 0, 0); m_eventReader = new EventReader(this); m_eventReader->start(); }
void X11WindowedBackend::init() { int screen = 0; xcb_connection_t *c = nullptr; Display *xDisplay = XOpenDisplay(deviceIdentifier().constData()); if (xDisplay) { c = XGetXCBConnection(xDisplay); XSetEventQueueOwner(xDisplay, XCBOwnsEventQueue); screen = XDefaultScreen(xDisplay); } if (c && !xcb_connection_has_error(c)) { m_connection = c; m_screenNumber = screen; m_display = xDisplay; for (xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(m_connection)); it.rem; --screen, xcb_screen_next(&it)) { if (screen == m_screenNumber) { m_screen = it.data; } } XRenderUtils::init(m_connection, m_screen->root); createWindow(); startEventReading(); connect(this, &X11WindowedBackend::cursorChanged, this, [this] { createCursor(softwareCursor(), softwareCursorHotspot()); } ); setReady(true); waylandServer()->seat()->setHasPointer(true); waylandServer()->seat()->setHasKeyboard(true); emit screensQueried(); } else { emit initFailed(); } }
int main(int argc, char *argv[]) { struct passwd *pw; char *username; char *image_path = NULL; int ret; struct pam_conv conv = {conv_callback, NULL}; int curs_choice = CURS_NONE; int o; int optind = 0; struct option longopts[] = { {"version", no_argument, NULL, 'v'}, {"nofork", no_argument, NULL, 'n'}, {"beep", no_argument, NULL, 'b'}, {"dpms", no_argument, NULL, 'd'}, {"color", required_argument, NULL, 'c'}, {"pointer", required_argument, NULL, 'p'}, {"debug", no_argument, NULL, 0}, {"help", no_argument, NULL, 'h'}, {"no-unlock-indicator", no_argument, NULL, 'u'}, {"image", required_argument, NULL, 'i'}, {"tiling", no_argument, NULL, 't'}, {"fuzzy", no_argument, NULL, 'f'}, {"radius", required_argument, NULL, 'r'}, {"sigma", required_argument, NULL, 's'}, {"ignore-empty-password", no_argument, NULL, 'e'}, {"inactivity-timeout", required_argument, NULL, 'I'}, {"show-failed-attempts", no_argument, NULL, 'f'}, {NULL, no_argument, NULL, 0}}; if ((pw = getpwuid(getuid())) == NULL) err(EXIT_FAILURE, "getpwuid() failed"); if ((username = pw->pw_name) == NULL) errx(EXIT_FAILURE, "pw->pw_name is NULL.\n"); char *optstring = "hvnbdc:p:ui:tfr:s:eI:l"; while ((o = getopt_long(argc, argv, optstring, longopts, &optind)) != -1) { switch (o) { case 'v': errx(EXIT_SUCCESS, "version " VERSION " © 2010 Michael Stapelberg"); case 'n': dont_fork = true; break; case 'b': beep = true; break; case 'd': fprintf(stderr, "DPMS support has been removed from i3lock. " "Please see the manpage i3lock(1).\n"); break; case 'I': { int time = 0; if (sscanf(optarg, "%d", &time) != 1 || time < 0) errx(EXIT_FAILURE, "invalid timeout, it must be a positive integer\n"); inactivity_timeout = time; break; } case 'c': { char *arg = optarg; /* Skip # if present */ if (arg[0] == '#') arg++; if (strlen(arg) != 6 || sscanf(arg, "%06[0-9a-fA-F]", color) != 1) errx(EXIT_FAILURE, "color is invalid, it must be given in " "3-byte hexadecimal format: rrggbb\n"); break; } case 'u': unlock_indicator = false; break; case 'i': image_path = strdup(optarg); break; case 't': tile = true; break; case 'f': fuzzy = true; break; case 'r': sscanf(optarg, "%d", &blur_radius); break; case 's': sscanf(optarg, "%f", &blur_sigma); break; case 'p': if (!strcmp(optarg, "win")) { curs_choice = CURS_WIN; } else if (!strcmp(optarg, "default")) { curs_choice = CURS_DEFAULT; } else { errx(EXIT_FAILURE, "i3lock: Invalid pointer type given. " "Expected one of \"win\" or " "\"default\".\n"); } break; case 'e': ignore_empty_password = true; break; case 0: if (strcmp(longopts[optind].name, "debug") == 0) debug_mode = true; break; case 'l': show_failed_attempts = true; break; default: errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c " "color] [-u] [-p win|default]" " [-i image.png] [-t] [-f] [-r radius] [-s " "sigma] [-e] [-I timeout] [-l]"); } } /* We need (relatively) random numbers for highlighting a random part of * the unlock indicator upon keypresses. */ srand(time(NULL)); /* Initialize PAM */ ret = pam_start("i3lock", username, &conv, &pam_handle); if (ret != PAM_SUCCESS) errx(EXIT_FAILURE, "PAM: %s", pam_strerror(pam_handle, ret)); /* Using mlock() as non-super-user seems only possible in Linux. Users of other * operating systems should use encrypted swap/no swap (or remove the ifdef and * run i3lock as super-user). */ #if defined(__linux__) /* Lock the area where we store the password in memory, we don’t want it to * be swapped to disk. Since Linux 2.6.9, this does not require any * privileges, just enough bytes in the RLIMIT_MEMLOCK limit. */ if (mlock(password, sizeof(password)) != 0) err(EXIT_FAILURE, "Could not lock page in memory, check RLIMIT_MEMLOCK"); #endif /* Initialize connection to X11 */ if ((display = XOpenDisplay(NULL)) == NULL) errx(EXIT_FAILURE, "Could not connect to X11, maybe you need to set DISPLAY?"); XSetEventQueueOwner(display, XCBOwnsEventQueue); conn = XGetXCBConnection(display); /* Double checking that connection is good and operatable with xcb */ if (xcb_connection_has_error(conn)) errx(EXIT_FAILURE, "Could not connect to X11, maybe you need to set DISPLAY?"); if (xkb_x11_setup_xkb_extension( conn, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION, 0, NULL, NULL, &xkb_base_event, &xkb_base_error) != 1) errx(EXIT_FAILURE, "Could not setup XKB extension."); static const xcb_xkb_map_part_t 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); static const xcb_xkb_event_type_t required_events = (XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY | XCB_XKB_EVENT_TYPE_STATE_NOTIFY); xcb_xkb_select_events(conn, xkb_x11_get_core_keyboard_device_id(conn), required_events, 0, required_events, required_map_parts, required_map_parts, 0); /* When we cannot initially load the keymap, we better exit */ if (!load_keymap()) errx(EXIT_FAILURE, "Could not load keymap"); const char *locale = getenv("LC_ALL"); if (!locale) locale = getenv("LC_CTYPE"); if (!locale) locale = getenv("LANG"); if (!locale) { if (debug_mode) fprintf(stderr, "Can't detect your locale, fallback to C\n"); locale = "C"; } load_compose_table(locale); xinerama_init(); xinerama_query_screens(); /* check if the X server supports DPMS */ xcb_dpms_capable_cookie_t dpmsc = xcb_dpms_capable(conn); xcb_dpms_capable_reply_t *dpmsr; if ((dpmsr = xcb_dpms_capable_reply(conn, dpmsc, NULL))) { dpms_capable = dpmsr->capable; if (!dpmsr->capable && dpms) { if (debug_mode) fprintf(stderr, "Disabling DPMS, X server not DPMS capable\n"); dpms = false; } free(dpmsr); } screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; last_resolution[0] = screen->width_in_pixels; last_resolution[1] = screen->height_in_pixels; xcb_change_window_attributes(conn, screen->root, XCB_CW_EVENT_MASK, (uint32_t[]){XCB_EVENT_MASK_STRUCTURE_NOTIFY}); if (image_path && !fuzzy) { /* Create a pixmap to render on, fill it with the background color */ img = cairo_image_surface_create_from_png(image_path); /* In case loading failed, we just pretend no -i was specified. */ if (cairo_surface_status(img) != CAIRO_STATUS_SUCCESS) { fprintf(stderr, "Could not load image \"%s\": %s\n", image_path, cairo_status_to_string(cairo_surface_status(img))); img = NULL; } } if (fuzzy) { init_blur_coefficents(); } /* Pixmap on which the image is rendered to (if any) */ xcb_pixmap_t bg_pixmap = draw_image(last_resolution); /* open the fullscreen window, already with the correct pixmap in place */ if (fuzzy) { win = open_overlay_window(conn, screen); } else { win = open_fullscreen_window(conn, screen, color, bg_pixmap); } xcb_free_pixmap(conn, bg_pixmap); if (fuzzy) { /* Set up damage notifications */ set_up_damage_notifications(conn, screen); } else { pid_t pid = fork(); /* The pid == -1 case is intentionally ignored here: * While the child process is useful for preventing other windows from * popping up while i3lock blocks, it is not critical. */ if (pid == 0) { /* Child */ close(xcb_get_file_descriptor(conn)); raise_loop(win); exit(EXIT_SUCCESS); } } cursor = create_cursor(conn, screen, win, curs_choice); grab_pointer_and_keyboard(conn, screen, cursor); /* Load the keymap again to sync the current modifier state. Since we first * loaded the keymap, there might have been changes, but starting from now, * we should get all key presses/releases due to having grabbed the * keyboard. */ (void)load_keymap(); /* Initialize the libev event loop. */ main_loop = EV_DEFAULT; if (main_loop == NULL) errx(EXIT_FAILURE, "Could not initialize libev. Bad LIBEV_FLAGS?\n"); struct ev_io *xcb_watcher = calloc(sizeof(struct ev_io), 1); struct ev_check *xcb_check = calloc(sizeof(struct ev_check), 1); struct ev_prepare *xcb_prepare = calloc(sizeof(struct ev_prepare), 1); ev_io_init(xcb_watcher, xcb_got_event, xcb_get_file_descriptor(conn), EV_READ); ev_io_start(main_loop, xcb_watcher); ev_check_init(xcb_check, xcb_check_cb); ev_check_start(main_loop, xcb_check); ev_prepare_init(xcb_prepare, xcb_prepare_cb); ev_prepare_start(main_loop, xcb_prepare); /* Invoke the event callback once to catch all the events which were * received up until now. ev will only pick up new events (when the X11 * file descriptor becomes readable). */ ev_invoke(main_loop, xcb_check, 0); /* usually fork is called from mapnotify event handler, but in our case * a new window is not created and so the mapnotify event doesn't come */ if (fuzzy && !dont_fork) { dont_fork = true; /* In the parent process, we exit */ if (fork() != 0) exit(0); ev_loop_fork(EV_DEFAULT); } ev_loop(main_loop, 0); }
extern struct gl_platform *gl_platform_create(gs_device_t *device, const struct gs_init_data *info) { /* There's some trickery here... we're mixing libX11, xcb, and GLX For an explanation see here: http://xcb.freedesktop.org/MixingCalls/ Essentially, GLX requires Xlib. Everything else we use xcb. */ struct gl_windowinfo *wi = gl_windowinfo_create(info); struct gl_platform * plat = bmalloc(sizeof(struct gl_platform)); Display * display; print_info_stuff(info); if (!wi) { blog(LOG_ERROR, "Failed to create window info!"); goto fail_wi_create; } display = XOpenDisplay(XDisplayString(info->window.display)); if (!display) { blog(LOG_ERROR, "Unable to open new X connection!"); goto fail_display_open; } XSetEventQueueOwner(display, XCBOwnsEventQueue); XSetErrorHandler(x_error_handler); /* We assume later that cur_swap is already set. */ device->cur_swap = &plat->swap; device->plat = plat; plat->display = display; plat->swap.device = device; plat->swap.info = *info; plat->swap.wi = wi; if (!gl_platform_init_swapchain(&plat->swap)) { blog(LOG_ERROR, "Failed to initialize swap chain!"); goto fail_init_swapchain; } if (!gl_context_create(plat)) { blog(LOG_ERROR, "Failed to create context!"); goto fail_context_create; } if (!glXMakeCurrent(plat->display, wi->window, plat->context)) { blog(LOG_ERROR, "Failed to make context current."); goto fail_make_current; } if (!gladLoadGL()) { blog(LOG_ERROR, "Failed to load OpenGL entry functions."); goto fail_load_gl; } blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION)); goto success; fail_make_current: gl_context_destroy(plat); fail_context_create: fail_load_gl: fail_init_swapchain: XCloseDisplay(display); fail_display_open: fail_wi_create: gl_windowinfo_destroy(wi); free(plat); plat = NULL; success: return plat; }
X11Backend::X11Backend(Compositor& comp, Seat& seat) : Backend(), compositor_(&comp), seat_(&seat) { //setup x connection xDisplay_ = XOpenDisplay(nullptr); if(!xDisplay_) { throw std::runtime_error("cant connect to x11 server"); return; } xConnection_ = XGetXCBConnection(xDisplay_); if(!xConnection_) { throw std::runtime_error("cant get xcb connection"); return; } XSetEventQueueOwner(xDisplay_, XCBOwnsEventQueue); if(xcb_connection_has_error(xConnection_)) { throw std::runtime_error("xcb connection error"); return; } xScreen_ = xcb_setup_roots_iterator(xcb_get_setup(xConnection_)).data; //atoms struct atomProp { xcb_atom_t& ret; std::string str; }; atomProp vec[] = { {atoms::protocols, "WM_PROTOCOLS"}, {atoms::deleteWindow, "WM_DELETE_WINDOW"} }; xcb_intern_atom_reply_t* reply; for(auto& p : vec) { auto atom = xcb_intern_atom(xConnection_, 0, p.str.size(), p.str.c_str()); reply = xcb_intern_atom_reply(xConnection_, atom, nullptr); p.ret = (reply ? reply->atom : 0); } //xkb xkbSetup(); //event source inputEventSource_ = wl_event_loop_add_fd(&comp.wlEventLoop(), xcb_get_file_descriptor(xConnection_), WL_EVENT_READABLE, eventCallback, this); if(!inputEventSource_) throw std::runtime_error("could not create wayland event source"); //what does this? really needed? wl_event_source_check(inputEventSource_); //eglContext eglContext_ = std::make_unique<WaylandEglContext>(xDisplay_); if(!eglContext_) throw std::runtime_error("x11Backend::x11Backend: failed to create EglContext"); eglContext_->bindWlDisplay(compositor_->wlDisplay()); xcb_flush(xConnection_); }
int main(int argc, char *argv[]) { setlocale(LC_TIME, "ru_RU.UTF-8"); char *username; char *image_path = NULL; int ret; struct pam_conv conv = {conv_callback, NULL}; int curs_choice = CURS_NONE; int o; int optind = 0; struct option longopts[] = { {"version", no_argument, NULL, 'v'}, {"nofork", no_argument, NULL, 'n'}, {"beep", no_argument, NULL, 'b'}, {"dpms", no_argument, NULL, 'd'}, {"color", required_argument, NULL, 'c'}, {"pointer", required_argument, NULL , 'p'}, {"debug", no_argument, NULL, 0}, {"help", no_argument, NULL, 'h'}, {"no-unlock-indicator", no_argument, NULL, 'u'}, {"image", required_argument, NULL, 'i'}, {"tiling", no_argument, NULL, 't'}, {"auth-fail-command", required_argument, NULL, 'f'}, {"auth-done-command", required_argument, NULL, 'o'}, {NULL, no_argument, NULL, 0} }; if ((username = getenv("USER")) == NULL) errx(1, "USER environment variable not set, please set it.\n"); while ((o = getopt_long(argc, argv, "hvnbdc:p:ui:f:o:t", longopts, &optind)) != -1) { switch (o) { case 'v': errx(EXIT_SUCCESS, "version " VERSION " © 2010-2012 Michael Stapelberg"); case 'n': dont_fork = true; break; case 'b': beep = true; break; case 'd': dpms = true; break; case 'c': { char *arg = optarg; /* Skip # if present */ if (arg[0] == '#') arg++; if (strlen(arg) != 6 || sscanf(arg, "%06[0-9a-fA-F]", color) != 1) errx(1, "color is invalid, it must be given in 3-byte hexadecimal format: rrggbb\n"); break; } case 'u': unlock_indicator = false; break; case 'i': image_path = strdup(optarg); break; case 't': tile = true; break; case 'p': if (!strcmp(optarg, "win")) { curs_choice = CURS_WIN; } else if (!strcmp(optarg, "default")) { curs_choice = CURS_DEFAULT; } else { errx(1, "i3lock: Invalid pointer type given. Expected one of \"win\" or \"default\".\n"); } break; case 'f': shell_auth_fail_command = strdup(optarg); break; case 'o': shell_auth_done_command = strdup(optarg); break; case 'h': show_time = false; break; case 0: if (strcmp(longopts[optind].name, "debug") == 0) debug_mode = true; break; default: errx(1, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c color] [-u] [-p win|default] [-h]" " [-i image.png] [-t] [-f command] [-o command]" ); } } /* We need (relatively) random numbers for highlighting a random part of * the unlock indicator upon keypresses. */ srand(time(NULL)); /* Initialize PAM */ ret = pam_start("i3lock", username, &conv, &pam_handle); if (ret != PAM_SUCCESS) errx(EXIT_FAILURE, "PAM: %s", pam_strerror(pam_handle, ret)); /* Using mlock() as non-super-user seems only possible in Linux. Users of other * operating systems should use encrypted swap/no swap (or remove the ifdef and * run i3lock as super-user). */ #if defined(__linux__) /* Lock the area where we store the password in memory, we don’t want it to * be swapped to disk. Since Linux 2.6.9, this does not require any * privileges, just enough bytes in the RLIMIT_MEMLOCK limit. */ if (mlock(password, sizeof(password)) != 0) err(EXIT_FAILURE, "Could not lock page in memory, check RLIMIT_MEMLOCK"); #endif /* Initialize connection to X11 */ if ((display = XOpenDisplay(NULL)) == NULL) errx(EXIT_FAILURE, "Could not connect to X11, maybe you need to set DISPLAY?"); XSetEventQueueOwner(display, XCBOwnsEventQueue); conn = XGetXCBConnection(display); /* Double checking that connection is good and operatable with xcb */ if (xcb_connection_has_error(conn)) errx(EXIT_FAILURE, "Could not connect to X11, maybe you need to set DISPLAY?"); /* When we cannot initially load the keymap, we better exit */ if (!load_keymap()) errx(EXIT_FAILURE, "Could not load keymap"); xinerama_init(); xinerama_query_screens(); /* if DPMS is enabled, check if the X server really supports it */ if (dpms) { xcb_dpms_capable_cookie_t dpmsc = xcb_dpms_capable(conn); xcb_dpms_capable_reply_t *dpmsr; if ((dpmsr = xcb_dpms_capable_reply(conn, dpmsc, NULL))) { if (!dpmsr->capable) { if (debug_mode) fprintf(stderr, "Disabling DPMS, X server not DPMS capable\n"); dpms = false; } free(dpmsr); } } screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; last_resolution[0] = screen->width_in_pixels; last_resolution[1] = screen->height_in_pixels; xcb_change_window_attributes(conn, screen->root, XCB_CW_EVENT_MASK, (uint32_t[]){ XCB_EVENT_MASK_STRUCTURE_NOTIFY }); if (image_path) { /* Create a pixmap to render on, fill it with the background color */ img = cairo_image_surface_create_from_png(image_path); /* In case loading failed, we just pretend no -i was specified. */ if (cairo_surface_status(img) != CAIRO_STATUS_SUCCESS) { fprintf(stderr, "Could not load image \"%s\": cairo surface status %d\n", image_path, cairo_surface_status(img)); img = NULL; } } /* Pixmap on which the image is rendered to (if any) */ xcb_pixmap_t bg_pixmap = draw_image(last_resolution); /* open the fullscreen window, already with the correct pixmap in place */ win = open_fullscreen_window(conn, screen, color, bg_pixmap); xcb_free_pixmap(conn, bg_pixmap); cursor = create_cursor(conn, screen, win, curs_choice); grab_pointer_and_keyboard(conn, screen, cursor); if (dpms) dpms_turn_off_screen(conn); /* Initialize the libev event loop. */ main_loop = EV_DEFAULT; if (main_loop == NULL) errx(EXIT_FAILURE, "Could not initialize libev. Bad LIBEV_FLAGS?\n"); struct ev_io *xcb_watcher = calloc(sizeof(struct ev_io), 1); struct ev_check *xcb_check = calloc(sizeof(struct ev_check), 1); struct ev_prepare *xcb_prepare = calloc(sizeof(struct ev_prepare), 1); ev_io_init(xcb_watcher, xcb_got_event, xcb_get_file_descriptor(conn), EV_READ); ev_io_start(main_loop, xcb_watcher); ev_check_init(xcb_check, xcb_check_cb); ev_check_start(main_loop, xcb_check); ev_prepare_init(xcb_prepare, xcb_prepare_cb); ev_prepare_start(main_loop, xcb_prepare); /* Invoke the event callback once to catch all the events which were * received up until now. ev will only pick up new events (when the X11 * file descriptor becomes readable). */ ev_invoke(main_loop, xcb_check, 0); if(show_time) start_time_redraw_tick(); ev_loop(main_loop, 0); }