2 * Copyright © 2012 Scott Moreau
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.
27 #include "compositor.h"
28 #include "text-cursor-position-server-protocol.h"
31 weston_zoom_frame_z(struct weston_animation *animation,
32 struct weston_output *output, uint32_t msecs)
34 if (animation->frame_counter <= 1)
35 output->zoom.spring_z.timestamp = msecs;
37 weston_spring_update(&output->zoom.spring_z, msecs);
39 if (output->zoom.spring_z.current > output->zoom.max_level)
40 output->zoom.spring_z.current = output->zoom.max_level;
41 else if (output->zoom.spring_z.current < 0.0)
42 output->zoom.spring_z.current = 0.0;
44 if (weston_spring_done(&output->zoom.spring_z)) {
45 if (output->zoom.active && output->zoom.level <= 0.0) {
46 output->zoom.active = 0;
47 output->disable_planes--;
48 wl_list_remove(&output->zoom.motion_listener.link);
50 output->zoom.spring_z.current = output->zoom.level;
51 wl_list_remove(&animation->link);
52 wl_list_init(&animation->link);
56 weston_output_damage(output);
59 static struct weston_seat *
60 weston_zoom_pick_seat(struct weston_compositor *compositor)
62 return container_of(compositor->seat_list.next,
63 struct weston_seat, link);
68 weston_zoom_frame_xy(struct weston_animation *animation,
69 struct weston_output *output, uint32_t msecs)
71 struct weston_seat *seat = weston_zoom_pick_seat(output->compositor);
74 if (animation->frame_counter <= 1)
75 output->zoom.spring_xy.timestamp = msecs;
77 weston_spring_update(&output->zoom.spring_xy, msecs);
79 x = output->zoom.from.x - ((output->zoom.from.x - output->zoom.to.x) *
80 output->zoom.spring_xy.current);
81 y = output->zoom.from.y - ((output->zoom.from.y - output->zoom.to.y) *
82 output->zoom.spring_xy.current);
84 output->zoom.current.x = x;
85 output->zoom.current.y = y;
87 if (weston_spring_done(&output->zoom.spring_xy)) {
88 output->zoom.spring_xy.current = output->zoom.spring_xy.target;
89 output->zoom.current.x = seat->pointer->x;
90 output->zoom.current.y = seat->pointer->y;
91 wl_list_remove(&animation->link);
92 wl_list_init(&animation->link);
96 weston_output_damage(output);
100 zoom_area_center_from_pointer(struct weston_output *output,
101 wl_fixed_t *x, wl_fixed_t *y)
103 float level = output->zoom.spring_z.current;
104 wl_fixed_t offset_x = wl_fixed_from_int(output->x);
105 wl_fixed_t offset_y = wl_fixed_from_int(output->y);
106 wl_fixed_t w = wl_fixed_from_int(output->width);
107 wl_fixed_t h = wl_fixed_from_int(output->height);
109 *x -= ((((*x - offset_x) / (float) w) - 0.5) * (w * (1.0 - level)));
110 *y -= ((((*y - offset_y) / (float) h) - 0.5) * (h * (1.0 - level)));
114 weston_output_update_zoom_transform(struct weston_output *output)
116 float global_x, global_y;
117 wl_fixed_t x = output->zoom.current.x;
118 wl_fixed_t y = output->zoom.current.y;
119 float trans_min, trans_max;
122 level = output->zoom.spring_z.current;
125 if (!output->zoom.active || level > output->zoom.max_level ||
129 if (wl_list_empty(&output->zoom.animation_xy.link))
130 zoom_area_center_from_pointer(output, &x, &y);
132 global_x = wl_fixed_to_double(x);
133 global_y = wl_fixed_to_double(y);
135 output->zoom.trans_x =
136 ((((global_x - output->x) / output->width) *
137 (level * 2)) - level) * ratio;
138 output->zoom.trans_y =
139 ((((global_y - output->y) / output->height) *
140 (level * 2)) - level) * ratio;
142 trans_max = level * 2 - level;
143 trans_min = -trans_max;
145 /* Clip zoom area to output */
146 if (output->zoom.trans_x > trans_max)
147 output->zoom.trans_x = trans_max;
148 else if (output->zoom.trans_x < trans_min)
149 output->zoom.trans_x = trans_min;
150 if (output->zoom.trans_y > trans_max)
151 output->zoom.trans_y = trans_max;
152 else if (output->zoom.trans_y < trans_min)
153 output->zoom.trans_y = trans_min;
157 weston_zoom_transition(struct weston_output *output, wl_fixed_t x, wl_fixed_t y)
159 if (output->zoom.level != output->zoom.spring_z.current) {
160 output->zoom.spring_z.target = output->zoom.level;
161 if (wl_list_empty(&output->zoom.animation_z.link)) {
162 output->zoom.animation_z.frame_counter = 0;
163 wl_list_insert(output->animation_list.prev,
164 &output->zoom.animation_z.link);
169 weston_output_damage(output);
173 weston_output_update_zoom(struct weston_output *output)
175 struct weston_seat *seat = weston_zoom_pick_seat(output->compositor);
176 wl_fixed_t x = seat->pointer->x;
177 wl_fixed_t y = seat->pointer->y;
179 zoom_area_center_from_pointer(output, &x, &y);
181 if (wl_list_empty(&output->zoom.animation_xy.link)) {
182 output->zoom.current.x = seat->pointer->x;
183 output->zoom.current.y = seat->pointer->y;
185 output->zoom.to.x = x;
186 output->zoom.to.y = y;
189 weston_zoom_transition(output, x, y);
190 weston_output_update_zoom_transform(output);
194 motion(struct wl_listener *listener, void *data)
196 struct weston_output_zoom *zoom =
197 container_of(listener, struct weston_output_zoom, motion_listener);
198 struct weston_output *output =
199 container_of(zoom, struct weston_output, zoom);
201 weston_output_update_zoom(output);
205 weston_output_activate_zoom(struct weston_output *output)
207 struct weston_seat *seat = weston_zoom_pick_seat(output->compositor);
209 if (output->zoom.active)
212 output->zoom.active = 1;
213 output->disable_planes++;
214 wl_signal_add(&seat->pointer->motion_signal,
215 &output->zoom.motion_listener);
219 weston_output_init_zoom(struct weston_output *output)
221 output->zoom.active = 0;
222 output->zoom.increment = 0.07;
223 output->zoom.max_level = 0.95;
224 output->zoom.level = 0.0;
225 output->zoom.trans_x = 0.0;
226 output->zoom.trans_y = 0.0;
227 weston_spring_init(&output->zoom.spring_z, 250.0, 0.0, 0.0);
228 output->zoom.spring_z.friction = 1000;
229 output->zoom.animation_z.frame = weston_zoom_frame_z;
230 wl_list_init(&output->zoom.animation_z.link);
231 weston_spring_init(&output->zoom.spring_xy, 250.0, 0.0, 0.0);
232 output->zoom.spring_xy.friction = 1000;
233 output->zoom.animation_xy.frame = weston_zoom_frame_xy;
234 wl_list_init(&output->zoom.animation_xy.link);
235 output->zoom.motion_listener.notify = motion;