• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <errno.h>
34 #include <sys/time.h>
35 
36 #include <linux/input.h>
37 #include <wayland-client.h>
38 #include "window.h"
39 
40 struct flower {
41 	struct display *display;
42 	struct window *window;
43 	struct widget *widget;
44 	int width, height;
45 };
46 
47 static void
set_random_color(cairo_t * cr)48 set_random_color(cairo_t *cr)
49 {
50 	cairo_set_source_rgba(cr,
51 			      0.5 + (random() % 50) / 49.0,
52 			      0.5 + (random() % 50) / 49.0,
53 			      0.5 + (random() % 50) / 49.0,
54 			      0.5 + (random() % 100) / 99.0);
55 }
56 
57 
58 static void
draw_stuff(cairo_surface_t * surface,int width,int height)59 draw_stuff(cairo_surface_t *surface, int width, int height)
60 {
61 	const int petal_count = 3 + random() % 5;
62 	const double r1 = 60 + random() % 35;
63 	const double r2 = 20 + random() % 40;
64 	const double u = (10 + random() % 90) / 100.0;
65 	const double v = (random() % 90) / 100.0;
66 
67 	cairo_t *cr;
68 	int i;
69 	double t, dt = 2 * M_PI / (petal_count * 2);
70 	double x1, y1, x2, y2, x3, y3;
71 
72 	cr = cairo_create(surface);
73 	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
74 	cairo_set_source_rgba(cr, 0, 0, 0, 0);
75 	cairo_paint(cr);
76 
77 	cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
78 	cairo_translate(cr, width / 2, height / 2);
79 	cairo_move_to(cr, cos(0) * r1, sin(0) * r1);
80 	for (t = 0, i = 0; i < petal_count; i++, t += dt * 2) {
81 		x1 = cos(t) * r1;
82 		y1 = sin(t) * r1;
83 		x2 = cos(t + dt) * r2;
84 		y2 = sin(t + dt) * r2;
85 		x3 = cos(t + 2 * dt) * r1;
86 		y3 = sin(t + 2 * dt) * r1;
87 
88 		cairo_curve_to(cr,
89 			       x1 - y1 * u, y1 + x1 * u,
90 			       x2 + y2 * v, y2 - x2 * v,
91 			       x2, y2);
92 
93 		cairo_curve_to(cr,
94 			       x2 - y2 * v, y2 + x2 * v,
95 			       x3 + y3 * u, y3 - x3 * u,
96 			       x3, y3);
97 	}
98 
99 	cairo_close_path(cr);
100 	set_random_color(cr);
101 	cairo_fill_preserve(cr);
102 	set_random_color(cr);
103 	cairo_stroke(cr);
104 
105 	cairo_destroy(cr);
106 }
107 
108 static void
resize_handler(struct widget * widget,int32_t width,int32_t height,void * data)109 resize_handler(struct widget *widget,
110 	       int32_t width, int32_t height, void *data)
111 {
112 	struct flower *flower = data;
113 
114 	/* Don't resize me */
115 	widget_set_size(flower->widget, flower->width, flower->height);
116 }
117 
118 static void
redraw_handler(struct widget * widget,void * data)119 redraw_handler(struct widget *widget, void *data)
120 {
121 	struct flower *flower = data;
122 	cairo_surface_t *surface;
123 
124 	surface = window_get_surface(flower->window);
125 	if (surface == NULL ||
126 	    cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
127 		fprintf(stderr, "failed to create cairo egl surface\n");
128 		return;
129 	}
130 
131 	draw_stuff(surface, flower->width, flower->height);
132 	cairo_surface_destroy(surface);
133 }
134 
135 static void
button_handler(struct widget * widget,struct input * input,uint32_t time,uint32_t button,enum wl_pointer_button_state state,void * data)136 button_handler(struct widget *widget,
137 	       struct input *input, uint32_t time,
138 	       uint32_t button, enum wl_pointer_button_state state, void *data)
139 {
140 	struct flower *flower = data;
141 
142 	switch (button) {
143 	case BTN_LEFT:
144 		if (state == WL_POINTER_BUTTON_STATE_PRESSED)
145 			window_move(flower->window, input,
146 				    display_get_serial(flower->display));
147 		break;
148 	case BTN_MIDDLE:
149 		if (state == WL_POINTER_BUTTON_STATE_PRESSED)
150 			widget_schedule_redraw(widget);
151 		break;
152 	case BTN_RIGHT:
153 		if (state == WL_POINTER_BUTTON_STATE_PRESSED)
154 			window_show_frame_menu(flower->window, input, time);
155 		break;
156 	}
157 }
158 
159 static void
touch_down_handler(struct widget * widget,struct input * input,uint32_t serial,uint32_t time,int32_t id,float x,float y,void * data)160 touch_down_handler(struct widget *widget, struct input *input,
161 		   uint32_t serial, uint32_t time, int32_t id,
162 		   float x, float y, void *data)
163 {
164 	struct flower *flower = data;
165 	window_move(flower->window, input, display_get_serial(flower->display));
166 }
167 
main(int argc,char * argv[])168 int main(int argc, char *argv[])
169 {
170 	struct flower flower;
171 	struct display *d;
172 	struct timeval tv;
173 
174 	d = display_create(&argc, argv);
175 	if (d == NULL) {
176 		fprintf(stderr, "failed to create display: %s\n",
177 			strerror(errno));
178 		return -1;
179 	}
180 
181 	gettimeofday(&tv, NULL);
182 	srandom(tv.tv_usec);
183 
184 	flower.width = 200;
185 	flower.height = 200;
186 	flower.display = d;
187 	flower.window = window_create(d);
188 	flower.widget = window_add_widget(flower.window, &flower);
189 	window_set_title(flower.window, "Flower");
190 
191 	widget_set_resize_handler(flower.widget, resize_handler);
192 	widget_set_redraw_handler(flower.widget, redraw_handler);
193 	widget_set_button_handler(flower.widget, button_handler);
194 	widget_set_default_cursor(flower.widget, CURSOR_HAND1);
195 	widget_set_touch_down_handler(flower.widget, touch_down_handler);
196 
197 	window_schedule_resize(flower.window, flower.width, flower.height);
198 
199 	display_run(d);
200 
201 	widget_destroy(flower.widget);
202 	window_destroy(flower.window);
203 	display_destroy(d);
204 
205 	return 0;
206 }
207