blob: cfed126726917c3c70136e3bb0d4c44e3dd01e23 [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>
28
29#include "wayland-util.h"
30#include "wayland-client.h"
31#include "wayland-glib.h"
32
33#include "window.h"
34
35#include <X11/keysym.h>
36
37struct resizor {
38 struct display *display;
39 struct window *window;
40 struct rectangle child_allocation;
41
42 struct {
43 double current;
44 double target;
45 double previous;
46 } height;
47};
48
49static void
50resizor_draw(struct resizor *resizor)
51{
52 cairo_surface_t *surface;
53 cairo_t *cr;
54
55 window_draw(resizor->window);
56
57 window_get_child_rectangle(resizor->window,
58 &resizor->child_allocation);
59
60 surface = window_get_surface(resizor->window);
61
62 cr = cairo_create(surface);
63 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
64 cairo_rectangle(cr,
65 resizor->child_allocation.x,
66 resizor->child_allocation.y,
67 resizor->child_allocation.width,
68 resizor->child_allocation.height);
69 cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
70 cairo_fill(cr);
71 cairo_destroy(cr);
72
73 cairo_surface_destroy(surface);
74
75 window_flush(resizor->window);
76}
77
78static void
79redraw_handler(struct window *window, void *data)
80{
81 struct resizor *resizor = data;
82
83 resizor_draw(resizor);
84}
85
86static void
87keyboard_focus_handler(struct window *window,
88 struct input *device, void *data)
89{
90 struct resizor *resizor = data;
91
92 window_schedule_redraw(resizor->window);
93}
94
95static void
96frame_callback(void *data, uint32_t time)
97{
98 struct resizor *resizor = data;
99 double force, height;
100
101 height = resizor->height.current;
102 force = (resizor->height.target - height) / 10.0 +
103 (resizor->height.previous - height);
104
105 resizor->height.current =
106 height + (height - resizor->height.previous) + force;
107 resizor->height.previous = height;
108
109 if (resizor->height.current >= 400) {
110 resizor->height.current = 400;
111 resizor->height.previous = 400;
112 }
113
114 if (resizor->height.current <= 200) {
115 resizor->height.current = 200;
116 resizor->height.previous = 200;
117 }
118
119 resizor->child_allocation.height = height + 0.5;
120 window_set_child_size(resizor->window,
121 &resizor->child_allocation);
122
123 if ((int) (height + 0.5) != resizor->height.target) {
124 window_schedule_redraw(resizor->window);
125 wl_display_frame_callback(display_get_display(resizor->display),
126 frame_callback, resizor);
127 }
128}
129
130static void
131key_handler(struct window *window, uint32_t key, uint32_t sym,
132 uint32_t state, uint32_t modifiers, void *data)
133{
134 struct resizor *resizor = data;
135
136 if (state == 0)
137 return;
138
139 switch (sym) {
140 case XK_F1:
141 resizor->height.target = 400;
142 resizor->height.current = resizor->child_allocation.height;
143 frame_callback(resizor, 0);
144 break;
145 case XK_F2:
146 resizor->height.target = 200;
147 resizor->height.current = resizor->child_allocation.height;
148 frame_callback(resizor, 0);
149 break;
150 }
151}
152
153static struct resizor *
154resizor_create(struct display *display)
155{
156 struct resizor *resizor;
157
158 resizor = malloc(sizeof *resizor);
159 if (resizor == NULL)
160 return resizor;
161 memset(resizor, 0, sizeof *resizor);
162
163 resizor->window = window_create(display, "Wayland Resizor",
164 100, 100, 500, 400);
165 resizor->display = display;
166
167 window_set_key_handler(resizor->window, key_handler);
168 window_set_user_data(resizor->window, resizor);
169 window_set_redraw_handler(resizor->window, redraw_handler);
170 window_set_keyboard_focus_handler(resizor->window,
171 keyboard_focus_handler);
172
173 resizor->child_allocation.x = 0;
174 resizor->child_allocation.y = 0;
175 resizor->child_allocation.width = 300;
176 resizor->child_allocation.height = 400;
177 resizor->height.current = 400;
178 resizor->height.previous = 400;
179 resizor->height.target = 400;
180
181 window_set_child_size(resizor->window, &resizor->child_allocation);
182
183 resizor_draw(resizor);
184
185 return resizor;
186}
187
188int
189main(int argc, char *argv[])
190{
191 struct display *d;
192
193 d = display_create(&argc, &argv, NULL);
194 if (d == NULL) {
195 fprintf(stderr, "failed to create display: %m\n");
196 return -1;
197 }
198
199 resizor_create (d);
200
201 display_run(d);
202
203 return 0;
204}