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; }
/* 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); }