2 * Copyright © 2011 Intel Corporation
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 #include "compositor.h"
31 weston_spring_init(struct weston_spring *spring,
32 double k, double current, double target)
35 spring->friction = 400.0;
36 spring->current = current;
37 spring->previous = current;
38 spring->target = target;
42 weston_spring_update(struct weston_spring *spring, uint32_t msec)
44 double force, v, current, step;
47 while (4 < msec - spring->timestamp) {
48 current = spring->current;
49 v = current - spring->previous;
50 force = spring->k * (spring->target - current) / 10.0 +
51 (spring->previous - current) - v * spring->friction;
54 current + (current - spring->previous) +
56 spring->previous = current;
59 if (spring->current >= 1.0) {
61 spring->current = 2.0 - spring->current;
62 spring->previous = 2.0 - spring->previous;
64 spring->current = 1.0;
65 spring->previous = 1.0;
69 if (spring->current <= 0.0) {
70 spring->current = 0.0;
71 spring->previous = 0.0;
74 spring->timestamp += 4;
79 weston_spring_done(struct weston_spring *spring)
81 return fabs(spring->previous - spring->target) < 0.0002 &&
82 fabs(spring->current - spring->target) < 0.0002;
86 struct weston_surface *surface;
87 struct weston_animation animation;
88 struct weston_spring spring;
89 struct weston_transform transform;
90 struct wl_listener listener;
92 void (*done)(struct weston_zoom *zoom, void *data);
97 weston_zoom_destroy(struct weston_zoom *zoom)
99 wl_list_remove(&zoom->animation.link);
100 wl_list_remove(&zoom->listener.link);
101 wl_list_remove(&zoom->transform.link);
102 zoom->surface->geometry.dirty = 1;
104 zoom->done(zoom, zoom->data);
109 handle_zoom_surface_destroy(struct wl_listener *listener,
110 struct wl_resource *resource, uint32_t time)
112 struct weston_zoom *zoom =
113 container_of(listener, struct weston_zoom, listener);
115 weston_zoom_destroy(zoom);
119 weston_zoom_frame(struct weston_animation *animation,
120 struct weston_output *output, uint32_t msecs)
122 struct weston_zoom *zoom =
123 container_of(animation, struct weston_zoom, animation);
124 struct weston_surface *es = zoom->surface;
127 weston_spring_update(&zoom->spring, msecs);
129 if (weston_spring_done(&zoom->spring)) {
130 weston_zoom_destroy(zoom);
134 scale = zoom->start +
135 (zoom->stop - zoom->start) * zoom->spring.current;
136 weston_matrix_init(&zoom->transform.matrix);
137 weston_matrix_translate(&zoom->transform.matrix,
138 -0.5f * es->geometry.width,
139 -0.5f * es->geometry.height, 0);
140 weston_matrix_scale(&zoom->transform.matrix, scale, scale, scale);
141 weston_matrix_translate(&zoom->transform.matrix,
142 0.5f * es->geometry.width,
143 0.5f * es->geometry.height, 0);
145 es->alpha = zoom->spring.current * 255;
149 zoom->surface->geometry.dirty = 1;
150 weston_compositor_schedule_repaint(es->compositor);
153 WL_EXPORT struct weston_zoom *
154 weston_zoom_run(struct weston_surface *surface, GLfloat start, GLfloat stop,
155 weston_zoom_done_func_t done, void *data)
157 struct weston_zoom *zoom;
159 zoom = malloc(sizeof *zoom);
163 zoom->surface = surface;
168 wl_list_insert(&surface->geometry.transformation_list,
169 &zoom->transform.link);
170 weston_spring_init(&zoom->spring, 200.0, 0.0, 1.0);
171 zoom->spring.friction = 700;
172 zoom->spring.timestamp = weston_compositor_get_time();
173 zoom->animation.frame = weston_zoom_frame;
174 weston_zoom_frame(&zoom->animation, NULL, zoom->spring.timestamp);
176 zoom->listener.func = handle_zoom_surface_destroy;
177 wl_list_insert(surface->surface.resource.destroy_listener_list.prev,
178 &zoom->listener.link);
180 wl_list_insert(&surface->compositor->animation_list,
181 &zoom->animation.link);
186 struct weston_binding {
191 weston_binding_handler_t handler;
196 WL_EXPORT struct weston_binding *
197 weston_compositor_add_binding(struct weston_compositor *compositor,
198 uint32_t key, uint32_t button, uint32_t axis, uint32_t modifier,
199 weston_binding_handler_t handler, void *data)
201 struct weston_binding *binding;
203 binding = malloc(sizeof *binding);
208 binding->button = button;
209 binding->axis = axis;
210 binding->modifier = modifier;
211 binding->handler = handler;
212 binding->data = data;
213 wl_list_insert(compositor->binding_list.prev, &binding->link);
219 weston_binding_destroy(struct weston_binding *binding)
221 wl_list_remove(&binding->link);
226 weston_binding_list_destroy_all(struct wl_list *list)
228 struct weston_binding *binding, *tmp;
230 wl_list_for_each_safe(binding, tmp, list, link)
231 weston_binding_destroy(binding);
234 struct binding_keyboard_grab {
236 struct wl_keyboard_grab grab;
240 binding_key(struct wl_keyboard_grab *grab,
241 uint32_t time, uint32_t key, int32_t state)
243 struct binding_keyboard_grab *b =
244 container_of(grab, struct binding_keyboard_grab, grab);
245 struct wl_resource *resource;
247 resource = grab->input_device->keyboard_focus_resource;
250 wl_input_device_end_keyboard_grab(grab->input_device,
255 wl_input_device_send_key(resource, time, key, state);
258 static const struct wl_keyboard_grab_interface binding_grab = {
263 install_binding_grab(struct wl_input_device *device,
264 uint32_t time, uint32_t key)
266 struct binding_keyboard_grab *grab;
268 grab = malloc(sizeof *grab);
270 grab->grab.interface = &binding_grab;
271 wl_input_device_start_keyboard_grab(device, &grab->grab, time);
275 weston_compositor_run_binding(struct weston_compositor *compositor,
276 struct weston_input_device *device,
277 uint32_t time, uint32_t key,
278 uint32_t button, uint32_t axis, int32_t state)
280 struct weston_binding *b;
282 wl_list_for_each(b, &compositor->binding_list, link) {
283 if (b->key == key && b->button == button && b->axis == axis &&
284 b->modifier == device->modifier_state && state) {
285 b->handler(&device->input_device,
286 time, key, button, axis, state, b->data);
288 /* If this was a key binding and it didn't
289 * install a keyboard grab, install one now to
290 * swallow the key release. */
292 device->input_device.keyboard_grab ==
293 &device->input_device.default_keyboard_grab)
294 install_binding_grab(&device->input_device,