diff --git a/clients/window.c b/clients/window.c index e4b5d0d5..e8e3508d 100644 --- a/clients/window.c +++ b/clients/window.c @@ -1163,52 +1163,44 @@ get_pointer_location(struct window *window, int32_t x, int32_t y) return location; } -void -input_set_pointer_image(struct input *input, uint32_t time, int pointer) +static int +input_get_pointer_image_for_location(struct input *input, int pointer) { - struct display *display = input->display; - struct wl_buffer *buffer; - cairo_surface_t *surface; int location; location = get_pointer_location(input->pointer_focus, input->sx, input->sy); switch (location) { case WINDOW_RESIZING_TOP: - pointer = POINTER_TOP; - break; + return POINTER_TOP; case WINDOW_RESIZING_BOTTOM: - pointer = POINTER_BOTTOM; - break; + return POINTER_BOTTOM; case WINDOW_RESIZING_LEFT: - pointer = POINTER_LEFT; - break; + return POINTER_LEFT; case WINDOW_RESIZING_RIGHT: - pointer = POINTER_RIGHT; - break; + return POINTER_RIGHT; case WINDOW_RESIZING_TOP_LEFT: - pointer = POINTER_TOP_LEFT; - break; + return POINTER_TOP_LEFT; case WINDOW_RESIZING_TOP_RIGHT: - pointer = POINTER_TOP_RIGHT; - break; + return POINTER_TOP_RIGHT; case WINDOW_RESIZING_BOTTOM_LEFT: - pointer = POINTER_BOTTOM_LEFT; - break; + return POINTER_BOTTOM_LEFT; case WINDOW_RESIZING_BOTTOM_RIGHT: - pointer = POINTER_BOTTOM_RIGHT; - break; + return POINTER_BOTTOM_RIGHT; case WINDOW_EXTERIOR: case WINDOW_TITLEBAR: - if (input->current_pointer_image == POINTER_DEFAULT) - return; - - wl_input_device_attach(input->input_device, time, NULL, 0, 0); - input->current_pointer_image = POINTER_DEFAULT; - return; + return POINTER_LEFT_PTR; default: - break; + return pointer; } +} + +void +input_set_pointer_image(struct input *input, uint32_t time, int pointer) +{ + struct display *display = input->display; + struct wl_buffer *buffer; + cairo_surface_t *surface; if (pointer == input->current_pointer_image) return; @@ -1264,6 +1256,7 @@ window_handle_motion(void *data, struct wl_input_device *input_device, x, y, sx, sy, window->user_data); + pointer = input_get_pointer_image_for_location(input, pointer); input_set_pointer_image(input, time, pointer); } @@ -1288,6 +1281,7 @@ window_handle_button(void *data, case WINDOW_TITLEBAR: if (!window->shell_surface) break; + input_set_pointer_image(input, time, POINTER_DRAGGING); wl_shell_surface_move(window->shell_surface, input_device, time); break; @@ -1399,6 +1393,7 @@ window_handle_pointer_focus(void *data, item = window_find_item(window, x, y); window_set_focus_item(window, item); + pointer = input_get_pointer_image_for_location(input, pointer); input_set_pointer_image(input, time, pointer); } } diff --git a/compositor/compositor.c b/compositor/compositor.c index 12678fde..220f51ca 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -423,128 +423,6 @@ wlsc_buffer_attach(struct wl_buffer *buffer, struct wl_surface *surface) } } -static void -wlsc_sprite_attach(struct wlsc_sprite *sprite, struct wl_surface *surface) -{ - struct wlsc_surface *es = (struct wlsc_surface *) surface; - struct wlsc_compositor *ec = es->compositor; - - es->pitch = sprite->width; - es->image = sprite->image; - if (sprite->image != EGL_NO_IMAGE_KHR) { - glBindTexture(GL_TEXTURE_2D, es->texture); - ec->image_target_texture_2d(GL_TEXTURE_2D, es->image); - } else { - if (es->saved_texture == 0) - es->saved_texture = es->texture; - es->texture = sprite->texture; - } - - es->visual = sprite->visual; - - if (es->buffer) - es->buffer = NULL; -} - -enum sprite_usage { - SPRITE_USE_CURSOR = (1 << 0), -}; - -static struct wlsc_sprite * -create_sprite_from_png(struct wlsc_compositor *ec, - const char *filename, uint32_t usage) -{ - uint32_t *pixels, *pad; - struct wlsc_sprite *sprite; - int32_t width, height; - uint32_t stride; - - pixels = wlsc_load_image(filename, &width, &height, &stride); - if (pixels == NULL) - return NULL; - - sprite = malloc(sizeof *sprite); - if (sprite == NULL) { - free(pixels); - return NULL; - } - - sprite->visual = WLSC_PREMUL_ARGB_VISUAL; - sprite->width = width; - sprite->height = height; - sprite->image = EGL_NO_IMAGE_KHR; - - glGenTextures(1, &sprite->texture); - glBindTexture(GL_TEXTURE_2D, sprite->texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - if (usage & SPRITE_USE_CURSOR && ec->create_cursor_image != NULL) { - sprite->image = ec->create_cursor_image(ec, &sprite->width, - &sprite->height); - - ec->image_target_texture_2d(GL_TEXTURE_2D, sprite->image); - - if (sprite->width > width || sprite->height > height) { - pad = calloc(sprite->width * sprite->height, - sizeof *pad); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, - sprite->width, sprite->height, - GL_BGRA_EXT, GL_UNSIGNED_BYTE, pad); - free(pad); - } - - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, - GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels); - - } else { - glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, width, height, 0, - GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels); - } - - free(pixels); - - return sprite; -} - -static const struct { - const char *filename; - int hotspot_x, hotspot_y; -} pointer_images[] = { - { DATADIR "/wayland/bottom_left_corner.png", 6, 30 }, - { DATADIR "/wayland/bottom_right_corner.png", 28, 28 }, - { DATADIR "/wayland/bottom_side.png", 16, 20 }, - { DATADIR "/wayland/grabbing.png", 20, 17 }, - { DATADIR "/wayland/left_ptr.png", 10, 5 }, - { DATADIR "/wayland/left_side.png", 10, 20 }, - { DATADIR "/wayland/right_side.png", 30, 19 }, - { DATADIR "/wayland/top_left_corner.png", 8, 8 }, - { DATADIR "/wayland/top_right_corner.png", 26, 8 }, - { DATADIR "/wayland/top_side.png", 18, 8 }, - { DATADIR "/wayland/xterm.png", 15, 15 } -}; - -static void -create_pointer_images(struct wlsc_compositor *ec) -{ - int i, count; - - count = ARRAY_LENGTH(pointer_images); - ec->pointer_sprites = malloc(count * sizeof *ec->pointer_sprites); - for (i = 0; i < count; i++) { - ec->pointer_sprites[i] = - create_sprite_from_png(ec, - pointer_images[i].filename, - SPRITE_USE_CURSOR); - if (!ec->pointer_sprites[i]) { - fprintf(stderr, "Error loading pointer image: %s\n", - pointer_images[i].filename); - } - } -} - static int texture_region(struct wlsc_surface *es, pixman_region32_t *region) { @@ -801,6 +679,9 @@ wlsc_output_set_cursor(struct wlsc_output *output, pixman_region32_t cursor_region; int use_hardware_cursor = 1, prior_was_hardware; + if (device->sprite == NULL) + return; + pixman_region32_init_rect(&cursor_region, device->sprite->x, device->sprite->y, device->sprite->width, @@ -1145,54 +1026,6 @@ const static struct wl_surface_interface surface_interface = { surface_frame }; -static void -wlsc_input_device_attach(struct wlsc_input_device *device, - int x, int y, int width, int height) -{ - wlsc_surface_damage_below(device->sprite); - - device->hotspot_x = x; - device->hotspot_y = y; - - device->sprite->x = device->input_device.x - device->hotspot_x; - device->sprite->y = device->input_device.y - device->hotspot_y; - device->sprite->width = width; - device->sprite->height = height; - - wlsc_surface_damage(device->sprite); -} - -static void -wlsc_input_device_attach_buffer(struct wlsc_input_device *device, - struct wl_buffer *buffer, int x, int y) -{ - wlsc_buffer_attach(buffer, &device->sprite->surface); - wlsc_input_device_attach(device, x, y, buffer->width, buffer->height); -} - -static void -wlsc_input_device_attach_sprite(struct wlsc_input_device *device, - struct wlsc_sprite *sprite, int x, int y) -{ - if (!sprite) - return; - - wlsc_sprite_attach(sprite, &device->sprite->surface); - wlsc_input_device_attach(device, x, y, sprite->width, sprite->height); -} - -WL_EXPORT void -wlsc_input_device_set_pointer_image(struct wlsc_input_device *device, - enum wlsc_pointer_type type) -{ - struct wlsc_compositor *compositor = device->compositor; - - wlsc_input_device_attach_sprite(device, - compositor->pointer_sprites[type], - pointer_images[type].hotspot_x, - pointer_images[type].hotspot_y); -} - static void compositor_create_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id) @@ -1401,12 +1234,14 @@ notify_motion(struct wl_input_device *device, uint32_t time, int x, int y) time, x, y, sx, sy); } - wlsc_surface_damage_below(wd->sprite); + if (wd->sprite) { + wlsc_surface_damage_below(wd->sprite); - wd->sprite->x = device->x - wd->hotspot_x; - wd->sprite->y = device->y - wd->hotspot_y; + wd->sprite->x = device->x - wd->hotspot_x; + wd->sprite->y = device->y - wd->hotspot_y; - wlsc_surface_damage(wd->sprite); + wlsc_surface_damage(wd->sprite); + } } WL_EXPORT void @@ -1604,16 +1439,11 @@ notify_pointer_focus(struct wl_input_device *device, time, x, y, sx, sy); compositor->focus = 1; - - wd->sprite->x = device->x - wd->hotspot_x; - wd->sprite->y = device->y - wd->hotspot_y; } else { wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0); compositor->focus = 0; } - - wlsc_surface_damage(wd->sprite); } WL_EXPORT void @@ -1664,25 +1494,44 @@ input_device_attach(struct wl_client *client, struct wl_resource *buffer_resource, int32_t x, int32_t y) { struct wlsc_input_device *device = resource->data; + struct wlsc_compositor *compositor = device->compositor; struct wl_buffer *buffer; if (time < device->input_device.pointer_focus_time) return; -#if 0 if (device->input_device.pointer_focus == NULL) return; if (device->input_device.pointer_focus->resource.client != client) return; -#endif - if (buffer_resource) { - buffer = buffer_resource->data; - wlsc_input_device_attach_buffer(device, buffer, x, y); - } else { - wlsc_input_device_set_pointer_image(device, - WLSC_POINTER_LEFT_PTR); + if (device->sprite) + wlsc_surface_damage_below(device->sprite); + + if (!buffer_resource) { + destroy_surface(&device->sprite->surface.resource); + device->sprite = NULL; return; } + + if (!device->sprite) { + device->sprite = + wlsc_surface_create(compositor, + device->input_device.x, + device->input_device.y, 32, 32); + wl_list_init(&device->sprite->link); + } + + buffer = buffer_resource->data; + wlsc_buffer_attach(buffer, &device->sprite->surface); + + device->hotspot_x = x; + device->hotspot_y = y; + device->sprite->width = buffer->width; + device->sprite->height = buffer->height; + device->sprite->x = device->input_device.x - device->hotspot_x; + device->sprite->y = device->input_device.y - device->hotspot_y; + + wlsc_surface_damage(device->sprite); } const static struct wl_input_device_interface input_device_interface = { @@ -1718,10 +1567,7 @@ wlsc_input_device_init(struct wlsc_input_device *device, wl_display_add_global(ec->wl_display, &wl_input_device_interface, device, bind_input_device); - device->sprite = wlsc_surface_create(ec, - device->input_device.x, - device->input_device.y, 32, 32); - wl_list_insert(&ec->surface_list, &device->sprite->link); + device->sprite = NULL; device->compositor = ec; device->hotspot_x = 16; @@ -1732,7 +1578,6 @@ wlsc_input_device_init(struct wlsc_input_device *device, wl_list_insert(ec->input_device_list.prev, &device->link); - wlsc_input_device_set_pointer_image(device, WLSC_POINTER_LEFT_PTR); device->selection_data_source = NULL; } @@ -2051,8 +1896,6 @@ wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display) MODIFIER_CTRL | MODIFIER_ALT, terminate_binding, ec); - create_pointer_images(ec); - screenshooter_create(ec); wlsc_data_device_manager_init(ec); diff --git a/compositor/compositor.h b/compositor/compositor.h index 3c88807e..cbcbcfce 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -96,20 +96,6 @@ struct wlsc_output { void (*destroy)(struct wlsc_output *output); }; -enum wlsc_pointer_type { - WLSC_POINTER_BOTTOM_LEFT, - WLSC_POINTER_BOTTOM_RIGHT, - WLSC_POINTER_BOTTOM, - WLSC_POINTER_DRAGGING, - WLSC_POINTER_LEFT_PTR, - WLSC_POINTER_LEFT, - WLSC_POINTER_RIGHT, - WLSC_POINTER_TOP_LEFT, - WLSC_POINTER_TOP_RIGHT, - WLSC_POINTER_TOP, - WLSC_POINTER_IBEAM, -}; - struct wlsc_input_device { struct wl_input_device input_device; struct wlsc_compositor *compositor; @@ -137,14 +123,6 @@ enum wlsc_visual { WLSC_RGB_VISUAL }; -struct wlsc_sprite { - GLuint texture; - EGLImageKHR image; - uint32_t visual; - int width; - int height; -}; - struct wlsc_shader { GLuint program; GLuint vertex_shader, fragment_shader; @@ -196,7 +174,6 @@ struct wlsc_compositor { EGLConfig config; GLuint fbo; GLuint proj_uniform, tex_uniform; - struct wlsc_sprite **pointer_sprites; struct wlsc_shader texture_shader; struct wlsc_shader solid_shader; struct wl_display *wl_display; @@ -368,9 +345,6 @@ wlsc_surface_damage_rectangle(struct wlsc_surface *surface, int32_t x, int32_t y, int32_t width, int32_t height); -void -wlsc_input_device_set_pointer_image(struct wlsc_input_device *device, - enum wlsc_pointer_type type); struct wlsc_surface * pick_surface(struct wl_input_device *device, int32_t *sx, int32_t *sy); diff --git a/compositor/shell.c b/compositor/shell.c index bb6db32f..9035eb20 100644 --- a/compositor/shell.c +++ b/compositor/shell.c @@ -174,7 +174,6 @@ wlsc_surface_move(struct wlsc_surface *es, &move->grab, &es->surface, time) < 0) return 0; - wlsc_input_device_set_pointer_image(wd, WLSC_POINTER_DRAGGING); wl_input_device_set_pointer_focus(&wd->input_device, NULL, time, 0, 0, 0, 0); @@ -253,7 +252,6 @@ wlsc_surface_resize(struct shell_surface *shsurf, { struct wlsc_resize_grab *resize; struct wlsc_surface *es = shsurf->surface; - enum wlsc_pointer_type pointer = WLSC_POINTER_LEFT_PTR; /* FIXME: Reject if fullscreen */ @@ -273,38 +271,10 @@ wlsc_surface_resize(struct shell_surface *shsurf, (edges & 3) == 3 || (edges & 12) == 12) return 0; - switch (edges) { - case WL_SHELL_SURFACE_RESIZE_TOP: - pointer = WLSC_POINTER_TOP; - break; - case WL_SHELL_SURFACE_RESIZE_BOTTOM: - pointer = WLSC_POINTER_BOTTOM; - break; - case WL_SHELL_SURFACE_RESIZE_LEFT: - pointer = WLSC_POINTER_LEFT; - break; - case WL_SHELL_SURFACE_RESIZE_TOP_LEFT: - pointer = WLSC_POINTER_TOP_LEFT; - break; - case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT: - pointer = WLSC_POINTER_BOTTOM_LEFT; - break; - case WL_SHELL_SURFACE_RESIZE_RIGHT: - pointer = WLSC_POINTER_RIGHT; - break; - case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT: - pointer = WLSC_POINTER_TOP_RIGHT; - break; - case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT: - pointer = WLSC_POINTER_BOTTOM_RIGHT; - break; - } - if (wl_input_device_update_grab(&wd->input_device, &resize->grab, &es->surface, time) < 0) return 0; - wlsc_input_device_set_pointer_image(wd, pointer); wl_input_device_set_pointer_focus(&wd->input_device, NULL, time, 0, 0, 0, 0);