compositor-x11: Rename the output make to "weston-X11"
[platform/upstream/weston.git] / clients / transformed.c
1 /*
2  * Copyright © 2008 Kristian Høgsberg
3  * Copyright © 2012 Intel Corporation
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and its
6  * documentation for any purpose is hereby granted without fee, provided that
7  * the above copyright notice appear in all copies and that both that copyright
8  * notice and this permission notice appear in supporting documentation, and
9  * that the name of the copyright holders not be used in advertising or
10  * publicity pertaining to distribution of the software without specific,
11  * written prior permission.  The copyright holders make no representations
12  * about the suitability of this software for any purpose.  It is provided "as
13  * is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21  * OF THIS 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 <math.h>
31 #include <cairo.h>
32
33 #include <linux/input.h>
34 #include <wayland-client.h>
35 #include "window.h"
36
37 struct transformed {
38         struct display *display;
39         struct window *window;
40         struct widget *widget;
41         int width, height;
42         int fullscreen;
43 };
44
45 static void
46 draw_stuff(cairo_t *cr, int width, int height)
47 {
48         cairo_matrix_t m;
49         cairo_get_matrix (cr, &m);
50
51         cairo_translate(cr, width / 2, height / 2);
52         cairo_scale(cr, width / 2, height / 2);
53
54         cairo_set_source_rgba(cr, 0, 0, 0.3, 1.0);
55         cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
56         cairo_rectangle(cr, -1, -1, 2, 2);
57         cairo_fill(cr);
58
59         cairo_set_source_rgb(cr, 1, 0, 0);
60         cairo_move_to(cr, 0,  0);
61         cairo_line_to(cr, 0, -1);
62
63         cairo_save(cr);
64         cairo_set_matrix(cr, &m);
65         cairo_set_line_width(cr, 2.0);
66         cairo_stroke(cr);
67         cairo_restore(cr);
68
69         cairo_set_source_rgb(cr, 0, 1, 0);
70         cairo_move_to(cr, 0, 0);
71         cairo_line_to(cr, 1, 0);
72
73         cairo_save(cr);
74         cairo_set_matrix(cr, &m);
75         cairo_set_line_width(cr, 2.0);
76         cairo_stroke(cr);
77         cairo_restore(cr);
78
79         cairo_set_source_rgb(cr, 1, 1, 1);
80         cairo_move_to(cr, 0, 0);
81         cairo_line_to(cr, 0, 1);
82         cairo_move_to(cr,  0, 0);
83         cairo_line_to(cr, -1, 0);
84
85         cairo_save(cr);
86         cairo_set_matrix(cr, &m);
87         cairo_set_line_width(cr, 2.0);
88         cairo_stroke(cr);
89         cairo_restore(cr);
90
91         cairo_destroy(cr);
92 }
93
94 static void
95 fullscreen_handler(struct window *window, void *data)
96 {
97         struct transformed *transformed = data;
98
99         transformed->fullscreen ^= 1;
100         window_set_fullscreen(window, transformed->fullscreen);
101 }
102
103 static void
104 redraw_handler(struct widget *widget, void *data)
105 {
106         struct transformed *transformed = data;
107         struct rectangle allocation;
108         cairo_surface_t *surface;
109         cairo_t *cr;
110
111         surface = window_get_surface(transformed->window);
112         if (surface == NULL ||
113             cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
114                 fprintf(stderr, "failed to create cairo egl surface\n");
115                 return;
116         }
117
118         widget_get_allocation(transformed->widget, &allocation);
119
120         cr = widget_cairo_create(widget);
121         draw_stuff(cr, allocation.width, allocation.height);
122
123         cairo_surface_destroy(surface);
124 }
125
126 static void
127 output_handler(struct window *window, struct output *output, int enter,
128                void *data)
129 {
130         if (!enter)
131                 return;
132
133         window_set_buffer_transform(window, output_get_transform(output));
134         window_set_buffer_scale(window, output_get_scale(output));
135         window_schedule_redraw(window);
136 }
137
138 static void
139 key_handler(struct window *window, struct input *input, uint32_t time,
140             uint32_t key, uint32_t sym, enum wl_keyboard_key_state state,
141             void *data)
142 {
143         int transform, scale;
144
145         if (state == WL_KEYBOARD_KEY_STATE_RELEASED)
146                 return;
147
148         transform = window_get_buffer_transform (window);
149         scale = window_get_buffer_scale (window);
150         switch (sym) {
151         case XKB_KEY_Left:
152                 if (transform == 0)
153                         transform = 3;
154                 else if (transform == 4)
155                         transform = 7;
156                 else
157                         transform--;
158                 break;
159
160         case XKB_KEY_Right:
161                 if (transform == 3)
162                         transform = 0;
163                 else if (transform == 7)
164                         transform = 4;
165                 else
166                         transform++;
167                 break;
168
169         case XKB_KEY_space:
170                 if (transform >= 4)
171                         transform -= 4;
172                 else
173                         transform += 4;
174                 break;
175
176         case XKB_KEY_z:
177                 if (scale == 1)
178                         scale = 2;
179                 else
180                         scale = 1;
181                 break;
182         }
183
184         printf ("setting buffer transform to %d\n", transform);
185         printf ("setting buffer scale to %d\n", scale);
186         window_set_buffer_transform(window, transform);
187         window_set_buffer_scale(window, scale);
188         window_schedule_redraw(window);
189 }
190
191 static void
192 button_handler(struct widget *widget,
193                struct input *input, uint32_t time,
194                uint32_t button, enum wl_pointer_button_state state, void *data)
195 {
196         struct transformed *transformed = data;
197
198         switch (button) {
199         case BTN_LEFT:
200                 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
201                         window_move(transformed->window, input,
202                                     display_get_serial(transformed->display));
203                 break;
204         case BTN_MIDDLE:
205                 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
206                         widget_schedule_redraw(widget);
207                 break;
208         case BTN_RIGHT:
209                 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
210                         window_show_frame_menu(transformed->window, input, time);
211                 break;
212         }
213 }
214
215 static void
216 touch_handler(struct widget *widget, struct input *input, 
217                    uint32_t serial, uint32_t time, int32_t id, 
218                    float x, float y, void *data)
219 {
220         struct transformed *transformed = data;
221         window_move(transformed->window, input, display_get_serial(transformed->display));
222 }
223
224 static void
225 usage(int error_code)
226 {
227         fprintf(stderr, "Usage: transformed [OPTIONS]\n\n"
228                 "   -d\t\tUse \"driver\" fullscreen method\n"
229                 "   -w <width>\tSet window width to <width>\n"
230                 "   -h <height>\tSet window height to <height>\n"
231                 "   --help\tShow this help text\n\n");
232
233         exit(error_code);
234 }
235
236 int main(int argc, char *argv[])
237 {
238         struct transformed transformed;
239         struct display *d;
240         int i;
241
242         transformed.width = 500;
243         transformed.height = 250;
244         transformed.fullscreen = 0;
245
246         for (i = 1; i < argc; i++) {
247                 if (strcmp(argv[i], "-w") == 0) {
248                         if (++i >= argc)
249                                 usage(EXIT_FAILURE);
250
251                         transformed.width = atol(argv[i]);
252                 } else if (strcmp(argv[i], "-h") == 0) {
253                         if (++i >= argc)
254                                 usage(EXIT_FAILURE);
255
256                         transformed.height = atol(argv[i]);
257                 } else if (strcmp(argv[i], "--help") == 0)
258                         usage(EXIT_SUCCESS);
259                 else
260                         usage(EXIT_FAILURE);
261         }
262
263         d = display_create(&argc, argv);
264         if (d == NULL) {
265                 fprintf(stderr, "failed to create display: %m\n");
266                 return -1;
267         }
268
269         transformed.display = d;
270         transformed.window = window_create(d);
271         transformed.widget =
272                 window_add_widget(transformed.window, &transformed);
273
274         window_set_title(transformed.window, "Transformed");
275
276         widget_set_transparent(transformed.widget, 0);
277         widget_set_default_cursor(transformed.widget, CURSOR_BLANK);
278
279         widget_set_redraw_handler(transformed.widget, redraw_handler);
280         widget_set_button_handler(transformed.widget, button_handler);
281
282         widget_set_touch_down_handler(transformed.widget, touch_handler);
283
284         window_set_key_handler(transformed.window, key_handler);
285         window_set_fullscreen_handler(transformed.window, fullscreen_handler);
286         window_set_output_handler(transformed.window, output_handler);
287
288         window_set_user_data(transformed.window, &transformed);
289         window_schedule_resize(transformed.window,
290                                transformed.width, transformed.height);
291
292         display_run(d);
293         widget_destroy(transformed.widget);
294         window_destroy(transformed.window);
295         display_destroy(d);
296
297         return 0;
298 }