xcb_visualtype_t *
ephyr_glamor_get_visual(void)
{
    xcb_screen_t *xscreen =
        xcb_aux_get_screen(XGetXCBConnection(dpy), DefaultScreen(dpy));
    int attribs[] = {
        GLX_RENDER_TYPE, GLX_RGBA_BIT,
        GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
        GLX_RED_SIZE, 1,
        GLX_GREEN_SIZE, 1,
        GLX_BLUE_SIZE, 1,
        GLX_DOUBLEBUFFER, 1,
        None
    };
    int event_base = 0, error_base = 0, nelements;
    GLXFBConfig *fbconfigs;

    if (!glXQueryExtension (dpy, &error_base, &event_base))
        FatalError("Couldn't find GLX extension\n");

    fbconfigs = glXChooseFBConfig(dpy, DefaultScreen(dpy), attribs, &nelements);
    if (!nelements)
        FatalError("Couldn't choose an FBConfig\n");
    fb_config = fbconfigs[0];
    free(fbconfigs);

    visual_info = glXGetVisualFromFBConfig(dpy, fb_config);
    if (visual_info == NULL)
        FatalError("Couldn't get RGB visual\n");

    return xcb_aux_find_visual_by_id(xscreen, visual_info->visualid);
}
int main(int argc, char **argv) {
    uint32_t width = test_width - 2 * INSET_X;
    uint32_t height = test_height - 2 * INSET_Y;
    int snum;
    xcb_void_cookie_t check_cookie;
    xcb_window_t w;
    xcb_gcontext_t gc;
    xcb_pixmap_t pix;
    xcb_connection_t *c = xcb_connect(0, &snum);
    xcb_screen_t *s = xcb_aux_get_screen(c, snum);
    xcb_alloc_named_color_cookie_t bg_cookie =
	xcb_alloc_named_color(c, s->default_colormap,
			      strlen("white"), "white");
    xcb_alloc_named_color_cookie_t fg_cookie =
	xcb_alloc_named_color(c, s->default_colormap,
			      strlen("black"), "black");
    xcb_alloc_named_color_reply_t *bg_reply =
	xcb_alloc_named_color_reply(c, bg_cookie, 0);
    xcb_alloc_named_color_reply_t *fg_reply =
	xcb_alloc_named_color_reply(c, fg_cookie, 0);
    uint32_t fg, bg;
    xcb_image_t *image, *native_image, *subimage;
    uint32_t mask = 0;
    xcb_params_gc_t gcv;

    assert(bg_reply && fg_reply);
    bg = bg_reply->pixel;
    fg = fg_reply->pixel;
    free(bg_reply);
    free(fg_reply);
    w = make_window(c, s, bg, fg, width, height);
    gc = xcb_generate_id(c);
    check_cookie = xcb_create_gc_checked(c, gc, w, 0, 0);
    assert(!xcb_request_check(c, check_cookie));
    image = xcb_image_create_from_bitmap_data((uint8_t *)test_bits,
					      test_width, test_height);
    native_image = xcb_image_native(c, image, 1);
    assert(native_image);
    if (native_image != image)
	xcb_image_destroy(image);
    subimage = xcb_image_subimage(native_image, INSET_X, INSET_Y,
				  width, height,
				  0, 0, 0);
    assert(subimage);
    xcb_image_destroy(native_image);
    subimage->format = XCB_IMAGE_FORMAT_XY_BITMAP;
    pix = xcb_generate_id(c);
    xcb_create_pixmap(c, s->root_depth, pix, w,
		      subimage->width, subimage->height);
    gc = xcb_generate_id(c);
    XCB_AUX_ADD_PARAM(&mask, &gcv, foreground, fg);
    XCB_AUX_ADD_PARAM(&mask, &gcv, background, bg);
    xcb_aux_create_gc(c, gc, pix, mask, &gcv);
    xcb_image_put(c, pix, gc, subimage, 0, 0, 0);
    process_events(c, gc, w, pix, width, height);
    xcb_disconnect(c);
    return 1;
}
Exemple #3
0
int run(config_t* config, key_handler_t key_handler)
{
    int default_screen;
    xcb_connection_t* c = xcb_connect(NULL, &default_screen);

    if(xcb_connection_has_error(c))
    {
		fprintf(stderr, "Cannot open display %s\n",
                getenv("DISPLAY") ? getenv("DISPLAY") : "<NULL>");
        return -1;
    }
    xcb_screen_t* screen;
    if(!(screen = xcb_aux_get_screen(c, default_screen)))
    {
        fprintf(stderr, "Cannot obtain default screen.\n");
        return -1;
    }

    context_t context = { config, key_handler };

    xcb_event_handlers_t eh;
    memset(&eh, 0, sizeof(xcb_event_handlers_t));
    xcb_event_handlers_init(c, &eh);
    xcb_event_set_key_press_handler(&eh, handle_keypress, &context);

    xcb_void_cookie_t* cookies = alloca(sizeof(xcb_void_cookie_t)
                                             * config->count);
    if(!cookies)
        return -1;

    int i;
    for(i = 0; i < config->count; ++i)
        cookies[i] = xcb_grab_key(c, true, screen->root,
                                  config->keys[i].is_alt ? XCB_MOD_MASK_1 : 0,
                                  config->keys[i].keysym, XCB_GRAB_MODE_ASYNC,
                                  XCB_GRAB_MODE_ASYNC);

    for(i = 0; i < config->count; ++i)
    {
        xcb_generic_error_t* e = xcb_request_check(c, cookies[i]);
        if(e)
        {
            fprintf(stderr, "WARNING: unable to grab key: %d\n", e->error_code);
            free(e);
        }
    }

    xcb_generic_event_t* e;
    while((e = xcb_wait_for_event(c)))
    {
        xcb_event_handle(&eh, e);
        free(e);
    }

    return 0;
}
static void setup(void) {
    int screennr;
    conn = xcb_connect(NULL, &screennr);
    if (xcb_connection_has_error(conn)) {
        fprintf(stderr, "Failed to connect to X11 server.\n");
        exit(EXIT_FAILURE);
    }

    screen = xcb_aux_get_screen(conn, 0);
}
Exemple #5
0
/*
 * Creates a database similarly to XGetDefault(). For typical applications,
 * this is the recommended way to construct the resource database.
 *
 * The database is created as follows:
 *   - If the RESOURCE_MANAGER property exists on the root window of
 *     screen 0, the database is constructed from it using @ref
 *     xcb_xrm_database_from_resource_manager().
 *   - Otherwise, if $HOME/.Xresources exists, the database is constructed from
 *     it using @ref xcb_xrm_database_from_file().
 *   - Otherwise, if $HOME/.Xdefaults exists, the database is constructed from
 *     it using @ref xcb_xrm_database_from_file().
 *   - If the environment variable XENVIRONMENT is set, the file specified by
 *     it is loaded using @ref xcb_xrm_database_from_file and then combined with
 *     the database using @ref xcb_xrm_database_combine() with override set to
 *     true.
 *     If XENVIRONMENT is not specified, the same is done with
 *     $HOME/.Xdefaults-$HOSTNAME, wherein $HOSTNAME is determined by
 *     gethostname(2).
 *
 * This represents the way XGetDefault() creates the database for the most
 * part, but is not exactly the same. In particular, XGetDefault() does not
 * consider $HOME/.Xresources.
 *
 * @param conn XCB connection.
 * @returns The constructed database. Can return NULL, e.g., if the screen
 * cannot be determined.
 */
