blob: 687145a1d2b81bd1b5cf083399a51269fa9f13b0 [file] [log] [blame]
Kristian Høgsberg7c221d22010-12-16 13:35:23 -05001/*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22
23#include <stdint.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <cairo.h>
Kristian Høgsberg5c4056e2010-12-16 14:56:41 -050028#include <math.h>
Kristian Høgsberg7c221d22010-12-16 13:35:23 -050029
30#include "wayland-util.h"
31#include "wayland-client.h"
32#include "wayland-glib.h"
33
34#include "window.h"
35
36#include <X11/keysym.h>
37
38struct resizor {
39 struct display *display;
40 struct window *window;
41 struct rectangle child_allocation;
42
43 struct {
44 double current;
45 double target;
46 double previous;
47 } height;
48};
49
50static void
51resizor_draw(struct resizor *resizor)
52{
53 cairo_surface_t *surface;
54 cairo_t *cr;
55
56 window_draw(resizor->window);
57
58 window_get_child_rectangle(resizor->window,
59 &resizor->child_allocation);
60
61 surface = window_get_surface(resizor->window);
62
63 cr = cairo_create(surface);
64 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
65 cairo_rectangle(cr,
66 resizor->child_allocation.x,
67 resizor->child_allocation.y,
68 resizor->child_allocation.width,
69 resizor->child_allocation.height);
70 cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
71 cairo_fill(cr);
72 cairo_destroy(cr);
73
74 cairo_surface_destroy(surface);
75
76 window_flush(resizor->window);
Kristian Høgsberg5c4056e2010-12-16 14:56:41 -050077
78 if (fabs(resizor->height.previous - resizor->height.target) < 0.1) {
79 wl_display_frame_callback(display_get_display(resizor->display),
80 frame_callback, resizor);
81 }
Kristian Høgsberg7c221d22010-12-16 13:35:23 -050082}
83
84static void
85redraw_handler(struct window *window, void *data)
86{
87 struct resizor *resizor = data;
88
89 resizor_draw(resizor);
90}
91
92static void
93keyboard_focus_handler(struct window *window,
94 struct input *device, void *data)
95{
96 struct resizor *resizor = data;
97
98 window_schedule_redraw(resizor->window);
99}
100
101static void
102frame_callback(void *data, uint32_t time)
103{
104 struct resizor *resizor = data;
105 double force, height;
106
107 height = resizor->height.current;
108 force = (resizor->height.target - height) / 10.0 +
109 (resizor->height.previous - height);
110
111 resizor->height.current =
112 height + (height - resizor->height.previous) + force;
113 resizor->height.previous = height;
114
115 if (resizor->height.current >= 400) {
116 resizor->height.current = 400;
117 resizor->height.previous = 400;
118 }
119
120 if (resizor->height.current <= 200) {
121 resizor->height.current = 200;
122 resizor->height.previous = 200;
123 }
124
125 resizor->child_allocation.height = height + 0.5;
126 window_set_child_size(resizor->window,
127 &resizor->child_allocation);
128
Kristian Høgsberg5c4056e2010-12-16 14:56:41 -0500129 window_schedule_redraw(resizor->window);
Kristian Høgsberg7c221d22010-12-16 13:35:23 -0500130}
131
132static void
133key_handler(struct window *window, uint32_t key, uint32_t sym,
134 uint32_t state, uint32_t modifiers, void *data)
135{
136 struct resizor *resizor = data;
137
138 if (state == 0)
139 return;
140
141 switch (sym) {
142 case XK_F1:
143 resizor->height.target = 400;
144 resizor->height.current = resizor->child_allocation.height;
145 frame_callback(resizor, 0);
146 break;
147 case XK_F2:
148 resizor->height.target = 200;
149 resizor->height.current = resizor->child_allocation.height;
150 frame_callback(resizor, 0);
151 break;
152 }
153}
154
155static struct resizor *
156resizor_create(struct display *display)
157{
158 struct resizor *resizor;
159
160 resizor = malloc(sizeof *resizor);
161 if (resizor == NULL)
162 return resizor;
163 memset(resizor, 0, sizeof *resizor);
164
165 resizor->window = window_create(display, "Wayland Resizor",
166 100, 100, 500, 400);
167 resizor->display = display;
168
169 window_set_key_handler(resizor->window, key_handler);
170 window_set_user_data(resizor->window, resizor);
171 window_set_redraw_handler(resizor->window, redraw_handler);
172 window_set_keyboard_focus_handler(resizor->window,
173 keyboard_focus_handler);
174
175 resizor->child_allocation.x = 0;
176 resizor->child_allocation.y = 0;
177 resizor->child_allocation.width = 300;
178 resizor->child_allocation.height = 400;
179 resizor->height.current = 400;
180 resizor->height.previous = 400;
181 resizor->height.target = 400;
182
183 window_set_child_size(resizor->window, &resizor->child_allocation);
184
185 resizor_draw(resizor);
186
187 return resizor;
188}
189
190int
191main(int argc, char *argv[])
192{
193 struct display *d;
194
195 d = display_create(&argc, &argv, NULL);
196 if (d == NULL) {
197 fprintf(stderr, "failed to create display: %m\n");
198 return -1;
199 }
200
201 resizor_create (d);
202
203 display_run(d);
204
205 return 0;
206}