static xcb_window_t make_window(xcb_connection_t *c,
				xcb_screen_t *s,
				uint32_t bg,
				uint32_t fg,
				uint32_t width,
				uint32_t height) {
    uint32_t mask = 0;
    xcb_params_cw_t cwa;
    xcb_window_t w;
    xcb_void_cookie_t check_cookie;
    xcb_generic_error_t *error;
    xcb_visualtype_t *v = xcb_aux_find_visual_by_id(s, s->root_visual);
    assert(v);
    XCB_AUX_ADD_PARAM(&mask, &cwa, back_pixel, bg);
    XCB_AUX_ADD_PARAM(&mask, &cwa, border_pixel, fg);
    XCB_AUX_ADD_PARAM(&mask, &cwa, override_redirect, 1);
    XCB_AUX_ADD_PARAM(&mask, &cwa, event_mask,
		      XCB_EVENT_MASK_BUTTON_PRESS |
		      XCB_EVENT_MASK_EXPOSURE);
    w = xcb_generate_id(c);
    check_cookie = xcb_aux_create_window_checked(c,
      s->root_depth, w, s->root, 0, 0, width, height, 1,
      XCB_WINDOW_CLASS_INPUT_OUTPUT, v->visual_id, mask, &cwa);
    error = xcb_request_check(c, check_cookie);
    assert(!error);
    check_cookie = xcb_map_window_checked(c, w);
    error = xcb_request_check(c, check_cookie);
    assert(!error);
    return w;
}
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;
}
Ejemplo n.º 3
0
/* Prepare the stack of "exposed windows" and init the placing animation frames. */
static void _show() {
    uint8_t i;
    int rows, cols;
    int row_i, col_i;
    int row_cols;
    xcb_rectangle_t generic_cell, root_r;
    xcb_params_cw_t p;
    uint32_t m;
    _exposed_win_t *tmp_ew, *last_exp_win;
    fwm_mwin_t *tmp_man_win;
    _exposed_win_t **ordered_exp_wins;

    /* Get effects window and create buffer + picture. */
    if ((_this.win = fwm_composite_get_effects_window()) == XCB_NONE) {
        return; /* The effects window is busy! */
    }
    XCB_AUX_ADD_PARAM(&m, &p, event_mask, XCB_EVENT_MASK_BUTTON_PRESS);
    xcb_aux_change_window_attributes(gd.conn, _this.win, m, &p);
    _this.win_buffer = xcb_generate_id(gd.conn);
    xcb_create_pixmap(gd.conn, gd.def_screen->root_depth, _this.win_buffer, _this.win,
            gd.def_screen->width_in_pixels, gd.def_screen->height_in_pixels);
    _this.win_buffer_pic = fwm_render_create_picture(_this.win_buffer, XCB_NONE, NULL);

    root_r.x = root_r.y = 0;
    root_r.width = gd.def_screen->width_in_pixels;
    root_r.height = gd.def_screen->height_in_pixels;
    _clean_rect(&root_r);

    /* Decide how to place window thumbs. */
    _find_cells(gd.def_screen->height_in_pixels, gd.def_screen->width_in_pixels, gd.win_count, &rows, &cols);

    generic_cell.width = (gd.def_screen->width_in_pixels / cols) - 20;
    generic_cell.height = (gd.def_screen->height_in_pixels / rows) - 20;

    /* Start preparing exposed windows. */
    ordered_exp_wins = malloc(sizeof (_exposed_win_t *) * gd.win_count);
    tmp_man_win = gd.ws->top->next;
    last_exp_win = malloc(sizeof (_exposed_win_t));
    last_exp_win->managed_win = tmp_man_win;
    last_exp_win->prev = NULL;
    _this.bottom = last_exp_win;
    ordered_exp_wins[0] = last_exp_win;
    tmp_man_win = tmp_man_win->next;
    i = 1;
    while (tmp_man_win != gd.ws->top->next) {
        tmp_ew = malloc(sizeof (_exposed_win_t));
        tmp_ew->managed_win = tmp_man_win;
        tmp_ew->prev = last_exp_win;
        tmp_ew->next = NULL;
        last_exp_win->next = tmp_ew;
        last_exp_win = tmp_ew;
        ordered_exp_wins[i++] = tmp_ew;
        tmp_man_win = tmp_man_win->next;
    }
    _this.top = last_exp_win;
    qsort(ordered_exp_wins, gd.win_count, sizeof (_exposed_win_t *),
            _is_higher_than);

    col_i = row_i = 0;
    generic_cell.x = 0;
    for (row_i = 0; row_i < rows; row_i++) {
        /* Treats last line in a different way to center if it was not full. */
        if (row_i == rows - 1) {
            row_cols = gd.win_count - row_i * cols;
            if (row_cols < cols) {
                generic_cell.x = ((cols - row_cols) * generic_cell.width + 60) / 2;
            }
        } else {
            row_cols = cols;
        }
        qsort(&ordered_exp_wins[row_i * cols], row_cols, sizeof (_exposed_win_t *),
                _is_more_left_placed_than);
        for (col_i = 0; col_i < row_cols; col_i++) {
            _setup_exposed_win(ordered_exp_wins[row_i * cols + col_i],
                    generic_cell, col_i, row_i);
        }
    }
    free(ordered_exp_wins);
    xcb_flush(gd.conn);

    _this.state = _PLACING;
    _this.remaining_steps = _TRANS_FRAMES;
    for (i = 1; i < _TRANS_FRAMES; i++) {
        fwm_animan_append_action(_paint_place_step, NULL, i);
    }
    fwm_animan_append_action(_paint_final_place_step, NULL, i + 1);
}