xcb_xrm_database_t *xcb_xrm_database_from_default(xcb_connection_t *conn) {
    xcb_screen_t *screen;
    xcb_xrm_database_t *database;
    char *xenvironment;

    screen = xcb_aux_get_screen(conn, 0);
    if (screen == NULL)
        return NULL;

    /* 1. Try to load the database from RESOURCE_MANAGER. */
    database = xcb_xrm_database_from_resource_manager(conn, screen);

    /* 2. Otherwise, try to load the database from $HOME/.Xresources. */
    if (database == NULL) {
        char *xresources = get_home_dir_file(".Xresources");
        database = xcb_xrm_database_from_file(xresources);
        FREE(xresources);
    }

    /* 3. Otherwise, try to load the database from $HOME/.Xdefaults. */
    if (database == NULL) {
        char *xdefaults = get_home_dir_file(".Xdefaults");
        database = xcb_xrm_database_from_file(xdefaults);
        FREE(xdefaults);
    }

    /* 4. If XENVIRONMENT is specified, merge the database defined by that file.
     *    Otherwise, use $HOME/.Xdefaults-$HOSTNAME. */
    if ((xenvironment = getenv("XENVIRONMENT")) != NULL) {
        xcb_xrm_database_t *source = xcb_xrm_database_from_file(xenvironment);
        xcb_xrm_database_combine(source, &database, true);
        xcb_xrm_database_free(source);
    } else {
        char hostname[1024];
        hostname[1023] = '\0';
        if (gethostname(hostname, 1023) == 0) {
            char *name;
            if (asprintf(&name, ".Xdefaults-%s", hostname) >= 0) {
                xcb_xrm_database_t *source;

                char *xdefaults = get_home_dir_file(name);
                FREE(name);

                source = xcb_xrm_database_from_file(xdefaults);
                FREE(xdefaults);

                xcb_xrm_database_combine(source, &database, true);
                xcb_xrm_database_free(source);
            }
        }
    }

    return database;
}
Exemple #6
0
void scan_windows(void)
{
    const int screens_len = xcb_setup_roots_length(xcb_get_setup(wm_conf.connection));
    int screen_idx;
    xcb_window_t root_wins[screens_len];
    xcb_query_tree_cookie_t root_tree_cookies[screens_len];

    /* request window trees for the root window of each screen */
    for (screen_idx = 0; screen_idx < screens_len; ++screen_idx) {
        xcb_screen_t *screen = xcb_aux_get_screen(wm_conf.connection, screen_idx);
        root_wins[screen_idx] = screen->root;
        root_tree_cookies[screen_idx] = xcb_query_tree_unchecked(wm_conf.connection,
                                                                 root_wins[screen_idx]);
    }

    xcb_query_tree_reply_t *root_tree_replies[screens_len];
    xcb_window_t *wins;
    int wins_len;

    /* collect replies */
    for (screen_idx = 0; screen_idx < screens_len; ++screen_idx) {
        root_tree_replies[screen_idx] = xcb_query_tree_reply(wm_conf.connection,
                                                             root_tree_cookies[screen_idx],
                                                             NULL);
        wins = xcb_query_tree_children(root_tree_replies[screen_idx]);
        if (!wins)
            fprintf(stderr, "failed to get child tree for window %u\n", root_wins[screen_idx]);
        wins_len = xcb_query_tree_children_length(root_tree_replies[screen_idx]);
        fprintf(stderr, "root window %u has %d children\n", root_wins[screen_idx], wins_len);

        fprintf(stderr, "examining children\n");
        xcb_window_t child_win;
        int i;
        for (i = 0; i < wins_len; ++i) {
            child_win = wins[i];
            fprintf(stderr, "  child window %u\n", child_win);
            client_t *client = find_client(child_win);
            if (!client) {
                client = client_init(client_alloc());
                client->window = child_win;
                sglib_client_t_add(&client_list, client);
            }
            read_client_geometry(client);
        }
    }

    for (screen_idx = 0; screen_idx < screens_len; ++screen_idx)
        free(root_tree_replies[screen_idx]);
}
Exemple #7
0
xcb_visualtype_t *
xcb_aux_get_visualtype (xcb_connection_t *c,
                        int               scr,
                        xcb_visualid_t    vid)
{
  xcb_screen_t        *screen;
  xcb_depth_t         *depth;
  xcb_visualtype_iterator_t iter;
  int               cur;

  screen = xcb_aux_get_screen (c, scr);
  if (!screen) return NULL;

  depth = xcb_screen_allowed_depths_iterator(screen).data;
  if (!depth) return NULL;
   
   iter = xcb_depth_visuals_iterator(depth);
   for (cur = 0 ; cur < iter.rem ; xcb_visualtype_next(&iter), ++cur)
      if (vid == iter.data->visual_id)
	 return iter.data;

   return NULL;
}
Exemple #8
0
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;
}
Exemple #9
0
ZLEwlViewWidget::ZLEwlViewWidget(ZLApplication *application, ZLView::Angle initialAngle) : ZLViewWidget(initialAngle) {
	myApplication = application;
	w = 600;
	h = 800;

	xcb_screen_iterator_t screen_iter;
	const xcb_setup_t    *setup;
	xcb_generic_event_t  *e;
	xcb_generic_error_t  *error;
	xcb_void_cookie_t     cookie_window;
	xcb_void_cookie_t     cookie_map;
	uint32_t              mask;
	uint32_t              values[2];
	int                   screen_number;
	uint8_t               is_hand = 0;
	xcb_rectangle_t     rect_coord = { 0, 0, 600, 800};

	/* getting the connection */
	connection = xcb_connect (NULL, &screen_number);
	if (xcb_connection_has_error(connection)) {
		fprintf (stderr, "ERROR: can't connect to an X server\n");
		exit(-1);
	}

	screen = xcb_aux_get_screen (connection, screen_number);

	gc = xcb_generate_id (connection);
	mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
	values[0] = screen->black_pixel;
	values[1] = 0; /* no graphics exposures */
	xcb_create_gc (connection, gc, screen->root, mask, values);

	bgcolor = xcb_generate_id (connection);
	mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
	values[0] = screen->white_pixel;
	values[1] = 0; /* no graphics exposures */
	xcb_create_gc (connection, bgcolor, screen->root, mask, values);

	/* creating the window */
	window = xcb_generate_id(connection);
	mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
	values[0] = screen->white_pixel;
	values[1] =
		XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
		XCB_EVENT_MASK_BUTTON_PRESS |
		XCB_EVENT_MASK_EXPOSURE |
		XCB_EVENT_MASK_POINTER_MOTION |
		XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
		XCB_EVENT_MASK_FOCUS_CHANGE      | XCB_EVENT_MASK_PROPERTY_CHANGE;

	uint8_t depth = xcb_aux_get_depth (connection, screen);
	xcb_create_window(connection,
			depth,
			window, screen->root,
			0, 0, 600, 800,
			0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
			screen->root_visual,
			mask, values);

	rect = xcb_generate_id (connection);
	xcb_create_pixmap (connection, depth,
			rect, window,
			600, 800);

	xcb_map_window(connection, window);

	xcb_colormap_t    colormap;
	colormap = screen->default_colormap;

	xcb_alloc_color_reply_t *rep;
	rep = xcb_alloc_color_reply (connection, xcb_alloc_color (connection, colormap, 0, 0, 0), NULL);
	pal_[0] = rep->pixel;
	free(rep);
	rep = xcb_alloc_color_reply (connection, xcb_alloc_color (connection, colormap, 0x55<<8, 0x55<<8, 0x55<<8), NULL);
	pal_[1] = rep->pixel;
	free(rep);
	rep = xcb_alloc_color_reply (connection, xcb_alloc_color (connection, colormap, 0xaa<<8, 0xaa<<8, 0xaa<<8), NULL);
	pal_[2] = rep->pixel;
	free(rep);
	rep = xcb_alloc_color_reply (connection, xcb_alloc_color (connection, colormap, 0xff<<8, 0xff<<8, 0xff<<8), NULL);
	pal_[3] = rep->pixel;
	free(rep);

	pal = pal_;

	xcb_shm_query_version_reply_t *rep_shm;

	rep_shm = xcb_shm_query_version_reply (connection,
			xcb_shm_query_version (connection),
			NULL);
	if(rep_shm) {
		xcb_image_format_t format;
		int shmctl_status;

		if (rep_shm->shared_pixmaps &&
				(rep_shm->major_version > 1 || rep_shm->minor_version > 0))
			format = (xcb_image_format_t)rep_shm->pixmap_format;
		else
			format = (xcb_image_format_t)0;

		im = xcb_image_create_native (connection, 600, 800,
				format, depth, NULL, ~0, NULL);
		assert(im);

		shminfo.shmid = shmget (IPC_PRIVATE,
				im->stride*im->height,
				IPC_CREAT | 0777);
		assert(shminfo.shmid != -1);
		shminfo.shmaddr = (uint8_t*)shmat (shminfo.shmid, 0, 0);
		assert(shminfo.shmaddr);
		im->data = shminfo.shmaddr;

		shminfo.shmseg = xcb_generate_id (connection);
		xcb_shm_attach (connection, shminfo.shmseg,
				shminfo.shmid, 0);
		shmctl_status = shmctl(shminfo.shmid, IPC_RMID, 0);
		assert(shmctl_status != -1);
		free (rep_shm);
	}

	xcb_flush(connection);
}
Exemple #10
0
int main(int argc, char *argv[]) {
    format = sstrdup("%s");
    char *socket_path = NULL;
    char *pattern = sstrdup("pango:monospace 8");
    int o, option_index = 0;

    static struct option long_options[] = {
        {"socket", required_argument, 0, 's'},
        {"version", no_argument, 0, 'v'},
        {"limit", required_argument, 0, 'l'},
        {"prompt", required_argument, 0, 'P'},
        {"prefix", required_argument, 0, 'p'},
        {"format", required_argument, 0, 'F'},
        {"font", required_argument, 0, 'f'},
        {"help", no_argument, 0, 'h'},
        {0, 0, 0, 0}};

    char *options_string = "s:p:P:f:l:F:vh";

    while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
        switch (o) {
            case 's':
                FREE(socket_path);
                socket_path = sstrdup(optarg);
                break;
            case 'v':
                printf("i3-input " I3_VERSION);
                return 0;
            case 'p':
                /* This option is deprecated, but will still work in i3 v4.1, 4.2 and 4.3 */
                fprintf(stderr, "i3-input: WARNING: the -p option is DEPRECATED in favor of the -F (format) option\n");
                FREE(format);
                sasprintf(&format, "%s%%s", optarg);
                break;
            case 'l':
                limit = atoi(optarg);
                break;
            case 'P':
                i3string_free(prompt);
                prompt = i3string_from_utf8(optarg);
                break;
            case 'f':
                FREE(pattern);
                pattern = sstrdup(optarg);
                break;
            case 'F':
                FREE(format);
                format = sstrdup(optarg);
                break;
            case 'h':
                printf("i3-input " I3_VERSION "\n");
                printf("i3-input [-s <socket>] [-F <format>] [-l <limit>] [-P <prompt>] [-f <font>] [-v]\n");
                printf("\n");
                printf("Example:\n");
                printf("    i3-input -F 'workspace \"%%s\"' -P 'Switch to workspace: '\n");
                return 0;
        }
    }

    printf("using format \"%s\"\n", format);

    int screen;
    conn = xcb_connect(NULL, &screen);
    if (!conn || xcb_connection_has_error(conn))
        die("Cannot open display\n");

    sockfd = ipc_connect(socket_path);

    root_screen = xcb_aux_get_screen(conn, screen);
    root = root_screen->root;

    symbols = xcb_key_symbols_alloc(conn);

    init_dpi();
    font = load_font(pattern, true);
    set_font(&font);

    if (prompt != NULL)
        prompt_offset = predict_text_width(prompt);

    const xcb_rectangle_t win_pos = get_window_position();

    /* Open an input window */
    win = xcb_generate_id(conn);
    xcb_create_window(
        conn,
        XCB_COPY_FROM_PARENT,
        win,                                                 /* the window id */
        root,                                                /* parent == root */
        win_pos.x, win_pos.y, win_pos.width, win_pos.height, /* dimensions */
        0,                                                   /* X11 border = 0, we draw our own */
        XCB_WINDOW_CLASS_INPUT_OUTPUT,
        XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */
        XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK,
        (uint32_t[]){
            0, /* back pixel: black */
            1, /* override redirect: don’t manage this window */
            XCB_EVENT_MASK_EXPOSURE});

    /* Map the window (make it visible) */
    xcb_map_window(conn, win);

    /* Initialize the drawable surface */
    draw_util_surface_init(conn, &surface, win, get_visualtype(root_screen), win_pos.width, win_pos.height);

    /* Grab the keyboard to get all input */
    xcb_flush(conn);

    /* Try (repeatedly, if necessary) to grab the keyboard. We might not
     * get the keyboard at the first attempt because of the keybinding
     * still being active when started via a wm’s keybinding. */
    xcb_grab_keyboard_cookie_t cookie;
    xcb_grab_keyboard_reply_t *reply = NULL;

    int count = 0;
    while ((reply == NULL || reply->status != XCB_GRAB_STATUS_SUCCESS) && (count++ < 500)) {
        cookie = xcb_grab_keyboard(conn, false, win, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
        reply = xcb_grab_keyboard_reply(conn, cookie, NULL);
        usleep(1000);
    }

    if (reply->status != XCB_GRAB_STATUS_SUCCESS) {
        fprintf(stderr, "Could not grab keyboard, status = %d\n", reply->status);
        exit(-1);
    }

    xcb_flush(conn);

    xcb_generic_event_t *event;
    while ((event = xcb_wait_for_event(conn)) != NULL) {
        if (event->response_type == 0) {
            fprintf(stderr, "X11 Error received! sequence %x\n", event->sequence);
            continue;
        }

        /* Strip off the highest bit (set if the event is generated) */
        int type = (event->response_type & 0x7F);

        switch (type) {
            case XCB_KEY_PRESS:
                handle_key_press(NULL, conn, (xcb_key_press_event_t *)event);
                break;

            case XCB_KEY_RELEASE:
                handle_key_release(NULL, conn, (xcb_key_release_event_t *)event);
                break;

            case XCB_EXPOSE:
                if (((xcb_expose_event_t *)event)->count == 0) {
                    handle_expose(NULL, conn, (xcb_expose_event_t *)event);
                }

                break;
        }

        free(event);
    }

    draw_util_surface_free(conn, &surface);
    return 0;
}
static int
dri2_connect(Display *display)
{
	xcb_dri2_query_version_cookie_t query_version_cookie;
	xcb_dri2_query_version_reply_t *query_version_reply;
	xcb_dri2_connect_cookie_t connect_cookie;
	xcb_dri2_connect_reply_t *connect_reply;
	xcb_dri2_authenticate_cookie_t auth_cookie;
	xcb_dri2_authenticate_reply_t *auth_reply;
	xcb_screen_t *root;
	xcb_connection_t *c = XGetXCBConnection(display);
	drm_magic_t magic;
	const xcb_query_extension_reply_t *dri2_reply;
	char *device_name;
	int len;

	root = xcb_aux_get_screen(c, DefaultScreen(display));

	dri2_reply = xcb_get_extension_data(c, &xcb_dri2_id);

	if (!dri2_reply) {
		XVMC_ERR("DRI2 required");
		return BadValue;
	}

	/* Query the extension and make our first use of it at the same time. */
	query_version_cookie = xcb_dri2_query_version(c, 1, 0);
	connect_cookie = xcb_dri2_connect(c, root->root, DRI2DriverDRI);

	query_version_reply =
		xcb_dri2_query_version_reply(c, query_version_cookie, NULL);
	connect_reply = xcb_dri2_connect_reply(c, connect_cookie, NULL);

	if (!query_version_reply) {
		XVMC_ERR("DRI2 required");
		return BadValue;
	}
	free(query_version_reply);

	len = xcb_dri2_connect_device_name_length(connect_reply);
	device_name = malloc(len + 1);
	if (!device_name) {
		XVMC_ERR("malloc failure");
		return BadAlloc;
	}
	strncpy(device_name, xcb_dri2_connect_device_name(connect_reply), len);
	device_name[len] = 0;
	xvmc_driver->fd = open(device_name, O_RDWR);
	free(device_name);
	free(connect_reply);
	if (xvmc_driver->fd < 0) {
		XVMC_ERR("Failed to open drm device: %s\n", strerror(errno));
		return BadValue;
	}

	if (drmGetMagic(xvmc_driver->fd, &magic)) {
		XVMC_ERR("Failed to get magic\n");
		return BadValue;
	}

	auth_cookie = xcb_dri2_authenticate(c, root->root, magic);
	auth_reply = xcb_dri2_authenticate_reply(c, auth_cookie, NULL);
	if (!auth_reply) {
		XVMC_ERR("Failed to authenticate magic %d\n", magic);
		return BadValue;
	}
	free(auth_reply);

	return Success;
}
Exemple #12
0
static gboolean
_eventd_nd_xcb_start(EventdNdBackendContext *self, const gchar *target)
{
    gint r;
    gchar *h;
    gint d;

    r = xcb_parse_display(target, &h, &d, NULL);
    if ( r == 0 )
        return FALSE;
    free(h);

    const xcb_query_extension_reply_t *extension_query;
    gint screen;

    self->source = g_water_xcb_source_new(NULL, target, &screen, _eventd_nd_xcb_events_callback, self, NULL);
    if ( self->source == NULL )
    {
        g_warning("Couldn't initialize X connection for '%s'", target);
        return FALSE;
    }

    self->xcb_connection = g_water_xcb_source_get_connection(self->source);
    self->screen_number = screen;
    self->screen = xcb_aux_get_screen(self->xcb_connection, screen);

    self->bubbles = g_hash_table_new(NULL, NULL);

    if ( self->follow_focus != EVENTD_ND_XCB_FOLLOW_FOCUS_NONE )
    {
        guint32 mask[] = { XCB_EVENT_MASK_PROPERTY_CHANGE };
        xcb_change_window_attributes(self->xcb_connection, self->screen->root, XCB_CW_EVENT_MASK, mask);
    }

    xcb_intern_atom_cookie_t *ac;
    ac = xcb_ewmh_init_atoms(self->xcb_connection, &self->ewmh);
    xcb_ewmh_init_atoms_replies(&self->ewmh, ac, NULL);

    extension_query = xcb_get_extension_data(self->xcb_connection, &xcb_randr_id);
    if ( ! extension_query->present )
        g_warning("No RandR extension");
    else
    {
        self->randr = TRUE;
        self->randr_event_base = extension_query->first_event;
        xcb_randr_select_input(self->xcb_connection, self->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);
    }

    self->custom_map = _eventd_nd_xcb_get_colormap(self);

    if ( self->custom_map )
    {
        /* We have a 32bit color map, try to support compositing */
        xcb_get_selection_owner_cookie_t oc;
        xcb_window_t owner;
        oc = xcb_ewmh_get_wm_cm_owner(&self->ewmh, self->screen_number);
        self->compositing = xcb_ewmh_get_wm_cm_owner_reply(&self->ewmh, oc, &owner, NULL) && ( owner != XCB_WINDOW_NONE );

        extension_query = xcb_get_extension_data(self->xcb_connection, &xcb_xfixes_id);
        if ( ! extension_query->present )
            g_warning("No XFixes extension");
        else
        {
            xcb_xfixes_query_version_cookie_t vc;
            xcb_xfixes_query_version_reply_t *r;
            vc = xcb_xfixes_query_version(self->xcb_connection, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION);
            r = xcb_xfixes_query_version_reply(self->xcb_connection, vc, NULL);
            if ( r == NULL )
                g_warning("Cannot get XFixes version");
            else
            {
                self->xfixes = TRUE;
                self->xfixes_event_base = extension_query->first_event;
                xcb_xfixes_select_selection_input_checked(self->xcb_connection, self->screen->root,
                    self->ewmh._NET_WM_CM_Sn[self->screen_number],
                    XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
                    XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
                    XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE);
            }
        }
    }

    extension_query = xcb_get_extension_data(self->xcb_connection, &xcb_shape_id);
    if ( ! extension_query->present )
        g_warning("No Shape extension");
    else
        self->shape = TRUE;

    xcb_flush(self->xcb_connection);
    _eventd_nd_xcb_check_geometry(self);

    return TRUE;
}
Exemple #13
0
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;
}
/**
 * sn_xcb_display_new:
 * @xdisplay: an X window system connection
 * @push_trap_func: function to push an X error trap
 * @pop_trap_func: function to pop an X error trap
 *
 * Creates a new #SnDisplay object, containing
 * data that libsn associates with an X connection.
 *
 * @push_trap_func should be a function that causes X errors to be
 * ignored until @pop_trap_func is called as many times as
 * @push_trap_func has been called. (Nested push/pop pairs must be
 * supported.)
 * These functions are used to avoid X errors due to BadWindow and
 * such.
 *
 * Return value: the new #SnDisplay
 **/
