static CoglandBuffer * cogland_buffer_from_resource (struct wl_resource *resource) { CoglandBuffer *buffer; struct wl_listener *listener; listener = wl_resource_get_destroy_listener (resource, cogland_buffer_destroy_handler); if (listener) { buffer = wl_container_of (listener, buffer, destroy_listener); } else { buffer = g_slice_new0 (CoglandBuffer); buffer->resource = resource; wl_signal_init (&buffer->destroy_signal); buffer->destroy_listener.notify = cogland_buffer_destroy_handler; wl_resource_add_destroy_listener (resource, &buffer->destroy_listener); } return buffer; }
static void set_selection(struct wl_client * client, struct wl_resource * resource, struct wl_resource * data_source, uint32_t serial) { struct data_device * data_device = wl_resource_get_user_data(resource); /* Check if this data source is already the current selection. */ if (data_source == data_device->selection) return; if (data_device->selection) { wl_data_source_send_cancelled(data_device->selection); wl_list_remove(&data_device->selection_destroy_listener.link); } data_device->selection = data_source; if (data_source) { wl_resource_add_destroy_listener (data_source, &data_device->selection_destroy_listener); } swc_send_event(&data_device->event_signal, DATA_DEVICE_EVENT_SELECTION_CHANGED, NULL); }
void wlb_keyboard_set_focus(struct wlb_keyboard *keyboard, struct wlb_surface *focus) { struct wl_resource *resource; uint32_t serial; if (keyboard->focus == focus) return; serial = wl_display_next_serial(keyboard->seat->compositor->display); if (keyboard->focus) { wl_resource_for_each(resource, &keyboard->resource_list) wl_keyboard_send_leave(resource, serial, keyboard->focus->resource); wl_list_remove(&keyboard->surface_destroy_listener.link); } keyboard->focus = focus; if (keyboard->focus) { wl_resource_add_destroy_listener(focus->resource, &keyboard->surface_destroy_listener); wl_resource_for_each(resource, &keyboard->resource_list) wl_keyboard_send_enter(resource, serial, keyboard->focus->resource, &keyboard->keys); } }
MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource) { MetaWaylandBuffer *buffer; struct wl_listener *listener; listener = wl_resource_get_destroy_listener (resource, meta_wayland_buffer_destroy_handler); if (listener) { buffer = wl_container_of (listener, buffer, destroy_listener); } else { buffer = g_object_new (META_TYPE_WAYLAND_BUFFER, NULL); buffer->resource = resource; buffer->destroy_listener.notify = meta_wayland_buffer_destroy_handler; wl_resource_add_destroy_listener (resource, &buffer->destroy_listener); } return buffer; }
static void pointer_set_cursor (struct wl_client *client, struct wl_resource *resource, uint32_t serial, struct wl_resource *surface_resource, int32_t x, int32_t y) { ClaylandSeat *seat = wl_resource_get_user_data (resource); ClaylandSurface *surface; surface = (surface_resource ? wl_resource_get_user_data (surface_resource) : NULL); if (seat->pointer.focus == NULL) return; if (wl_resource_get_client (seat->pointer.focus->resource) != client) return; if (seat->pointer.focus_serial - serial > G_MAXUINT32 / 2) return; pointer_unmap_sprite (seat); if (!surface) return; wl_resource_add_destroy_listener (surface->resource, &seat->sprite_destroy_listener); seat->sprite = surface; seat->hotspot_x = x; seat->hotspot_y = y; }
static void drag_grab_focus (MetaWaylandPointerGrab *grab, MetaWaylandSurface *surface) { MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab; MetaWaylandSeat *seat = drag_grab->seat; struct wl_client *client; struct wl_resource *data_device_resource, *offer = NULL; struct wl_display *display; guint32 serial; wl_fixed_t sx, sy; if (drag_grab->drag_focus == surface) return; if (drag_grab->drag_focus_data_device) { wl_data_device_send_leave (drag_grab->drag_focus_data_device); wl_list_remove (&drag_grab->drag_focus_listener.link); drag_grab->drag_focus_data_device = NULL; drag_grab->drag_focus = NULL; } if (!surface) return; if (!drag_grab->drag_data_source && wl_resource_get_client (surface->resource) != drag_grab->drag_client) return; client = wl_resource_get_client (surface->resource); data_device_resource = wl_resource_find_for_client (&seat->data_device.resource_list, client); if (!data_device_resource) return; display = wl_client_get_display (client); serial = wl_display_next_serial (display); if (drag_grab->drag_data_source) offer = meta_wayland_data_source_send_offer (drag_grab->drag_data_source, data_device_resource); meta_wayland_pointer_get_relative_coordinates (grab->pointer, surface, &sx, &sy); wl_data_device_send_enter (data_device_resource, serial, surface->resource, sx, sy, offer); drag_grab->drag_focus = surface; drag_grab->drag_focus_data_device = data_device_resource; drag_grab->drag_focus_listener.notify = destroy_drag_focus; wl_resource_add_destroy_listener (data_device_resource, &drag_grab->drag_focus_listener); }
static void weston_drag_set_focus(struct weston_drag *drag, struct weston_seat *seat, struct weston_view *view, wl_fixed_t sx, wl_fixed_t sy) { struct wl_resource *resource, *offer = NULL; struct wl_display *display = seat->compositor->wl_display; uint32_t serial; if (drag->focus && view && drag->focus->surface == view->surface) { drag->focus = view; return; } if (drag->focus_resource) { wl_data_device_send_leave(drag->focus_resource); wl_list_remove(&drag->focus_listener.link); drag->focus_resource = NULL; drag->focus = NULL; } if (!view || !view->surface->resource) return; if (!drag->data_source && wl_resource_get_client(view->surface->resource) != drag->client) return; resource = wl_resource_find_for_client(&seat->drag_resource_list, wl_resource_get_client(view->surface->resource)); if (!resource) return; serial = wl_display_next_serial(display); if (drag->data_source) { offer = weston_data_source_send_offer(drag->data_source, resource); if (offer == NULL) return; } wl_data_device_send_enter(resource, serial, view->surface->resource, sx, sy, offer); drag->focus = view; drag->focus_listener.notify = destroy_drag_focus; wl_resource_add_destroy_listener(resource, &drag->focus_listener); drag->focus_resource = resource; }
static void set_cursor_surface (MetaWaylandPointer *pointer, MetaWaylandSurface *surface) { if (pointer->cursor_surface == surface) return; if (pointer->cursor_surface) wl_list_remove (&pointer->cursor_surface_destroy_listener.link); pointer->cursor_surface = surface; if (pointer->cursor_surface) wl_resource_add_destroy_listener (pointer->cursor_surface->resource, &pointer->cursor_surface_destroy_listener); }
static void meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device, MetaWaylandDataSource *source, guint32 serial) { MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); struct wl_resource *data_device_resource, *offer; struct wl_client *focus_client; if (data_device->selection_data_source && data_device->selection_serial - serial < UINT32_MAX / 2) return; if (data_device->selection_data_source) { wl_data_source_send_cancelled (data_device->selection_data_source->resource); wl_list_remove (&data_device->selection_data_source_listener.link); data_device->selection_data_source = NULL; } data_device->selection_data_source = source; data_device->selection_serial = serial; focus_client = meta_wayland_keyboard_get_focus_client (&seat->keyboard); if (focus_client) { data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client); if (data_device_resource) { if (data_device->selection_data_source) { offer = meta_wayland_data_source_send_offer (data_device->selection_data_source, data_device_resource); wl_data_device_send_selection (data_device_resource, offer); } else { wl_data_device_send_selection (data_device_resource, NULL); } } } if (source) { data_device->selection_data_source_listener.notify = destroy_selection_data_source; wl_resource_add_destroy_listener (source->resource, &data_device->selection_data_source_listener); } }
static struct wl_resource * meta_wayland_data_source_send_offer (MetaWaylandDataSource *source, struct wl_resource *target) { MetaWaylandDataOffer *offer = g_slice_new0 (MetaWaylandDataOffer); char **p; offer->source = source; offer->source_destroy_listener.notify = destroy_offer_data_source; offer->resource = wl_resource_create (wl_resource_get_client (target), &wl_data_offer_interface, wl_resource_get_version (target), 0); wl_resource_set_implementation (offer->resource, &data_offer_interface, offer, destroy_data_offer); wl_resource_add_destroy_listener (source->resource, &offer->source_destroy_listener); wl_data_device_send_data_offer (target, offer->resource); wl_array_for_each (p, &source->mime_types) wl_data_offer_send_offer (offer->resource, *p); return offer->resource; }
struct xdg_popup * xdg_popup_new(struct wl_client *client, uint32_t version, uint32_t id, struct surface *surface, struct surface *parent_surface, int32_t x, int32_t y) { struct xdg_popup *popup; struct compositor_view *parent = compositor_view(parent_surface->view); if (!parent) goto error0; popup = malloc(sizeof *popup); if (!popup) goto error0; popup->resource = wl_resource_create(client, &xdg_popup_interface, version, id); if (!popup->resource) goto error1; popup->surface_destroy_listener.notify = &handle_surface_destroy; wl_resource_add_destroy_listener(surface->resource, &popup->surface_destroy_listener); wl_resource_set_implementation(popup->resource, &xdg_popup_implementation, popup, &destroy_popup); if (!(popup->view = compositor_create_view(surface))) goto error2; view_move(&popup->view->base, parent->base.geometry.x + x, parent->base.geometry.y + y); compositor_view_set_parent(popup->view, parent); return popup; error2: wl_resource_destroy(popup->resource); error1: free(popup); error0: return NULL; }
static void data_device_start_drag (struct wl_client *client, struct wl_resource *resource, struct wl_resource *source_resource, struct wl_resource *origin_resource, struct wl_resource *icon_resource, guint32 serial) { MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource); MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); MetaWaylandSurface *surface = NULL; MetaWaylandDragGrab *drag_grab; ClutterPoint pos; if (origin_resource) surface = wl_resource_get_user_data (origin_resource); if (!surface) return; if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || !seat->pointer.focus_surface || seat->pointer.focus_surface != surface) return; /* FIXME: Check that the data source type array isn't empty. */ if (data_device->current_grab || seat->pointer.grab != &seat->pointer.default_grab) return; data_device->current_grab = drag_grab = g_slice_new0 (MetaWaylandDragGrab); drag_grab->generic.interface = &drag_grab_interface; drag_grab->generic.pointer = &seat->pointer; drag_grab->drag_client = client; drag_grab->seat = seat; drag_grab->drag_origin = surface; drag_grab->drag_origin_listener.notify = destroy_data_device_origin; wl_resource_add_destroy_listener (origin_resource, &drag_grab->drag_origin_listener); clutter_input_device_get_coords (seat->pointer.device, NULL, &pos); clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)), pos.x, pos.y, &pos.x, &pos.y); drag_grab->drag_start_x = pos.x; drag_grab->drag_start_y = pos.y; if (source_resource) { drag_grab->drag_data_source = wl_resource_get_user_data (source_resource); drag_grab->drag_data_source_listener.notify = destroy_data_device_source; wl_resource_add_destroy_listener (source_resource, &drag_grab->drag_data_source_listener); } if (icon_resource) { drag_grab->drag_surface = wl_resource_get_user_data (icon_resource); drag_grab->drag_icon_listener.notify = destroy_data_device_icon; wl_resource_add_destroy_listener (icon_resource, &drag_grab->drag_icon_listener); drag_grab->feedback_actor = meta_dnd_actor_new (CLUTTER_ACTOR (drag_grab->drag_origin->surface_actor), drag_grab->drag_start_x, drag_grab->drag_start_y); meta_feedback_actor_set_anchor (META_FEEDBACK_ACTOR (drag_grab->feedback_actor), -drag_grab->drag_surface->offset_x, -drag_grab->drag_surface->offset_y); clutter_actor_add_child (drag_grab->feedback_actor, CLUTTER_ACTOR (drag_grab->drag_surface->surface_actor)); clutter_input_device_get_coords (seat->pointer.device, NULL, &pos); meta_feedback_actor_set_position (META_FEEDBACK_ACTOR (drag_grab->feedback_actor), pos.x, pos.y); } meta_wayland_pointer_set_focus (&seat->pointer, NULL); meta_wayland_pointer_start_grab (&seat->pointer, (MetaWaylandPointerGrab*)drag_grab); }
static void modify(struct screen_modifier * modifier, const struct swc_rectangle * geometry, pixman_region32_t * usable) { struct panel * panel = wl_container_of(modifier, panel, modifier); pixman_box32_t box = { .x1 = geometry->x, .y1 = geometry->y, .x2 = geometry->x + geometry->width, .y2 = geometry->y + geometry->height }; assert(panel->docked); DEBUG("Original geometry { x1: %d, y1: %d, x2: %d, y2: %d }\n", box.x1, box.y1, box.x2, box.y2); switch (panel->edge) { case SWC_PANEL_EDGE_TOP: box.y1 = MAX(box.y1, geometry->y + panel->strut_size); break; case SWC_PANEL_EDGE_BOTTOM: box.y2 = MIN(box.y2, geometry->y + geometry->height - panel->strut_size); break; case SWC_PANEL_EDGE_LEFT: box.x1 = MAX(box.x1, geometry->x + panel->strut_size); break; case SWC_PANEL_EDGE_RIGHT: box.x2 = MIN(box.x2, geometry->x + geometry->width - panel->strut_size); break; } DEBUG("Usable region { x1: %d, y1: %d, x2: %d, y2: %d }\n", box.x1, box.y1, box.x2, box.y2); pixman_region32_reset(usable, &box); } static void destroy_panel(struct wl_resource * resource) { struct panel * panel = wl_resource_get_user_data(resource); if (panel->docked) { wl_list_remove(&panel->modifier.link); screen_update_usable_geometry(panel->screen); } compositor_view_destroy(panel->view); free(panel); } static void handle_surface_destroy(struct wl_listener * listener, void * data) { struct panel * panel = wl_container_of(listener, panel, surface_destroy_listener); wl_resource_destroy(panel->resource); } struct panel * panel_new(struct wl_client * client, uint32_t version, uint32_t id, struct surface * surface) { struct panel * panel; panel = malloc(sizeof *panel); if (!panel) goto error0; panel->resource = wl_resource_create(client, &swc_panel_interface, version, id); if (!panel->resource) goto error1; if (!(panel->view = compositor_create_view(surface))) goto error2; wl_resource_set_implementation(panel->resource, &panel_implementation, panel, &destroy_panel); panel->surface_destroy_listener.notify = &handle_surface_destroy; panel->view_handler.impl = &view_handler_impl; panel->modifier.modify = &modify; panel->screen = NULL; panel->offset = 0; panel->strut_size = 0; panel->docked = false; wl_list_insert(&panel->view->base.handlers, &panel->view_handler.link); wl_resource_add_destroy_listener(surface->resource, &panel->surface_destroy_listener); return panel; error2: wl_resource_destroy(panel->resource); error1: free(panel); error0: return NULL; }
static void xdg_shell_get_xdg_popup (struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource, struct wl_resource *parent_resource, struct wl_resource *seat_resource, uint32_t serial, int32_t x, int32_t y) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); MetaWaylandPopupSurface *popup_surface; MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource); MetaWaylandSurface *top_popup; MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); MetaWindow *window; MetaDisplay *display = meta_get_display (); MetaWaylandXdgPopup *xdg_popup; MetaWaylandPopup *popup; if (META_IS_WAYLAND_XDG_POPUP (surface->role) && META_WAYLAND_XDG_POPUP (surface->role)->resource) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "xdg_shell::get_xdg_popup already requested"); return; } if (!meta_wayland_surface_assign_role (surface, META_TYPE_WAYLAND_XDG_POPUP)) { wl_resource_post_error (resource, XDG_SHELL_ERROR_ROLE, "wl_surface@%d already has a different role", wl_resource_get_id (surface->resource)); return; } if (parent_surf == NULL || parent_surf->window == NULL || (!META_IS_WAYLAND_XDG_POPUP (parent_surf->role) && !META_IS_WAYLAND_XDG_SURFACE (parent_surf->role))) { wl_resource_post_error (resource, XDG_SHELL_ERROR_INVALID_POPUP_PARENT, "invalid parent surface"); return; } top_popup = meta_wayland_pointer_get_top_popup (&seat->pointer); if ((top_popup == NULL && !META_IS_WAYLAND_XDG_SURFACE (parent_surf->role)) || (top_popup != NULL && parent_surf != top_popup)) { wl_resource_post_error (resource, XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP, "parent not top most surface"); return; } xdg_popup = META_WAYLAND_XDG_POPUP (surface->role); xdg_popup->resource = wl_resource_create (client, &xdg_popup_interface, wl_resource_get_version (resource), id); wl_resource_set_implementation (xdg_popup->resource, &meta_wayland_xdg_popup_interface, xdg_popup, xdg_popup_destructor); xdg_popup->xdg_shell_resource = resource; if (!meta_wayland_seat_can_popup (seat, serial)) { xdg_popup_send_popup_done (xdg_popup->resource); return; } xdg_popup->parent_surface = parent_surf; xdg_popup->parent_destroy_listener.notify = handle_popup_parent_destroyed; wl_resource_add_destroy_listener (parent_surf->resource, &xdg_popup->parent_destroy_listener); window = meta_window_wayland_new (display, surface); meta_window_wayland_place_relative_to (window, parent_surf->window, x, y); window->showing_for_first_time = FALSE; meta_wayland_surface_set_window (surface, window); meta_window_focus (window, meta_display_get_current_time (display)); popup_surface = META_WAYLAND_POPUP_SURFACE (surface->role); popup = meta_wayland_pointer_start_popup_grab (&seat->pointer, popup_surface); if (popup == NULL) { xdg_popup_send_popup_done (xdg_popup->resource); meta_wayland_surface_destroy_window (surface); return; } xdg_popup->popup = popup; }