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); } }
WL_EXPORT void wlb_keyboard_key(struct wlb_keyboard *keyboard, uint32_t time, uint32_t key, enum wl_keyboard_key_state state) { struct wl_resource *resource; uint32_t serial, *k, *end; keyboard_ensure_focus(keyboard); end = keyboard->keys.data + keyboard->keys.size; for (k = keyboard->keys.data; k < end; k++) { if (*k == key) { /* Ignore server-generated repeats. */ if (state == WL_KEYBOARD_KEY_STATE_PRESSED) return; *k = *--end; } } keyboard->keys.size = (void *) end - keyboard->keys.data; if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { k = wl_array_add(&keyboard->keys, sizeof *k); *k = key; } if (!keyboard->focus || wl_list_empty(&keyboard->resource_list)) return; serial = wl_display_next_serial(keyboard->seat->compositor->display); wl_resource_for_each(resource, &keyboard->resource_list) wl_keyboard_send_key(resource, serial, time, key, state); }
static void ss_seat_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial_in, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { struct ss_seat *seat = data; struct weston_compositor *c = seat->base.compositor; struct weston_keyboard *keyboard; uint32_t serial_out; /* If we get a key event followed by a modifier event with the * same serial number, then we try to preserve those semantics by * reusing the same serial number on the way out too. */ if (serial_in == seat->key_serial) serial_out = wl_display_get_serial(c->wl_display); else serial_out = wl_display_next_serial(c->wl_display); keyboard = weston_seat_get_keyboard(&seat->base); xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed, mods_latched, mods_locked, 0, 0, group); notify_modifiers(&seat->base, serial_out); }
static void weston_wm_get_selection_targets(struct weston_wm *wm) { struct x11_data_source *source; struct weston_compositor *compositor; struct weston_seat *seat = weston_wm_pick_seat(wm); xcb_get_property_cookie_t cookie; xcb_get_property_reply_t *reply; xcb_atom_t *value; char **p; uint32_t i; cookie = xcb_get_property(wm->conn, 1, /* delete */ wm->selection_window, wm->atom.wl_selection, XCB_GET_PROPERTY_TYPE_ANY, 0, /* offset */ 4096 /* length */); reply = xcb_get_property_reply(wm->conn, cookie, NULL); if (reply == NULL) return; dump_property(wm, wm->atom.wl_selection, reply); if (reply->type != XCB_ATOM_ATOM) { free(reply); return; } source = zalloc(sizeof *source); if (source == NULL) { free(reply); return; } wl_signal_init(&source->base.destroy_signal); source->base.accept = data_source_accept; source->base.send = data_source_send; source->base.cancel = data_source_cancel; source->wm = wm; wl_array_init(&source->base.mime_types); value = xcb_get_property_value(reply); for (i = 0; i < reply->value_len; i++) { if (value[i] == wm->atom.utf8_string) { p = wl_array_add(&source->base.mime_types, sizeof *p); if (p) *p = strdup("text/plain;charset=utf-8"); } } compositor = wm->server->compositor; weston_seat_set_selection(seat, &source->base, wl_display_next_serial(compositor->wl_display)); free(reply); }
void Touch::sendUp(int touch_id) { if (!m_focusResource) return; uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); send_up(m_focusResource->handle, serial, Compositor::currentTimeMsecs(), touch_id); }
void Touch::sendDown(int touch_id, const QPointF &position) { if (!m_focusResource || !m_focus) return; uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); send_down(m_focusResource->handle, serial, Compositor::currentTimeMsecs(), m_focus->resource()->handle, touch_id, wl_fixed_from_double(position.x()), wl_fixed_from_double(position.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 int weston_wm_handle_xfixes_selection_notify(struct weston_wm *wm, xcb_generic_event_t *event) { xcb_xfixes_selection_notify_event_t *xfixes_selection_notify = (xcb_xfixes_selection_notify_event_t *) event; struct weston_compositor *compositor; struct weston_seat *seat = weston_wm_pick_seat(wm); uint32_t serial; if (xfixes_selection_notify->selection != wm->atom.clipboard) return 0; weston_log("xfixes selection notify event: owner %d\n", xfixes_selection_notify->owner); if (xfixes_selection_notify->owner == XCB_WINDOW_NONE) { if (wm->selection_owner != wm->selection_window) { /* A real X client selection went away, not our * proxy selection. Clear the wayland selection. */ compositor = wm->server->compositor; serial = wl_display_next_serial(compositor->wl_display); weston_seat_set_selection(seat, NULL, serial); } wm->selection_owner = XCB_WINDOW_NONE; return 1; } wm->selection_owner = xfixes_selection_notify->owner; /* We have to use XCB_TIME_CURRENT_TIME when we claim the * selection, so grab the actual timestamp here so we can * answer TIMESTAMP conversion requests correctly. */ if (xfixes_selection_notify->owner == wm->selection_window) { wm->selection_timestamp = xfixes_selection_notify->timestamp; weston_log("our window, skipping\n"); return 1; } wm->incr = 0; xcb_convert_selection(wm->conn, wm->selection_window, wm->atom.clipboard, wm->atom.targets, wm->atom.wl_selection, xfixes_selection_notify->timestamp); xcb_flush(wm->conn); return 1; }
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 configure_view(struct wlc_view *view, uint32_t edges, const struct wlc_geometry *g) { assert(view && g); struct wl_resource *r; if (view->xdg_surface && (r = wl_resource_from_wlc_resource(view->xdg_surface, "xdg-surface"))) { const uint32_t serial = wl_display_next_serial(wlc_display()); struct wl_array states = { .size = view->wl_state.items.used, .alloc = view->wl_state.items.allocated, .data = view->wl_state.items.buffer }; xdg_surface_send_configure(r, g->size.w, g->size.h, &states, serial); } else if (view->shell_surface && (r = wl_resource_from_wlc_resource(view->shell_surface, "shell-surface"))) { wl_shell_surface_send_configure(r, edges, g->size.w, g->size.h); } else if (view->x11.id) { wlc_x11_window_configure(&view->x11, g); } }
static void drag_grab_focus(struct wl_pointer_grab *grab, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y) { struct wl_seat *seat = container_of(grab, struct wl_seat, drag_grab); struct wl_resource *resource, *offer = NULL; struct wl_display *display; uint32_t serial; if (seat->drag_focus_resource) { wl_data_device_send_leave(seat->drag_focus_resource); wl_list_remove(&seat->drag_focus_listener.link); seat->drag_focus_resource = NULL; seat->drag_focus = NULL; } if (!surface) return; if (!seat->drag_data_source && surface->resource.client != seat->drag_client) return; resource = find_resource(&seat->drag_resource_list, surface->resource.client); if (!resource) return; display = wl_client_get_display(resource->client); serial = wl_display_next_serial(display); if (seat->drag_data_source) offer = wl_data_source_send_offer(seat->drag_data_source, resource); wl_data_device_send_enter(resource, serial, &surface->resource, x, y, offer); seat->drag_focus = surface; seat->drag_focus_listener.notify = destroy_drag_focus; wl_signal_add(&resource->destroy_signal, &seat->drag_focus_listener); seat->drag_focus_resource = resource; grab->focus = surface; }
WL_EXPORT void wlb_keyboard_modifiers(struct wlb_keyboard *keyboard, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { struct wl_resource *resource; uint32_t serial; keyboard_ensure_focus(keyboard); if (!keyboard->focus || wl_list_empty(&keyboard->resource_list)) return; serial = wl_display_next_serial(keyboard->seat->compositor->display); wl_resource_for_each(resource, &keyboard->resource_list) wl_keyboard_send_modifiers(resource, serial, mods_depressed, mods_latched, mods_locked, group); }
static void send_release_for_keys(struct chck_iter_pool *resources, struct chck_iter_pool *keys) { assert(keys); wlc_dlog(WLC_DBG_KEYBOARD, "release keys"); uint32_t *k; uint32_t time = wlc_get_time(NULL); chck_iter_pool_for_each(keys, k) { wlc_resource *r; chck_iter_pool_for_each(resources, r) { struct wl_resource *wr; if (!(wr = wl_resource_from_wlc_resource(*r, "keyboard"))) continue; uint32_t serial = wl_display_next_serial(wlc_display()); wl_keyboard_send_key(wr, serial, time, *k, WL_KEYBOARD_KEY_STATE_RELEASED); } }
static void input_handle_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial_in, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { struct wayland_input *input = data; struct wayland_compositor *c = input->compositor; uint32_t serial_out; /* If we get a key event followed by a modifier event with the * same serial number, then we try to preserve those semantics by * reusing the same serial number on the way out too. */ if (serial_in == input->key_serial) serial_out = wl_display_get_serial(c->base.wl_display); else serial_out = wl_display_next_serial(c->base.wl_display); xkb_state_update_mask(input->base.xkb_state.state, mods_depressed, mods_latched, mods_locked, 0, 0, group); notify_modifiers(&input->base, serial_out); }
static void xdg_surface_role_configure (MetaWaylandSurfaceRoleShellSurface *shell_surface_role, int new_width, int new_height, MetaWaylandSerial *sent_serial) { MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (shell_surface_role); MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (shell_surface_role); MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (surface_role); struct wl_client *client = wl_resource_get_client (xdg_surface->resource); struct wl_display *display = wl_client_get_display (client); uint32_t serial = wl_display_next_serial (display); struct wl_array states; if (!xdg_surface->resource) return; wl_array_init (&states); fill_states (&states, surface->window); xdg_surface_send_configure (xdg_surface->resource, new_width, new_height, &states, serial); wl_array_release (&states); if (sent_serial) { sent_serial->set = TRUE; sent_serial->value = serial; } }
uint32_t Compositor::nextSerial() { return wl_display_next_serial(m_display); }
void wlc_view_commit_state(struct wlc_view *view, struct wlc_view_state *pending, struct wlc_view_state *out) { assert(view && pending && out); struct wlc_surface *surface; if (!(surface = convert_from_wlc_resource(view->surface, "surface"))) return; // FIXME: handle ping #if 0 struct wl_resource *r; if (view->shell_surface && (r = wl_resource_from_wlc_resource(view->shell_surface, "shell-surface"))) wl_shell_surface_send_ping(r, wl_display_next_serial(wlc_display())); wlc_dlog(WLC_DBG_COMMIT, "=> ping view %" PRIuWLC, convert_to_wlc_handle(view)); return; #endif if (!view->state.created) { // Initial size of the view view->pending.geometry.size = surface->size; view->state.created = true; if (WLC_INTERFACE_EMIT_EXCEPT(view.created, false, convert_to_wlc_handle(view))) { wlc_view_close_ptr(view); return; } } if (!memcmp(pending, out, sizeof(struct wlc_view_state))) return; if (pending->state != out->state) { const struct { enum wlc_view_state_bit bit; uint32_t state; } map[] = { { WLC_BIT_MAXIMIZED, XDG_SURFACE_STATE_MAXIMIZED }, { WLC_BIT_FULLSCREEN, XDG_SURFACE_STATE_FULLSCREEN }, { WLC_BIT_RESIZING, XDG_SURFACE_STATE_RESIZING }, { WLC_BIT_ACTIVATED, XDG_SURFACE_STATE_ACTIVATED }, }; chck_iter_pool_flush(&view->wl_state); for (uint32_t i = 0; i < LENGTH(map); ++i) { if (pending->state & map[i].bit) chck_iter_pool_push_back(&view->wl_state, &map[i].state); } } const bool size_changed = (!wlc_size_equals(&pending->geometry.size, &out->geometry.size) || !wlc_size_equals(&pending->geometry.size, &surface->size)); wlc_dlog(WLC_DBG_COMMIT, "=> pending view commit %" PRIuWLC " (%d) pending: %ux%u commited: %ux%u surface: %ux%u", convert_to_wlc_handle(view), size_changed, pending->geometry.size.w, pending->geometry.size.h, out->geometry.size.w, out->geometry.size.h, surface->size.w, surface->size.h); if (pending->state != out->state || size_changed) configure_view(view, pending->edges, &pending->geometry); *out = *pending; wlc_dlog(WLC_DBG_COMMIT, "=> commit view %" PRIuWLC, convert_to_wlc_handle(view)); }
void wlc_view_commit_state(struct wlc_view *view, struct wlc_view_state *pending, struct wlc_view_state *out) { struct wlc_surface *surface; if (!(surface = convert_from_wlc_resource(view->surface, "surface"))) return; // FIXME: handle ping #if 0 struct wl_resource *r; if (view->shell_surface && (r = wl_resource_from_wlc_resource(view->shell_surface, "shell-surface"))) wl_shell_surface_send_ping(r, wl_display_next_serial(wlc_display())); wlc_dlog(WLC_DBG_COMMIT, "=> ping view %zu", convert_to_wlc_handle(view)); return; #endif if (!view->state.created) { // Initial size of the view view->pending.geometry.size = surface->size; view->state.created = true; if (WLC_INTERFACE_EMIT_EXCEPT(view.created, false, convert_to_wlc_handle(view))) { wlc_view_close_ptr(view); return; } } if (!memcmp(pending, out, sizeof(struct wlc_view_state))) return; if (pending->state != out->state) { const struct { uint32_t bit; uint32_t state; } map[] = { { WLC_BIT_MAXIMIZED, XDG_SURFACE_STATE_MAXIMIZED }, { WLC_BIT_FULLSCREEN, XDG_SURFACE_STATE_FULLSCREEN }, { WLC_BIT_RESIZING, XDG_SURFACE_STATE_RESIZING }, { WLC_BIT_ACTIVATED, XDG_SURFACE_STATE_ACTIVATED }, { 0, 0 }, }; chck_iter_pool_flush(&view->wl_state); for (uint32_t i = 0; map[i].state != 0; ++i) { if (pending->state & map[i].bit) chck_iter_pool_push_back(&view->wl_state, &map[i].state); } } const bool size_changed = (!wlc_size_equals(&pending->geometry.size, &out->geometry.size) || !wlc_size_equals(&pending->geometry.size, &surface->size)); wlc_dlog(WLC_DBG_COMMIT, "=> pending commit %zu (%d) pending: %ux%u commited: %ux%u surface: %ux%u", convert_to_wlc_handle(view), size_changed, pending->geometry.size.w, pending->geometry.size.h, out->geometry.size.w, out->geometry.size.h, surface->size.w, surface->size.h); if (pending->state != out->state || size_changed) { struct wl_resource *r; if (view->xdg_surface && (r = wl_resource_from_wlc_resource(view->xdg_surface, "xdg-surface"))) { const uint32_t serial = wl_display_next_serial(wlc_display()); struct wl_array states = { .size = view->wl_state.items.used, .alloc = view->wl_state.items.allocated, .data = view->wl_state.items.buffer }; xdg_surface_send_configure(r, pending->geometry.size.w, pending->geometry.size.h, &states, serial); } else if (view->shell_surface && (r = wl_resource_from_wlc_resource(view->shell_surface, "shell-surface"))) { wl_shell_surface_send_configure(r, pending->edges, pending->geometry.size.w, pending->geometry.size.h); } } if (view->x11.id) { if (!wlc_origin_equals(&pending->geometry.origin, &out->geometry.origin)) wlc_x11_window_position(&view->x11, pending->geometry.origin.x, pending->geometry.origin.y); if (size_changed) wlc_x11_window_resize(&view->x11, pending->geometry.size.w, pending->geometry.size.h); } memcpy(out, pending, sizeof(struct wlc_view_state)); wlc_dlog(WLC_DBG_COMMIT, "=> commit %zu", convert_to_wlc_handle(view)); }