SnDisplay*
sn_xcb_display_new (xcb_connection_t          *xconnection,
                    SnXcbDisplayErrorTrapPush  push_trap_func,
                    SnXcbDisplayErrorTrapPop   pop_trap_func)
{
  SnDisplay *display;
  int i;

  /* Get all atoms we will need in the future */
  xcb_intern_atom_cookie_t atom_utf8_string_c =
    xcb_intern_atom(xconnection, FALSE,
                    sizeof("UTF8_STRING") - 1, "UTF8_STRING");

  xcb_intern_atom_cookie_t atom_net_startup_info_begin_c =
    xcb_intern_atom(xconnection, FALSE,
                    sizeof("_NET_STARTUP_INFO_BEGIN") - 1,
                    "_NET_STARTUP_INFO_BEGIN");

  xcb_intern_atom_cookie_t atom_net_startup_info_c =
    xcb_intern_atom(xconnection, FALSE,
                    sizeof("_NET_STARTUP_INFO") - 1, "_NET_STARTUP_INFO");

  xcb_intern_atom_cookie_t atom_net_startup_id_c =
    xcb_intern_atom(xconnection, FALSE,
                    sizeof("_NET_STARTUP_ID") - 1, "_NET_STARTUP_ID");

  display = sn_new0 (SnDisplay, 1);

  display->xconnection = xconnection;
  display->n_screens = xcb_setup_roots_length (xcb_get_setup (xconnection));
  display->screens = sn_new (xcb_screen_t*, display->n_screens);
  display->refcount = 1;

  display->xcb_push_trap_func = push_trap_func;
  display->xcb_pop_trap_func = pop_trap_func;

  for (i = 0; i < display->n_screens; ++i)
    display->screens[i] = xcb_aux_get_screen(xconnection, i);

  xcb_intern_atom_reply_t *atom_reply;

  atom_reply = xcb_intern_atom_reply(display->xconnection,
                                     atom_utf8_string_c,
                                     NULL);
  display->UTF8_STRING = atom_reply->atom;
  free(atom_reply);

  atom_reply = xcb_intern_atom_reply(display->xconnection,
                                     atom_net_startup_info_begin_c,
                                     NULL);
  display->NET_STARTUP_INFO_BEGIN = atom_reply->atom;
  free(atom_reply);

  atom_reply = xcb_intern_atom_reply(display->xconnection,
                                     atom_net_startup_info_c,
                                     NULL);
  display->NET_STARTUP_INFO = atom_reply->atom;
  free(atom_reply);

  atom_reply = xcb_intern_atom_reply(display->xconnection,
                                     atom_net_startup_id_c,
                                     NULL);
  display->NET_STARTUP_ID = atom_reply->atom;
  free(atom_reply);

  return display;
}
Exemple #15
0
/* Main driver */
int
main (int argc, char **argv)
{
    xcb_connection_t *conn;
    int conn_screen;
    xcb_screen_t *root_screen;
    xcb_drawable_t root_window;
    xcb_connection_t *conn_two;
    int conn_two_screen;
    xcb_screen_t *root_two_screen;
    xcb_drawable_t root_two_window;
    xcb_drawable_t window;

    uint32_t mask;
    uint32_t values[1];

    xcb_void_cookie_t cookie;

    xcb_get_geometry_reply_t *geom_reply;

    xcb_generic_event_t *event;

    image_data_t img_data;
    xcb_image_t *image;
    xcb_pixmap_t pixmap;
    xcb_gcontext_t gc;

    /* Check the first argument to see what display to connect to. If
       empty, then use default display. */
    if (argc > 1) {
      conn = xcb_connect(argv[1], &conn_screen);
    } else {
      conn = xcb_connect(NULL, &conn_screen);
    }
    root_screen = xcb_aux_get_screen(conn, conn_screen);
    root_window = root_screen->root;

    /* Get the geometry of the root window */
    geom_reply = GetWindowGeometry(conn, root_window);
    
    WriteWindowInfo(conn, root_window);
	WriteAllChildrenWindowInfo(conn, root_window);
    img_data = GetWindowImageData(conn, root_window);

	xcb_flush(conn);
    /* Get the image of the root window */
    image = xcb_image_get(conn,
                          root_window,
                          geom_reply->x,
                          geom_reply->y,
                          geom_reply->width,
                          geom_reply->height,
                          (unsigned int) ~0L,
                          XCB_IMAGE_FORMAT_Z_PIXMAP);
    /* Set up the events the window will recognize */
    mask = XCB_CW_EVENT_MASK;
    values[0] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;

    /* Create our new window on the default display. Make it half the size */
    conn_two = xcb_connect(NULL, &conn_two_screen);
    root_two_screen = xcb_aux_get_screen(conn_two, conn_two_screen);
    root_two_window = root_two_screen->root;
    window = xcb_generate_id(conn_two);
    cookie = xcb_create_window_checked(conn_two,
                                       XCB_COPY_FROM_PARENT,
                                       window,
                                       root_two_window,
                                       geom_reply->x,
                                       geom_reply->y,
                                       geom_reply->width / 2,
                                       geom_reply->height / 2,
                                       geom_reply->border_width,
                                       XCB_WINDOW_CLASS_INPUT_OUTPUT,
                                       root_two_screen->root_visual,
                                       mask,
                                       values);
    if (RequestCheck(conn_two, cookie, "Falied to create new window")) {
        exit(1);
    }

    WriteWindowInfo(conn_two, window);
    /* Map the window and flush the connection so it draws to the screen */
    xcb_map_window(conn_two, window);
    xcb_flush(conn_two);
    WriteWindowInfo(conn_two, window);

    /* Create the pixmap and associate it with our new window. */
    pixmap = xcb_generate_id(conn_two);
    cookie = xcb_create_pixmap(conn_two,
                               geom_reply->depth,
                               pixmap,
                               window,
                               geom_reply->width,
                               geom_reply->height);
    if (RequestCheck(conn_two, cookie, "Failed to create pixmap")) {
        exit(1);
    }

    /* Put the root_window image into the pixmap. Note that a gc is
     * created, but I believe it is ignored. */
    gc = xcb_generate_id(conn_two);
    xcb_create_gc(conn_two, gc, window, 0, 0);
    cookie = xcb_image_put(conn_two,
                           pixmap,
                           gc,
                           image,
                           0,
                           0,
                           0);
    if (RequestCheck(conn_two, cookie, "Failed to put image into pixmap")) {
        exit(1);
    }

    /* Copy the pixmap into the new window */
    cookie = xcb_copy_area(conn_two,
                           pixmap,
                           window,
                           gc,
                           0,
                           0,
                           0,
                           0,
                           geom_reply->width / 2,
                           geom_reply->height / 2);
    if (RequestCheck(conn_two, cookie, "Failed to put image into pixmap")) {
        exit(1);
    }
                           
    xcb_flush(conn_two);
    WriteWindowInfo(conn_two, window);

    /* Enter infinte loop so the window stays open */
    while (1) {
    }

    /* Never get here, but if we could, would still want to clean up memory */
    free(geom_reply);
    xcb_disconnect(conn);
    xcb_disconnect(conn_two);

    return 0;
}
Exemple #16
0
Fichier : main.c Projet : stfnm/i3
/*
 * Creates the config file and tells i3 to reload.
 *
 */
