blob: be840d933008f358c036c0c495485cb6e02ab0ef [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 Oliveira1b4312d2012-11-27 17:03:44 +020041};
42
43static void
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020044update_transform(cairo_t *cr, enum wl_output_transform transform)
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020045{
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020046 double angle;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020047
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020048 cairo_matrix_t m;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020049
50 switch(transform) {
51 case WL_OUTPUT_TRANSFORM_FLIPPED:
52 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
53 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
54 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020055 cairo_matrix_init(&m, -1, 0, 0, 1, 0, 0);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020056 break;
57 default:
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020058 cairo_matrix_init_identity(&m);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020059 break;
60 }
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020061 switch (transform) {
62 case WL_OUTPUT_TRANSFORM_NORMAL:
63 case WL_OUTPUT_TRANSFORM_FLIPPED:
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020064 default:
65 angle = 0;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020066 break;
67 case WL_OUTPUT_TRANSFORM_90:
68 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020069 angle = M_PI_2;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020070 break;
71 case WL_OUTPUT_TRANSFORM_180:
72 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020073 angle = M_PI;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020074 break;
75 case WL_OUTPUT_TRANSFORM_270:
76 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020077 angle = M_PI + M_PI_2;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020078 break;
79 }
80
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020081 cairo_rotate(cr, angle);
82 cairo_transform(cr, &m);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020083}
84
85static void
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020086draw_stuff(cairo_surface_t *surface, int width, int height, int transform)
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020087{
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020088 cairo_t *cr;
89 int tmp;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020090
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020091 if (transform & 1) {
92 tmp = width;
93 width = height;
94 height = tmp;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +020095 }
96
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +020097 cr = cairo_create(surface);
98
99 cairo_identity_matrix(cr);
100 cairo_translate(cr, width / 2, height / 2);
101 cairo_scale(cr, width / 2, height / 2);
102
103 update_transform(cr, transform);
104
105 cairo_set_source_rgba(cr, 0, 0, 0.3, 1.0);
106 cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
107 cairo_rectangle(cr, -1, -1, 2, 2);
108 cairo_fill(cr);
109
110 cairo_set_source_rgb(cr, 1, 0, 0);
111 cairo_move_to(cr, 0, 0);
112 cairo_line_to(cr, 0, -1);
113
114 cairo_save(cr);
115 cairo_identity_matrix(cr);
116 cairo_set_line_width(cr, 2.0);
117 cairo_stroke(cr);
118 cairo_restore(cr);
119
120 cairo_set_source_rgb(cr, 0, 1, 0);
121 cairo_move_to(cr, 0, 0);
122 cairo_line_to(cr, 1, 0);
123
124 cairo_save(cr);
125 cairo_identity_matrix(cr);
126 cairo_set_line_width(cr, 2.0);
127 cairo_stroke(cr);
128 cairo_restore(cr);
129
130 cairo_set_source_rgb(cr, 1, 1, 1);
131 cairo_move_to(cr, 0, 0);
132 cairo_line_to(cr, 0, 1);
133 cairo_move_to(cr, 0, 0);
134 cairo_line_to(cr, -1, 0);
135
136 cairo_save(cr);
137 cairo_identity_matrix(cr);
138 cairo_set_line_width(cr, 2.0);
139 cairo_stroke(cr);
140 cairo_restore(cr);
141
142 cairo_destroy(cr);
143}
144
145static void
146fullscreen_handler(struct window *window, void *data)
147{
148 struct transformed *transformed = data;
149
150 transformed->fullscreen ^= 1;
151 window_set_fullscreen(window, transformed->fullscreen);
152}
153
154static void
155redraw_handler(struct widget *widget, void *data)
156{
157 struct transformed *transformed = data;
158 struct rectangle allocation;
159 cairo_surface_t *surface;
160 int transform;
161
162 surface = window_get_surface(transformed->window);
163 if (surface == NULL ||
164 cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
165 fprintf(stderr, "failed to create cairo egl surface\n");
166 return;
167 }
168
169 widget_get_allocation(transformed->widget, &allocation);
170 transform = window_get_buffer_transform(transformed->window);
171
172 draw_stuff(surface, allocation.width, allocation.height, transform);
173
174 cairo_surface_destroy(surface);
175}
176
177static void
178output_handler(struct window *window, struct output *output, int enter,
179 void *data)
180{
181 if (!enter)
182 return;
183
184 window_set_buffer_transform(window, output_get_transform(output));
185 window_schedule_redraw(window);
186}
187
188static int
189motion_handler(struct widget *widget, struct input *input,
190 uint32_t time, float x, float y, void *data)
191{
192 return CURSOR_BLANK;
193}
194
195static void
196button_handler(struct widget *widget,
197 struct input *input, uint32_t time,
198 uint32_t button, enum wl_pointer_button_state state, void *data)
199{
200 struct transformed *transformed = data;
201
202 switch (button) {
203 case BTN_LEFT:
204 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
205 window_move(transformed->window, input,
206 display_get_serial(transformed->display));
207 break;
208 case BTN_MIDDLE:
209 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
210 widget_schedule_redraw(widget);
211 break;
212 case BTN_RIGHT:
213 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
214 window_show_frame_menu(transformed->window, input, time);
215 break;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200216 }
217}
218
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200219int main(int argc, char *argv[])
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200220{
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200221 struct transformed transformed;
222 struct display *d;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200223
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200224 d = display_create(argc, argv);
225 if (d == NULL) {
226 fprintf(stderr, "failed to create display: %m\n");
227 return -1;
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200228 }
229
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200230 transformed.width = 500;
231 transformed.height = 250;
232 transformed.display = d;
233 transformed.fullscreen = 0;
234 transformed.window = window_create(d);
235 transformed.widget =
236 window_add_widget(transformed.window, &transformed);
237 window_set_title(transformed.window, "Transformed");
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200238
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200239 widget_set_transparent(transformed.widget, 0);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200240
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200241 widget_set_redraw_handler(transformed.widget, redraw_handler);
242 widget_set_motion_handler(transformed.widget, motion_handler);
243 widget_set_button_handler(transformed.widget, button_handler);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200244
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200245 window_set_fullscreen_handler(transformed.window, fullscreen_handler);
246 window_set_output_handler(transformed.window, output_handler);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200247
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200248 window_set_user_data(transformed.window, &transformed);
249 window_schedule_resize(transformed.window,
250 transformed.width, transformed.height);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200251
Ander Conselvan de Oliveiraa06a8602012-11-30 17:34:26 +0200252 display_run(d);
Ander Conselvan de Oliveira1b4312d2012-11-27 17:03:44 +0200253
254 return 0;
255}