static void bind_output (struct wl_client *client, void *data, guint32 version, guint32 id) { MetaWaylandOutput *wayland_output = data; MetaOutput *output = wayland_output->output; struct wl_resource *resource; guint mode_flags; resource = wl_resource_create (client, &wl_output_interface, MIN (META_WL_OUTPUT_VERSION, version), id); wayland_output->resources = g_list_prepend (wayland_output->resources, resource); wl_resource_set_user_data (resource, wayland_output); wl_resource_set_destructor (resource, output_resource_destroy); meta_verbose ("Binding output %p/%s (%u, %u, %u, %u) x %f\n", output, output->name, output->crtc->rect.x, output->crtc->rect.y, output->crtc->rect.width, output->crtc->rect.height, output->crtc->current_mode->refresh_rate); wl_resource_post_event (resource, WL_OUTPUT_GEOMETRY, (int)output->crtc->rect.x, (int)output->crtc->rect.y, output->width_mm, output->height_mm, /* Cogl values reflect XRandR values, and so does wayland */ output->subpixel_order, output->vendor, output->product, output->crtc->transform); g_assert (output->crtc->current_mode != NULL); mode_flags = WL_OUTPUT_MODE_CURRENT; if (output->crtc->current_mode == output->preferred_mode) mode_flags |= WL_OUTPUT_MODE_PREFERRED; wl_resource_post_event (resource, WL_OUTPUT_MODE, mode_flags, (int)output->crtc->current_mode->width, (int)output->crtc->current_mode->height, (int)output->crtc->current_mode->refresh_rate); output->scale = compute_scale (output); if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) wl_resource_post_event (resource, WL_OUTPUT_SCALE, output->scale); if (version >= WL_OUTPUT_DONE_SINCE_VERSION) wl_resource_post_event (resource, WL_OUTPUT_DONE); }
static void drag_grab_focus(struct wl_grab *grab, uint32_t time, struct wl_surface *surface, int32_t x, int32_t y) { struct wl_input_device *device = container_of(grab, struct wl_input_device, drag_grab); struct wl_resource *resource, *offer; if (device->drag_focus_resource) { wl_resource_post_event(device->drag_focus_resource, WL_DATA_DEVICE_LEAVE); wl_list_remove(&device->drag_focus_listener.link); device->drag_focus_resource = NULL; device->drag_focus = NULL; } if (surface) resource = find_resource(&device->drag_resource_list, surface->resource.client); if (surface && resource) { offer = wl_data_source_send_offer(device->drag_data_source, resource); wl_resource_post_event(resource, WL_DATA_DEVICE_ENTER, time, surface, x, y, offer); device->drag_focus = surface; device->drag_focus_listener.func = destroy_drag_focus; wl_list_insert(resource->destroy_listener_list.prev, &device->drag_focus_listener.link); device->drag_focus_resource = resource; grab->focus = surface; } }
static void bind_output (struct wl_client *client, void *data, uint32_t version, uint32_t id) { CoglandOutput *output = data; struct wl_resource *resource = wl_client_add_object (client, &wl_output_interface, NULL, id, data); GList *l; wl_resource_post_event (resource, WL_OUTPUT_GEOMETRY, output->x, output->y, output->width_mm, output->height_mm, 0, /* subpixel: unknown */ "unknown", /* make */ "unknown"); /* model */ for (l = output->modes; l; l = l->next) { CoglandMode *mode = l->data; wl_resource_post_event (resource, WL_OUTPUT_MODE, mode->flags, mode->width, mode->height, mode->refresh); } }
static void bind_drm(struct wl_client *client, void *data, uint32_t version, uint32_t id) { struct wl_drm *drm = data; struct wl_resource *resource; resource = wl_client_add_object(client, &wl_drm_interface, &drm_interface, id, data); wl_resource_post_event(resource, WL_DRM_DEVICE, drm->device_name); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_ARGB8888); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_XRGB8888); }
static void wayland_output_update_for_output (MetaWaylandOutput *wayland_output, MetaOutput *output) { GList *iter; guint mode_flags; enum wl_output_transform wl_transform = wl_output_transform_from_meta_monitor_transform (output->crtc->transform); g_assert (output->crtc->current_mode != NULL); mode_flags = WL_OUTPUT_MODE_CURRENT; if (output->crtc->current_mode == output->preferred_mode) mode_flags |= WL_OUTPUT_MODE_PREFERRED; for (iter = wayland_output->resources; iter; iter = iter->next) { struct wl_resource *resource = iter->data; if (wayland_output->x != output->crtc->rect.x || wayland_output->y != output->crtc->rect.y || wayland_output->transform != wl_transform) { wl_resource_post_event (resource, WL_OUTPUT_GEOMETRY, (int)output->crtc->rect.x, (int)output->crtc->rect.y, output->width_mm, output->height_mm, output->subpixel_order, output->vendor, output->product, wl_transform); } wl_resource_post_event (resource, WL_OUTPUT_MODE, mode_flags, (int)output->crtc->current_mode->width, (int)output->crtc->current_mode->height, (int)output->crtc->current_mode->refresh_rate); } /* It's very important that we change the output pointer here, as the old structure is about to be freed by MetaMonitorManager */ wayland_output->output = output; wayland_output->x = output->crtc->rect.x; wayland_output->y = output->crtc->rect.y; wayland_output->transform = wl_transform; }
/* local functions */ static void _e_mod_comp_wl_output_bind(struct wl_client *client, void *data, uint32_t version __UNUSED__, uint32_t id) { Wayland_Output *output; struct wl_resource *resource; LOGFN(__FILE__, __LINE__, __FUNCTION__); if (!(output = data)) return; resource = wl_client_add_object(client, &wl_output_interface, NULL, id, data); wl_resource_post_event(resource, WL_OUTPUT_GEOMETRY, output->x, output->y, output->w, output->h, output->subpixel, output->make, output->model); wl_resource_post_event(resource, WL_OUTPUT_MODE, output->mode.flags, output->mode.w, output->mode.h, output->mode.refresh); }
static void drag_grab_motion(struct wl_grab *grab, uint32_t time, int32_t x, int32_t y) { struct wl_input_device *device = container_of(grab, struct wl_input_device, drag_grab); if (device->drag_focus_resource) wl_resource_post_event(device->drag_focus_resource, WL_DATA_DEVICE_MOTION, time, x, y); }
static void data_offer_receive(struct wl_client *client, struct wl_resource *resource, const char *mime_type, int32_t fd) { struct wl_data_offer *offer = resource->data; if (offer->source) wl_resource_post_event(&offer->source->resource, WL_DATA_SOURCE_SEND, mime_type, fd); close(fd); }
static void drm_authenticate(struct wl_client *client, struct wl_resource *resource, uint32_t id) { struct wl_drm *drm = resource->data; if (drm->callbacks->authenticate(drm->user_data, id) < 0) wl_resource_post_error(resource, WL_DRM_ERROR_AUTHENTICATE_FAIL, "authenicate failed"); else wl_resource_post_event(resource, WL_DRM_AUTHENTICATED); }
static void data_offer_accept(struct wl_client *client, struct wl_resource *resource, uint32_t time, const char *mime_type) { struct wl_data_offer *offer = resource->data; /* FIXME: Check that client is currently focused by the input * device that is currently dragging this data source. Should * this be a wl_data_device request? */ if (offer->source) wl_resource_post_event(&offer->source->resource, WL_DATA_SOURCE_TARGET, mime_type); }
static struct wl_resource * wl_data_source_send_offer(struct wl_data_source *source, struct wl_resource *target) { struct wl_data_offer *offer; char **p, **end; offer = malloc(sizeof *offer); if (offer == NULL) return NULL; offer->resource.destroy = destroy_data_offer; offer->resource.object.id = 0; offer->resource.object.interface = &wl_data_offer_interface; offer->resource.object.implementation = (void (**)(void)) source->offer_interface; offer->resource.data = offer; wl_list_init(&offer->resource.destroy_listener_list); offer->source = source; offer->source_destroy_listener.func = destroy_offer_data_source; wl_list_insert(&source->resource.destroy_listener_list, &offer->source_destroy_listener.link); wl_client_add_resource(target->client, &offer->resource); wl_resource_post_event(target, WL_DATA_DEVICE_DATA_OFFER, &offer->resource); end = source->mime_types.data + source->mime_types.size; for (p = source->mime_types.data; p < end; p++) wl_resource_post_event(&offer->resource, WL_DATA_OFFER_OFFER, *p); return &offer->resource; }
static CoglBool paint_cb (void *user_data) { CoglandCompositor *compositor = user_data; GList *l; for (l = compositor->outputs; l; l = l->next) { CoglandOutput *output = l->data; CoglFramebuffer *fb = COGL_FRAMEBUFFER (output->onscreen); GList *l2; cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1); cogl_framebuffer_draw_primitive (fb, compositor->triangle_pipeline, compositor->triangle); for (l2 = compositor->surfaces; l2; l2 = l2->next) { CoglandSurface *surface = l2->data; if (surface->buffer) { CoglTexture2D *texture = surface->buffer->texture; CoglPipeline *pipeline = cogl_pipeline_new (compositor->cogl_context); cogl_pipeline_set_layer_texture (pipeline, 0, COGL_TEXTURE (texture)); cogl_framebuffer_draw_rectangle (fb, pipeline, -1, 1, 1, -1); cogl_object_unref (pipeline); } } cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb)); } while (!g_queue_is_empty (&compositor->frame_callbacks)) { CoglandFrameCallback *callback = g_queue_peek_head (&compositor->frame_callbacks); wl_resource_post_event (&callback->resource, WL_CALLBACK_DONE, get_time ()); wl_resource_destroy (&callback->resource, 0); } return TRUE; }
static void drag_grab_button(struct wl_grab *grab, uint32_t time, int32_t button, int32_t state) { struct wl_input_device *device = container_of(grab, struct wl_input_device, drag_grab); if (device->drag_focus_resource && device->grab_button == button && state == 0) wl_resource_post_event(device->drag_focus_resource, WL_DATA_DEVICE_DROP); if (device->button_count == 0 && state == 0) { wl_input_device_end_grab(device, time); device->drag_data_source = NULL; } }
static void drm_authenticate(struct wl_client *client, struct wl_resource *resource, uint32_t id) { /* * there is the full- GPU sharing to support authenticating * like this, uncertain if we actually need to do more though * struct wl_drm *drm = resource->data; if (drm->callbacks->authenticate(drm->user_data, id) < 0) wl_resource_post_error(resource, WL_DRM_ERROR_AUTHENTICATE_FAIL, "authenicate failed"); else */ wl_resource_post_event(resource, WL_DRM_AUTHENTICATED); }
static void destroy_selection_data_source(struct wl_listener *listener, struct wl_resource *resource, uint32_t time) { struct wl_input_device *device = container_of(listener, struct wl_input_device, selection_data_source_listener); struct wl_resource *data_device, *focus; device->selection_data_source = NULL; focus = device->keyboard_focus_resource; if (focus) { data_device = find_resource(&device->drag_resource_list, focus->client); wl_resource_post_event(data_device, WL_DATA_DEVICE_SELECTION, NULL); } }
WL_EXPORT void wl_data_device_set_keyboard_focus(struct wl_input_device *device) { struct wl_resource *data_device, *focus, *offer; struct wl_data_source *source; focus = device->keyboard_focus_resource; if (!focus) return; data_device = find_resource(&device->drag_resource_list, focus->client); if (!data_device) return; source = device->selection_data_source; if (source) { offer = wl_data_source_send_offer(source, data_device); wl_resource_post_event(data_device, WL_DATA_DEVICE_SELECTION, offer); } }
WL_EXPORT void wl_input_device_set_selection(struct wl_input_device *device, struct wl_data_source *source, uint32_t time) { struct wl_resource *data_device, *focus, *offer; struct wl_selection_listener *listener, *next; if (device->selection_data_source) { device->selection_data_source->cancel(device->selection_data_source); wl_list_remove(&device->selection_data_source_listener.link); device->selection_data_source = NULL; } device->selection_data_source = source; focus = device->keyboard_focus_resource; if (focus) { data_device = find_resource(&device->drag_resource_list, focus->client); if (data_device) { offer = wl_data_source_send_offer(device->selection_data_source, data_device); wl_resource_post_event(data_device, WL_DATA_DEVICE_SELECTION, offer); } } wl_list_for_each_safe(listener, next, &device->selection_listener_list, link) listener->func(listener, device); device->selection_data_source_listener.func = destroy_selection_data_source; wl_list_insert(source->resource.destroy_listener_list.prev, &device->selection_data_source_listener.link); }
static void bind_drm(struct wl_client *client, void *data, uint32_t version, uint32_t id) { struct wl_drm *drm = data; struct wl_resource *resource; uint32_t capabilities; resource = wl_client_add_object(client, &wl_drm_interface, &drm_interface, id, data); wl_resource_post_event(resource, WL_DRM_DEVICE, drm->device_name); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_ARGB8888); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_XRGB8888); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV410); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV411); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV420); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV422); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV444); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_NV12); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_NV16); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUYV); capabilities = 0; if (drm->flags & WAYLAND_DRM_PRIME) capabilities |= WL_DRM_CAPABILITY_PRIME; if (version >= 2) wl_resource_post_event(resource, WL_DRM_CAPABILITIES, capabilities); }
static void bind_drm(struct wl_client *client, void *data, uint32_t version, uint32_t id) { struct wl_drm *drm = data; struct wl_resource *resource; uint32_t capabilities; resource = wl_resource_create(client, &wl_drm_interface, MIN(version, 2), id); if (!resource) { wl_client_post_no_memory(client); return; } wl_resource_set_implementation(resource, &drm_interface, data, NULL); wl_resource_post_event(resource, WL_DRM_DEVICE, drm->device_name); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_ARGB8888); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_XRGB8888); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV410); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV411); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV420); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV422); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV444); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_NV12); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_NV16); wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUYV); capabilities = 0; if (drm->flags & WAYLAND_DRM_PRIME) capabilities |= WL_DRM_CAPABILITY_PRIME; if (version >= 2) wl_resource_post_event(resource, WL_DRM_CAPABILITIES, capabilities); }
static void data_source_cancel(struct wl_data_source *source) { wl_resource_post_event(&source->resource, WL_DATA_SOURCE_CANCELLED); }