static void finish() {
    printf("creating \"%s\"...\n", config_path);

    if (!(dpy = XOpenDisplay(NULL)))
        errx(1, "Could not connect to X11");

    FILE *kc_config = fopen(SYSCONFDIR "/i3/config.keycodes", "r");
    if (kc_config == NULL)
        err(1, "Could not open input file \"%s\"", SYSCONFDIR "/i3/config.keycodes");

    FILE *ks_config = fopen(config_path, "w");
    if (ks_config == NULL)
        err(1, "Could not open output config file \"%s\"", config_path);
    free(config_path);

    char *line = NULL;
    size_t len = 0;
#ifndef USE_FGETLN
    ssize_t read;
#endif
    bool head_of_file = true;

    /* write a header about auto-generation to the output file */
    fputs("# This file has been auto-generated by i3-config-wizard(1).\n", ks_config);
    fputs("# It will not be overwritten, so edit it as you like.\n", ks_config);
    fputs("#\n", ks_config);
    fputs("# Should you change your keyboard layout somewhen, delete\n", ks_config);
    fputs("# this file and re-run i3-config-wizard(1).\n", ks_config);
    fputs("#\n", ks_config);

#ifdef USE_FGETLN
    char *buf = NULL;
    while ((buf = fgetln(kc_config, &len)) != NULL) {
        /* fgetln does not return null-terminated strings */
        FREE(line);
        sasprintf(&line, "%.*s", len, buf);
#else
    size_t linecap = 0;
    while ((read = getline(&line, &linecap, kc_config)) != -1) {
        len = strlen(line);
#endif
        /* skip the warning block at the beginning of the input file */
        if (head_of_file &&
            strncmp("# WARNING", line, strlen("# WARNING")) == 0)
            continue;

        head_of_file = false;

        /* Skip leading whitespace */
        char *walk = line;
        while (isspace(*walk) && walk < (line + len)) {
            /* Pre-output the skipped whitespaces to keep proper indentation */
            fputc(*walk, ks_config);
            walk++;
        }

        /* Set the modifier the user chose */
        if (strncmp(walk, "set $mod ", strlen("set $mod ")) == 0) {
            if (modifier == MOD_Mod1)
                fputs("set $mod Mod1\n", ks_config);
            else fputs("set $mod Mod4\n", ks_config);
            continue;
        }

        /* Check for 'bindcode'. If it’s not a bindcode line, we
         * just copy it to the output file */
        if (strncmp(walk, "bindcode", strlen("bindcode")) != 0) {
            fputs(walk, ks_config);
            continue;
        }
        char *result = rewrite_binding(walk);
        fputs(result, ks_config);
        free(result);
    }

    /* sync to do our best in order to have the file really stored on disk */
    fflush(ks_config);
    fsync(fileno(ks_config));

#ifndef USE_FGETLN
    free(line);
#endif

    fclose(kc_config);
    fclose(ks_config);

    /* tell i3 to reload the config file */
    int sockfd = ipc_connect(socket_path);
    ipc_send_message(sockfd, strlen("reload"), 0, (uint8_t*)"reload");
    close(sockfd);

    exit(0);
}

int main(int argc, char *argv[]) {
    config_path = resolve_tilde("~/.i3/config");
    socket_path = getenv("I3SOCK");
    char *pattern = "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
    char *patternbold = "-misc-fixed-bold-r-normal--13-120-75-75-C-70-iso10646-1";
    int o, option_index = 0;

    static struct option long_options[] = {
        {"socket", required_argument, 0, 's'},
        {"version", no_argument, 0, 'v'},
        {"limit", required_argument, 0, 'l'},
        {"prompt", required_argument, 0, 'P'},
        {"prefix", required_argument, 0, 'p'},
        {"font", required_argument, 0, 'f'},
        {"help", no_argument, 0, 'h'},
        {0, 0, 0, 0}
    };

    char *options_string = "s:vh";

    while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
        switch (o) {
            case 's':
                FREE(socket_path);
                socket_path = strdup(optarg);
                break;
            case 'v':
                printf("i3-config-wizard " I3_VERSION "\n");
                return 0;
            case 'h':
                printf("i3-config-wizard " I3_VERSION "\n");
                printf("i3-config-wizard [-s <socket>] [-v]\n");
                return 0;
        }
    }

    /* Check if the destination config file does not exist but the path is
     * writable. If not, exit now, this program is not useful in that case. */
    struct stat stbuf;
    if (stat(config_path, &stbuf) == 0) {
        printf("The config file \"%s\" already exists. Exiting.\n", config_path);
        return 0;
    }

    /* Create ~/.i3 if it does not yet exist */
    char *config_dir = resolve_tilde("~/.i3");
    if (stat(config_dir, &stbuf) != 0)
        if (mkdir(config_dir, 0755) == -1)
            err(1, "mkdir(%s) failed", config_dir);
    free(config_dir);

    int fd;
    if ((fd = open(config_path, O_CREAT | O_RDWR, 0644)) == -1) {
        printf("Cannot open file \"%s\" for writing: %s. Exiting.\n", config_path, strerror(errno));
        return 0;
    }
    close(fd);
    unlink(config_path);

    if (socket_path == NULL)
        socket_path = root_atom_contents("I3_SOCKET_PATH");

    if (socket_path == NULL)
        socket_path = "/tmp/i3-ipc.sock";

    int screens;
    if ((conn = xcb_connect(NULL, &screens)) == NULL ||
        xcb_connection_has_error(conn))
        errx(1, "Cannot open display\n");

    xcb_get_modifier_mapping_cookie_t modmap_cookie;
    modmap_cookie = xcb_get_modifier_mapping(conn);
    symbols = xcb_key_symbols_alloc(conn);

    /* Place requests for the atoms we need as soon as possible */
    #define xmacro(atom) \
        xcb_intern_atom_cookie_t atom ## _cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom);
    #include "atoms.xmacro"
    #undef xmacro

    root_screen = xcb_aux_get_screen(conn, screens);
    root = root_screen->root;

    if (!(modmap_reply = xcb_get_modifier_mapping_reply(conn, modmap_cookie, NULL)))
        errx(EXIT_FAILURE, "Could not get modifier mapping\n");

    xcb_numlock_mask = get_mod_mask_for(XCB_NUM_LOCK, symbols, modmap_reply);

    font = load_font(pattern, true);
    bold_font = load_font(patternbold, true);

    /* Open an input window */
    win = xcb_generate_id(conn);
    xcb_create_window(
        conn,
        XCB_COPY_FROM_PARENT,
        win, /* the window id */
        root, /* parent == root */
        490, 297, 300, 205, /* dimensions */
        0, /* X11 border = 0, we draw our own */
        XCB_WINDOW_CLASS_INPUT_OUTPUT,
        XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */
        XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK,
        (uint32_t[]){
            0, /* back pixel: black */
            XCB_EVENT_MASK_EXPOSURE |
            XCB_EVENT_MASK_BUTTON_PRESS
        });

    /* Map the window (make it visible) */
    xcb_map_window(conn, win);

    /* Setup NetWM atoms */
    #define xmacro(name) \
        do { \
            xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name ## _cookie, NULL); \
            if (!reply) \
                errx(EXIT_FAILURE, "Could not get atom " # name "\n"); \
            \
            A_ ## name = reply->atom; \
            free(reply); \
        } while (0);
    #include "atoms.xmacro"
    #undef xmacro

    /* Set dock mode */
    xcb_change_property(conn,
        XCB_PROP_MODE_REPLACE,
        win,
        A__NET_WM_WINDOW_TYPE,
        A_ATOM,
        32,
        1,
        (unsigned char*) &A__NET_WM_WINDOW_TYPE_DIALOG);

    /* Set window title */
    xcb_change_property(conn,
        XCB_PROP_MODE_REPLACE,
        win,
        A__NET_WM_NAME,
        A_UTF8_STRING,
        8,
        strlen("i3: first configuration"),
        "i3: first configuration");

    /* Create pixmap */
    pixmap = xcb_generate_id(conn);
    pixmap_gc = xcb_generate_id(conn);
    xcb_create_pixmap(conn, root_screen->root_depth, pixmap, win, 500, 500);
    xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0);

    /* Grab the keyboard to get all input */
    xcb_flush(conn);

    /* Try (repeatedly, if necessary) to grab the keyboard. We might not
     * get the keyboard at the first attempt because of the keybinding
     * still being active when started via a wm’s keybinding. */
    xcb_grab_keyboard_cookie_t cookie;
    xcb_grab_keyboard_reply_t *reply = NULL;

    int count = 0;
    while ((reply == NULL || reply->status != XCB_GRAB_STATUS_SUCCESS) && (count++ < 500)) {
        cookie = xcb_grab_keyboard(conn, false, win, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
        reply = xcb_grab_keyboard_reply(conn, cookie, NULL);
        usleep(1000);
    }

    if (reply->status != XCB_GRAB_STATUS_SUCCESS) {
        fprintf(stderr, "Could not grab keyboard, status = %d\n", reply->status);
        exit(-1);
    }

    xcb_flush(conn);

    xcb_generic_event_t *event;
    while ((event = xcb_wait_for_event(conn)) != NULL) {
        if (event->response_type == 0) {
            fprintf(stderr, "X11 Error received! sequence %x\n", event->sequence);
            continue;
        }

        /* Strip off the highest bit (set if the event is generated) */
        int type = (event->response_type & 0x7F);

        switch (type) {
            case XCB_KEY_PRESS:
                handle_key_press(NULL, conn, (xcb_key_press_event_t*)event);
                break;

            /* TODO: handle mappingnotify */

            case XCB_BUTTON_PRESS:
                handle_button_press((xcb_button_press_event_t*)event);
                break;

            case XCB_EXPOSE:
                handle_expose();
                break;
        }

        free(event);
    }

    return 0;
}
Exemple #17
0
// ===== startSystemTray() =====
WId LXCB::startSystemTray(int screen){
  qDebug() << "Starting System Tray:" << screen;
  //Setup the freedesktop standards compliance
  
  //Get the appropriate atom for this screen
  QString str = QString("_NET_SYSTEM_TRAY_S%1").arg(QString::number(screen));
  //qDebug() << "Default Screen Atom Name:" << str;
  xcb_intern_atom_reply_t *treply = xcb_intern_atom_reply(QX11Info::connection(), \
			xcb_intern_atom(QX11Info::connection(), 0, str.length(), str.toLocal8Bit()), NULL);
  xcb_intern_atom_reply_t *oreply = xcb_intern_atom_reply(QX11Info::connection(), \
			xcb_intern_atom(QX11Info::connection(), 0, 28, "_NET_SYSTEM_TRAY_ORIENTATION"), NULL);  
  xcb_intern_atom_reply_t *vreply = xcb_intern_atom_reply(QX11Info::connection(), \
			xcb_intern_atom(QX11Info::connection(), 0, 23, "_NET_SYSTEM_TRAY_VISUAL"), NULL);  
  if(treply==0){
    qDebug() << " - ERROR: Could not initialize _NET_SYSTEM_TRAY_S<num> atom";
    return 0;
  }
  if(oreply==0){
    qDebug() << " - ERROR: Could not initialize _NET_SYSTEM_TRAY_ORIENTATION atom";
    return 0;	  
  }
  if(vreply==0){
    qDebug() << " - ERROR: Could not initialize _NET_SYSTEM_TRAY_VISUAL atom";
    return 0;	  
  }
  xcb_atom_t _NET_SYSTEM_TRAY_S = treply->atom;
  xcb_atom_t _NET_SYSTEM_TRAY_ORIENTATION = oreply->atom;
  xcb_atom_t _NET_SYSTEM_TRAY_VISUAL = vreply->atom;
  free(treply); //done with atom generation
  free(oreply);
  free(vreply);
  
  //Make sure that there is no other system tray running
  xcb_get_selection_owner_reply_t *ownreply = xcb_get_selection_owner_reply(QX11Info::connection(), \
						xcb_get_selection_owner_unchecked(QX11Info::connection(), _NET_SYSTEM_TRAY_S), NULL);
  if(ownreply==0){
    qWarning() << " - Could not get owner selection reply";
    return 0;
  }
  if(ownreply->owner != 0){
    free(ownreply);
    qWarning() << " - An alternate system tray is currently in use";
    return 0;
  }
  free(ownreply);
  
  //Create a simple window to register as the tray (not visible - just off the screen)
  xcb_screen_t *root_screen = xcb_aux_get_screen(QX11Info::connection(), QX11Info::appScreen());
  uint32_t params[] = {1};
  WId LuminaSessionTrayID = xcb_generate_id(QX11Info::connection()); //need a new ID
    xcb_create_window(QX11Info::connection(), root_screen->root_depth, \
		LuminaSessionTrayID, root_screen->root, -1, -1, 1, 1, 0, \
		XCB_WINDOW_CLASS_INPUT_OUTPUT, root_screen->root_visual, \
		XCB_CW_OVERRIDE_REDIRECT, params);
		
  //Now register this widget as the system tray
  xcb_set_selection_owner(QX11Info::connection(), LuminaSessionTrayID, _NET_SYSTEM_TRAY_S, XCB_CURRENT_TIME);
  //Make sure that it was registered properly
  ownreply = xcb_get_selection_owner_reply(QX11Info::connection(), \
						xcb_get_selection_owner_unchecked(QX11Info::connection(), _NET_SYSTEM_TRAY_S), NULL);
  
  if(ownreply==0 || ownreply->owner != LuminaSessionTrayID){
    if(ownreply!=0){ free(ownreply); }
    qWarning() << " - Could not register the system tray";
    xcb_destroy_window(QX11Info::connection(), LuminaSessionTrayID);
    return 0;
  }
  free(ownreply); //done with structure
  
  //Now register the orientation of the system tray
  uint32_t orient = _NET_SYSTEM_TRAY_ORIENTATION_HORZ;
   xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, LuminaSessionTrayID, \
			_NET_SYSTEM_TRAY_ORIENTATION, XCB_ATOM_CARDINAL, 32, 1, &orient);

  //Now set the visual ID for the system tray (same as the root window, but TrueColor)
    xcb_visualtype_t *type = xcb_aux_find_visual_by_attrs(root_screen, XCB_VISUAL_CLASS_TRUE_COLOR, 32);
    if(type!=0){
      xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, LuminaSessionTrayID, \
	  _NET_SYSTEM_TRAY_VISUAL, XCB_ATOM_VISUALID, 32, 1, &type->visual_id);	    
    }else{
      qWarning() << " - Could not set TrueColor visual for system tray";
    }
  
  //Finally, send out an X event letting others know that the system tray is up and running
   xcb_client_message_event_t event;
    event.response_type = XCB_CLIENT_MESSAGE;
    event.format = 32;
    event.window = root_screen->root;
    event.type = EWMH.MANAGER; //MANAGER atom
    event.data.data32[0] = XCB_TIME_CURRENT_TIME; //CurrentTime;  
    event.data.data32[1] = _NET_SYSTEM_TRAY_S; //_NET_SYSTEM_TRAY_S atom
    event.data.data32[2] = LuminaSessionTrayID;
    event.data.data32[3] = 0;
    event.data.data32[4] = 0;

    xcb_send_event(QX11Info::connection(), 0, root_screen->root,  XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event);
  
  //Success
  return LuminaSessionTrayID;
}
Exemple #18
0
/** 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;
}