struct client * client_create(int x, int y, int width, int height) { struct client *client; struct surface *surface; wl_log_set_handler_client(log_handler); /* connect to display */ client = xzalloc(sizeof *client); client->wl_display = wl_display_connect(NULL); assert(client->wl_display); wl_list_init(&client->global_list); /* setup registry so we can bind to interfaces */ client->wl_registry = wl_display_get_registry(client->wl_display); wl_registry_add_listener(client->wl_registry, ®istry_listener, client); /* trigger global listener */ wl_display_dispatch(client->wl_display); wl_display_roundtrip(client->wl_display); /* must have WL_SHM_FORMAT_ARGB32 */ assert(client->has_argb); /* must have wl_test interface */ assert(client->test); /* must have an output */ assert(client->output); /* initialize the client surface */ surface = xzalloc(sizeof *surface); surface->wl_surface = wl_compositor_create_surface(client->wl_compositor); assert(surface->wl_surface); wl_surface_add_listener(surface->wl_surface, &surface_listener, surface); client->surface = surface; wl_surface_set_user_data(surface->wl_surface, surface); surface->width = width; surface->height = height; surface->wl_buffer = create_shm_buffer(client, width, height, &surface->data); memset(surface->data, 64, width * height * 4); move_client(client, x, y); return client; }
static void check_client_move(struct client *client, int x, int y) { move_client(client, x, y); if (output_contains_client(client)) { assert(client->surface->output == client->output); } else { assert(client->surface->output == NULL); } }
void track_pointer(coordinates_t loc, pointer_action_t pac, xcb_point_t pos) { node_t *n = loc.node; resize_handle_t rh = get_handle(loc.node, pos, pac); uint16_t last_motion_x = pos.x, last_motion_y = pos.y; xcb_timestamp_t last_motion_time = 0; xcb_generic_event_t *evt = NULL; grabbing = true; grabbed_node = n; do { free(evt); while ((evt = xcb_wait_for_event(dpy)) == NULL) { xcb_flush(dpy); } uint8_t resp_type = XCB_EVENT_RESPONSE_TYPE(evt); if (resp_type == XCB_MOTION_NOTIFY) { xcb_motion_notify_event_t *e = (xcb_motion_notify_event_t*) evt; uint32_t dtime = e->time - last_motion_time; if (dtime < pointer_motion_interval) { continue; } last_motion_time = e->time; int16_t dx = e->root_x - last_motion_x; int16_t dy = e->root_y - last_motion_y; if (pac == ACTION_MOVE) { move_client(&loc, dx, dy); } else { resize_client(&loc, rh, e->root_x, e->root_y, false); } last_motion_x = e->root_x; last_motion_y = e->root_y; xcb_flush(dpy); } else if (resp_type == XCB_BUTTON_RELEASE) { grabbing = false; } else { handle_event(evt); } } while (grabbing && grabbed_node != NULL); free(evt); xcb_ungrab_pointer(dpy, XCB_CURRENT_TIME); if (grabbed_node == NULL) { grabbing = false; return; } if (pac == ACTION_MOVE) { put_status(SBSC_MASK_POINTER_ACTION, "pointer_action 0x%08X 0x%08X 0x%08X move end\n", loc.monitor->id, loc.desktop->id, n->id); } else if (pac == ACTION_RESIZE_CORNER) { put_status(SBSC_MASK_POINTER_ACTION, "pointer_action 0x%08X 0x%08X 0x%08X resize_corner end\n", loc.monitor->id, loc.desktop->id, n->id); } else if (pac == ACTION_RESIZE_SIDE) { put_status(SBSC_MASK_POINTER_ACTION, "pointer_action 0x%08X 0x%08X 0x%08X resize_side end\n", loc.monitor->id, loc.desktop->id, n->id); } xcb_rectangle_t r = get_rectangle(NULL, NULL, n); put_status(SBSC_MASK_NODE_GEOMETRY, "node_geometry 0x%08X 0x%08X 0x%08X %ux%u+%i+%i\n", loc.monitor->id, loc.desktop->id, loc.node->id, r.width, r.height, r.x, r.y); if ((pac == ACTION_MOVE && IS_TILED(n->client)) || ((pac == ACTION_RESIZE_CORNER || pac == ACTION_RESIZE_SIDE) && n->client->state == STATE_TILED)) { for (node_t *f = first_extrema(loc.desktop->root); f != NULL; f = next_leaf(f, loc.desktop->root)) { if (f == n || f->client == NULL || !IS_TILED(f->client)) { continue; } xcb_rectangle_t r = f->client->tiled_rectangle; put_status(SBSC_MASK_NODE_GEOMETRY, "node_geometry 0x%08X 0x%08X 0x%08X %ux%u+%i+%i\n", loc.monitor->id, loc.desktop->id, f->id, r.width, r.height, r.x, r.y); } } }