blob: 75c1250e20f8398204767cd6885609b67df265a3 [file] [log] [blame]
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +02001/*
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +02002 * Copyright © 2008 Kristian Høgsberg
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +02003 * 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
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020024#include <stdint.h>
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020025#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020028#include <math.h>
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020029#include <cairo.h>
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020030
31#include <linux/input.h>
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020032#include <wayland-client.h>
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020033#include "window.h"
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020034
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020035struct transformed {
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020036 struct display *display;
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020037 struct window *window;
38 struct widget *widget;
39 int width, height;
40 int fullscreen;
Ander Conselvan de Oliveirab77aa062012-12-14 13:37:24 -020041 enum wl_shell_surface_fullscreen_method fullscreen_method;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020042};
43
44static void
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020045update_transform(cairo_t *cr, enum wl_output_transform transform)
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020046{
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020047 double angle;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020048
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020049 cairo_matrix_t m;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020050
51 switch(transform) {
52 case WL_OUTPUT_TRANSFORM_FLIPPED:
53 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
54 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
55 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020056 cairo_matrix_init(&m, -1, 0, 0, 1, 0, 0);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020057 break;
58 default:
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020059 cairo_matrix_init_identity(&m);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020060 break;
61 }
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020062 switch (transform) {
63 case WL_OUTPUT_TRANSFORM_NORMAL:
64 case WL_OUTPUT_TRANSFORM_FLIPPED:
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020065 default:
66 angle = 0;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020067 break;
68 case WL_OUTPUT_TRANSFORM_90:
69 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020070 angle = M_PI_2;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020071 break;
72 case WL_OUTPUT_TRANSFORM_180:
73 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020074 angle = M_PI;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020075 break;
76 case WL_OUTPUT_TRANSFORM_270:
77 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020078 angle = M_PI + M_PI_2;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020079 break;
80 }
81
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020082 cairo_rotate(cr, angle);
83 cairo_transform(cr, &m);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020084}
85
86static void
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020087draw_stuff(cairo_surface_t *surface, int width, int height, int transform)
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020088{
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020089 cairo_t *cr;
90 int tmp;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020091
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020092 if (transform & 1) {
93 tmp = width;
94 width = height;
95 height = tmp;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020096 }
97
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020098 cr = cairo_create(surface);
99
100 cairo_identity_matrix(cr);
101 cairo_translate(cr, width / 2, height / 2);
102 cairo_scale(cr, width / 2, height / 2);
103
104 update_transform(cr, transform);
105
106 cairo_set_source_rgba(cr, 0, 0, 0.3, 1.0);
107 cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
108 cairo_rectangle(cr, -1, -1, 2, 2);
109 cairo_fill(cr);
110
111 cairo_set_source_rgb(cr, 1, 0, 0);
112 cairo_move_to(cr, 0, 0);
113 cairo_line_to(cr, 0, -1);
114
115 cairo_save(cr);
116 cairo_identity_matrix(cr);
117 cairo_set_line_width(cr, 2.0);
118 cairo_stroke(cr);
119 cairo_restore(cr);
120
121 cairo_set_source_rgb(cr, 0, 1, 0);
122 cairo_move_to(cr, 0, 0);
123 cairo_line_to(cr, 1, 0);
124
125 cairo_save(cr);
126 cairo_identity_matrix(cr);
127 cairo_set_line_width(cr, 2.0);
128 cairo_stroke(cr);
129 cairo_restore(cr);
130
131 cairo_set_source_rgb(cr, 1, 1, 1);
132 cairo_move_to(cr, 0, 0);
133 cairo_line_to(cr, 0, 1);
134 cairo_move_to(cr, 0, 0);
135 cairo_line_to(cr, -1, 0);
136
137 cairo_save(cr);
138 cairo_identity_matrix(cr);
139 cairo_set_line_width(cr, 2.0);
140 cairo_stroke(cr);
141 cairo_restore(cr);
142
143 cairo_destroy(cr);
144}
145
146static void
147fullscreen_handler(struct window *window, void *data)
148{
149 struct transformed *transformed = data;
150
151 transformed->fullscreen ^= 1;
152 window_set_fullscreen(window, transformed->fullscreen);
153}
154
155static void
Ander Conselvan de Oliveirab77aa062012-12-14 13:37:24 -0200156resize_handler(struct widget *widget, int width, int height, void *data)
157{
158 struct transformed *transformed = data;
159
160 if (transformed->fullscreen_method !=
161 WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT)
162 widget_set_size(widget, transformed->width, transformed->height);
163}
164
165static void
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200166redraw_handler(struct widget *widget, void *data)
167{
168 struct transformed *transformed = data;
169 struct rectangle allocation;
170 cairo_surface_t *surface;
171 int transform;
172
173 surface = window_get_surface(transformed->window);
174 if (surface == NULL ||
175 cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
176 fprintf(stderr, "failed to create cairo egl surface\n");
177 return;
178 }
179
180 widget_get_allocation(transformed->widget, &allocation);
181 transform = window_get_buffer_transform(transformed->window);
182
183 draw_stuff(surface, allocation.width, allocation.height, transform);
184
185 cairo_surface_destroy(surface);
186}
187
188static void
189output_handler(struct window *window, struct output *output, int enter,
190 void *data)
191{
192 if (!enter)
193 return;
194
195 window_set_buffer_transform(window, output_get_transform(output));
196 window_schedule_redraw(window);
197}
198
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200199static void
200button_handler(struct widget *widget,
201 struct input *input, uint32_t time,
202 uint32_t button, enum wl_pointer_button_state state, void *data)
203{
204 struct transformed *transformed = data;
205
206 switch (button) {
207 case BTN_LEFT:
208 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
209 window_move(transformed->window, input,
210 display_get_serial(transformed->display));
211 break;
212 case BTN_MIDDLE:
213 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
214 widget_schedule_redraw(widget);
215 break;
216 case BTN_RIGHT:
217 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
218 window_show_frame_menu(transformed->window, input, time);
219 break;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200220 }
221}
222
Ander Conselvan de Oliveirab77aa062012-12-14 13:37:24 -0200223static void
224usage(int error_code)
225{
226 fprintf(stderr, "Usage: transformed [OPTIONS]\n\n"
227 " -d\t\tUse \"driver\" fullscreen method\n"
228 " -w <width>\tSet window width to <width>\n"
229 " -h <height>\tSet window height to <height>\n"
230 " --help\tShow this help text\n\n");
231
232 exit(error_code);
233}
234
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200235int main(int argc, char *argv[])
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200236{
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200237 struct transformed transformed;
238 struct display *d;
Ander Conselvan de Oliveirab77aa062012-12-14 13:37:24 -0200239 int i;
240
241 transformed.width = 500;
242 transformed.height = 250;
243 transformed.fullscreen = 0;
244 transformed.fullscreen_method =
245 WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
246
247 for (i = 1; i < argc; i++) {
248 if (strcmp(argv[i], "-d") == 0) {
249 transformed.fullscreen_method =
250 WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER;
251 } else if (strcmp(argv[i], "-w") == 0) {
252 if (++i >= argc)
253 usage(EXIT_FAILURE);
254
255 transformed.width = atol(argv[i]);
256 } else if (strcmp(argv[i], "-h") == 0) {
257 if (++i >= argc)
258 usage(EXIT_FAILURE);
259
260 transformed.height = atol(argv[i]);
261 } else if (strcmp(argv[i], "--help") == 0)
262 usage(EXIT_SUCCESS);
263 else
264 usage(EXIT_FAILURE);
265 }
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200266
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200267 d = display_create(argc, argv);
268 if (d == NULL) {
269 fprintf(stderr, "failed to create display: %m\n");
270 return -1;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200271 }
272
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200273 transformed.display = d;
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200274 transformed.window = window_create(d);
275 transformed.widget =
276 window_add_widget(transformed.window, &transformed);
Ander Conselvan de Oliveirab77aa062012-12-14 13:37:24 -0200277
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200278 window_set_title(transformed.window, "Transformed");
Ander Conselvan de Oliveirab77aa062012-12-14 13:37:24 -0200279 window_set_fullscreen_method(transformed.window,
280 transformed.fullscreen_method);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200281
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200282 widget_set_transparent(transformed.widget, 0);
Kristian Høgsbergbf74d522012-11-30 14:54:35 -0500283 widget_set_default_cursor(transformed.widget, CURSOR_BLANK);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200284
Ander Conselvan de Oliveirab77aa062012-12-14 13:37:24 -0200285 widget_set_resize_handler(transformed.widget, resize_handler);
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200286 widget_set_redraw_handler(transformed.widget, redraw_handler);
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200287 widget_set_button_handler(transformed.widget, button_handler);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200288
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200289 window_set_fullscreen_handler(transformed.window, fullscreen_handler);
290 window_set_output_handler(transformed.window, output_handler);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200291
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200292 window_set_user_data(transformed.window, &transformed);
293 window_schedule_resize(transformed.window,
294 transformed.width, transformed.height);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200295
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200296 display_run(d);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200297
298 return 0;
299}