fix weston launch error
[platform/upstream/weston.git] / clients / flower.c
1 /*
2  * Copyright © 2008 Kristian Høgsberg
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23
24 #include "config.h"
25
26 #include <stdint.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <time.h>
31 #include <math.h>
32 #include <cairo.h>
33 #include <sys/time.h>
34
35 #include <linux/input.h>
36 #include <wayland-client.h>
37 #include "window.h"
38
39 struct flower {
40         struct display *display;
41         struct window *window;
42         struct widget *widget;
43         int width, height;
44 };
45
46 static void
47 set_random_color(cairo_t *cr)
48 {
49         cairo_set_source_rgba(cr,
50                               0.5 + (random() % 50) / 49.0,
51                               0.5 + (random() % 50) / 49.0,
52                               0.5 + (random() % 50) / 49.0,
53                               0.5 + (random() % 100) / 99.0);
54 }
55
56
57 static void
58 draw_stuff(cairo_surface_t *surface, int width, int height)
59 {
60         const int petal_count = 3 + random() % 5;
61         const double r1 = 60 + random() % 35;
62         const double r2 = 20 + random() % 40;
63         const double u = (10 + random() % 90) / 100.0;
64         const double v = (random() % 90) / 100.0;
65
66         cairo_t *cr;
67         int i;
68         double t, dt = 2 * M_PI / (petal_count * 2);
69         double x1, y1, x2, y2, x3, y3;
70
71         cr = cairo_create(surface);
72         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
73         cairo_set_source_rgba(cr, 0, 0, 0, 0);
74         cairo_paint(cr);
75
76         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
77         cairo_translate(cr, width / 2, height / 2);
78         cairo_move_to(cr, cos(0) * r1, sin(0) * r1);
79         for (t = 0, i = 0; i < petal_count; i++, t += dt * 2) {
80                 x1 = cos(t) * r1;
81                 y1 = sin(t) * r1;
82                 x2 = cos(t + dt) * r2;
83                 y2 = sin(t + dt) * r2;
84                 x3 = cos(t + 2 * dt) * r1;
85                 y3 = sin(t + 2 * dt) * r1;
86
87                 cairo_curve_to(cr,
88                                x1 - y1 * u, y1 + x1 * u,
89                                x2 + y2 * v, y2 - x2 * v,
90                                x2, y2);
91
92                 cairo_curve_to(cr,
93                                x2 - y2 * v, y2 + x2 * v,
94                                x3 + y3 * u, y3 - x3 * u,
95                                x3, y3);
96         }
97
98         cairo_close_path(cr);
99         set_random_color(cr);
100         cairo_fill_preserve(cr);
101         set_random_color(cr);
102         cairo_stroke(cr);
103
104         cairo_destroy(cr);
105 }
106
107 static void
108 resize_handler(struct widget *widget,
109                int32_t width, int32_t height, void *data)
110 {
111         struct flower *flower = data;
112
113         /* Don't resize me */
114         widget_set_size(flower->widget, flower->width, flower->height);
115 }
116
117 static void
118 redraw_handler(struct widget *widget, void *data)
119 {
120         struct flower *flower = data;
121         cairo_surface_t *surface;
122
123         surface = window_get_surface(flower->window);
124         if (surface == NULL ||
125             cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
126                 fprintf(stderr, "failed to create cairo egl surface\n");
127                 return;
128         }
129
130         draw_stuff(surface, flower->width, flower->height);
131         cairo_surface_destroy(surface);
132 }
133
134 static void
135 button_handler(struct widget *widget,
136                struct input *input, uint32_t time,
137                uint32_t button, enum wl_pointer_button_state state, void *data)
138 {
139         struct flower *flower = data;
140
141         switch (button) {
142         case BTN_LEFT:
143                 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
144                         window_move(flower->window, input,
145                                     display_get_serial(flower->display));
146                 break;
147         case BTN_MIDDLE:
148                 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
149                         widget_schedule_redraw(widget);
150                 break;
151         case BTN_RIGHT:
152                 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
153                         window_show_frame_menu(flower->window, input, time);
154                 break;
155         }
156 }
157
158 static void
159 touch_down_handler(struct widget *widget, struct input *input,
160                    uint32_t serial, uint32_t time, int32_t id,
161                    float x, float y, void *data)
162 {
163         struct flower *flower = data;
164         window_move(flower->window, input, display_get_serial(flower->display));
165 }
166
167 int main(int argc, char *argv[])
168 {
169         struct flower flower;
170         struct display *d;
171         struct timeval tv;
172
173         d = display_create(&argc, argv);
174         if (d == NULL) {
175                 fprintf(stderr, "failed to create display: %m\n");
176                 return -1;
177         }
178
179         gettimeofday(&tv, NULL);
180         srandom(tv.tv_usec);
181
182         flower.width = 200;
183         flower.height = 200;
184         flower.display = d;
185         flower.window = window_create(d);
186         flower.widget = window_add_widget(flower.window, &flower);
187         window_set_title(flower.window, "Flower");
188
189         widget_set_resize_handler(flower.widget, resize_handler);
190         widget_set_redraw_handler(flower.widget, redraw_handler);
191         widget_set_button_handler(flower.widget, button_handler);
192         widget_set_default_cursor(flower.widget, CURSOR_HAND1);
193         widget_set_touch_down_handler(flower.widget, touch_down_handler);
194
195         window_schedule_resize(flower.window, flower.width, flower.height);
196
197         display_run(d);
198
199         widget_destroy(flower.widget);
200         window_destroy(flower.window);
201         display_destroy(d);
202
203         return 0;
204 }