blob: f30898341cf9c2e1c8c99cc8cdc6dba770cc2988 [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
Kristian Høgsberg7c221d22010-12-16 13:35:23 -050051frame_callback(void *data, uint32_t time)
52{
53 struct resizor *resizor = data;
54 double force, height;
55
56 height = resizor->height.current;
57 force = (resizor->height.target - height) / 10.0 +
58 (resizor->height.previous - height);
59
60 resizor->height.current =
61 height + (height - resizor->height.previous) + force;
62 resizor->height.previous = height;
63
64 if (resizor->height.current >= 400) {
65 resizor->height.current = 400;
66 resizor->height.previous = 400;
67 }
68
69 if (resizor->height.current <= 200) {
70 resizor->height.current = 200;
71 resizor->height.previous = 200;
72 }
73
74 resizor->child_allocation.height = height + 0.5;
75 window_set_child_size(resizor->window,
76 &resizor->child_allocation);
77
Kristian Høgsberg5c4056e2010-12-16 14:56:41 -050078 window_schedule_redraw(resizor->window);
Kristian Høgsberg7c221d22010-12-16 13:35:23 -050079}
80
81static void
Kristian Høgsberg53a7f212010-12-16 21:11:10 -050082resizor_draw(struct resizor *resizor)
83{
84 cairo_surface_t *surface;
85 cairo_t *cr;
86
87 window_draw(resizor->window);
88
89 window_get_child_rectangle(resizor->window,
90 &resizor->child_allocation);
91
92 surface = window_get_surface(resizor->window);
93
94 cr = cairo_create(surface);
95 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
96 cairo_rectangle(cr,
97 resizor->child_allocation.x,
98 resizor->child_allocation.y,
99 resizor->child_allocation.width,
100 resizor->child_allocation.height);
101 cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
102 cairo_fill(cr);
103 cairo_destroy(cr);
104
105 cairo_surface_destroy(surface);
106
107 window_flush(resizor->window);
108
109 if (fabs(resizor->height.previous - resizor->height.target) > 0.1) {
110 wl_display_frame_callback(display_get_display(resizor->display),
111 frame_callback, resizor);
112 }
113}
114
115static void
116redraw_handler(struct window *window, void *data)
117{
118 struct resizor *resizor = data;
119
120 resizor_draw(resizor);
121}
122
123static void
124keyboard_focus_handler(struct window *window,
125 struct input *device, void *data)
126{
127 struct resizor *resizor = data;
128
129 window_schedule_redraw(resizor->window);
130}
131
132static void
Kristian Høgsberg7c221d22010-12-16 13:35:23 -0500133key_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) {
Kristian Høgsberg53a7f212010-12-16 21:11:10 -0500142 case XK_Down:
Kristian Høgsberg7c221d22010-12-16 13:35:23 -0500143 resizor->height.target = 400;
144 resizor->height.current = resizor->child_allocation.height;
145 frame_callback(resizor, 0);
146 break;
Kristian Høgsberg53a7f212010-12-16 21:11:10 -0500147 case XK_Up:
Kristian Høgsberg7c221d22010-12-16 13:35:23 -0500148 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
Kristian Høgsberg82da52b2010-12-17 09:53:12 -0500165 resizor->window = window_create(display, "Wayland Resizor", 500, 400);
Kristian Høgsberg7c221d22010-12-16 13:35:23 -0500166 resizor->display = display;
167
168 window_set_key_handler(resizor->window, key_handler);
169 window_set_user_data(resizor->window, resizor);
170 window_set_redraw_handler(resizor->window, redraw_handler);
171 window_set_keyboard_focus_handler(resizor->window,
172 keyboard_focus_handler);
173
174 resizor->child_allocation.x = 0;
175 resizor->child_allocation.y = 0;
176 resizor->child_allocation.width = 300;
177 resizor->child_allocation.height = 400;
178 resizor->height.current = 400;
179 resizor->height.previous = 400;
180 resizor->height.target = 400;
181
182 window_set_child_size(resizor->window, &resizor->child_allocation);
183
184 resizor_draw(resizor);
185
186 return resizor;
187}
188
189int
190main(int argc, char *argv[])
191{
192 struct display *d;
193
194 d = display_create(&argc, &argv, NULL);
195 if (d == NULL) {
196 fprintf(stderr, "failed to create display: %m\n");
197 return -1;
198 }
199
200 resizor_create (d);
201
202 display_run(d);
203
204 return 0;
205}