blob: 1c318e82d01df48b178b0aac6944194b11172b39 [file] [log] [blame]
Kristian Høgsbergffd710e2008-12-02 15:15:01 -05001/*
2 * Copyright © 2008 Kristian Høgsberg
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22
Kristian Høgsberg61017b12008-11-02 18:51:48 -050023#include <stdint.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
Kristian Høgsberg61017b12008-11-02 18:51:48 -050027#include <fcntl.h>
28#include <unistd.h>
29#include <math.h>
30#include <time.h>
31#include <cairo.h>
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -050032#include <glib.h>
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -050033#include <cairo-drm.h>
Kristian Høgsberg61017b12008-11-02 18:51:48 -050034
Kristian Høgsberg5ee1a602008-12-11 23:18:45 -050035#include <linux/input.h>
Kristian Høgsberg61017b12008-11-02 18:51:48 -050036#include "wayland-client.h"
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -050037#include "wayland-glib.h"
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050038
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -050039#include "window.h"
Kristian Høgsberg8a9cda82008-11-03 15:31:30 -050040
Kristian Høgsberg61017b12008-11-02 18:51:48 -050041struct window {
Kristian Høgsberg40979232008-11-25 22:40:39 -050042 struct wl_display *display;
Kristian Høgsbergd2412e22008-12-15 20:35:24 -050043 struct wl_compositor *compositor;
Kristian Høgsberg61017b12008-11-02 18:51:48 -050044 struct wl_surface *surface;
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -050045 const char *title;
Kristian Høgsberg94448c02008-12-30 11:03:33 -050046 struct rectangle allocation, saved_allocation, screen_allocation;
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -050047 int minimum_width, minimum_height;
Kristian Høgsberg40979232008-11-25 22:40:39 -050048 int margin;
Kristian Høgsbergc492b482008-12-12 12:00:02 -050049 int drag_x, drag_y;
Kristian Høgsberg61017b12008-11-02 18:51:48 -050050 int state;
Kristian Høgsberg0395f302008-12-22 12:14:50 -050051 int fullscreen;
Kristian Høgsberg94448c02008-12-30 11:03:33 -050052 struct wl_input_device *grab_device;
Kristian Høgsberg61017b12008-11-02 18:51:48 -050053 uint32_t name;
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -050054 cairo_drm_context_t *ctx;
Kristian Høgsberg78231c82008-11-08 15:06:01 -050055
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -050056 cairo_surface_t *cairo_surface;
Kristian Høgsberg8a9cda82008-11-03 15:31:30 -050057
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -050058 window_resize_handler_t resize_handler;
Kristian Høgsberg6e83d582008-12-08 00:01:36 -050059 window_key_handler_t key_handler;
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -050060 void *user_data;
Kristian Høgsberg61017b12008-11-02 18:51:48 -050061};
62
Kristian Høgsberge4feb562008-11-08 18:53:37 -050063static void
64rounded_rect(cairo_t *cr, int x0, int y0, int x1, int y1, int radius)
65{
66 cairo_move_to(cr, x0, y0 + radius);
67 cairo_arc(cr, x0 + radius, y0 + radius, radius, M_PI, 3 * M_PI / 2);
68 cairo_line_to(cr, x1 - radius, y0);
69 cairo_arc(cr, x1 - radius, y0 + radius, radius, 3 * M_PI / 2, 2 * M_PI);
70 cairo_line_to(cr, x1, y1 - radius);
71 cairo_arc(cr, x1 - radius, y1 - radius, radius, 0, M_PI / 2);
72 cairo_line_to(cr, x0 + radius, y1);
73 cairo_arc(cr, x0 + radius, y1 - radius, radius, M_PI / 2, M_PI);
74 cairo_close_path(cr);
75}
76
Kristian Høgsberg0395f302008-12-22 12:14:50 -050077static void
78window_draw_decorations(struct window *window)
Kristian Høgsberg61017b12008-11-02 18:51:48 -050079{
Kristian Høgsberg61017b12008-11-02 18:51:48 -050080 cairo_t *cr;
Kristian Høgsberg40979232008-11-25 22:40:39 -050081 int border = 2, radius = 5;
Kristian Høgsbergca1d1f62008-11-03 06:59:52 -050082 cairo_text_extents_t extents;
Kristian Høgsberge4feb562008-11-08 18:53:37 -050083 cairo_pattern_t *gradient, *outline, *bright, *dim;
Kristian Høgsbergde31d5c2008-12-18 17:55:33 -050084 struct wl_visual *visual;
Kristian Høgsberg0395f302008-12-22 12:14:50 -050085 int width, height;
Kristian Høgsberg61017b12008-11-02 18:51:48 -050086
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -050087 window->cairo_surface =
88 cairo_drm_surface_create(window->ctx,
89 CAIRO_CONTENT_COLOR_ALPHA,
90 window->allocation.width,
91 window->allocation.height);
Kristian Høgsberg61017b12008-11-02 18:51:48 -050092
Kristian Høgsberge4feb562008-11-08 18:53:37 -050093 outline = cairo_pattern_create_rgb(0.1, 0.1, 0.1);
Kristian Høgsberge9d550b2008-11-19 00:49:39 -050094 bright = cairo_pattern_create_rgb(0.8, 0.8, 0.8);
Kristian Høgsberge4feb562008-11-08 18:53:37 -050095 dim = cairo_pattern_create_rgb(0.4, 0.4, 0.4);
96
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -050097 cr = cairo_create(window->cairo_surface);
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050098
Kristian Høgsberg0395f302008-12-22 12:14:50 -050099 width = window->allocation.width - window->margin * 2;
100 height = window->allocation.height - window->margin * 2;
101
Kristian Høgsberg40979232008-11-25 22:40:39 -0500102 cairo_translate(cr, window->margin + 7, window->margin + 5);
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -0500103 cairo_set_line_width (cr, border);
Kristian Høgsberge9d550b2008-11-19 00:49:39 -0500104 cairo_set_source_rgba(cr, 0, 0, 0, 0.7);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500105 rounded_rect(cr, 0, 0, width, height, radius);
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -0500106 cairo_fill(cr);
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -0500107
108#ifdef SLOW_BUT_PWETTY
109 /* FIXME: Aw, pretty drop shadows now have to fallback to sw.
110 * Ideally we should have convolution filters in cairo, but we
111 * can also fallback to compositing the shadow image a bunch
112 * of times according to the blur kernel. */
113 {
114 cairo_surface_t *map;
115
116 map = cairo_drm_surface_map(window->cairo_surface);
117 blur_surface(map);
118 cairo_drm_surface_unmap(window->cairo_surface, map);
119 }
120#endif
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -0500121
Kristian Høgsberge9d550b2008-11-19 00:49:39 -0500122 cairo_translate(cr, -7, -5);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500123 cairo_set_line_width (cr, border);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500124 rounded_rect(cr, 1, 1, width - 1, height - 1, radius);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500125 cairo_set_source(cr, outline);
126 cairo_stroke(cr);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500127 rounded_rect(cr, 2, 2, width - 2, height - 2, radius - 1);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500128 cairo_set_source(cr, bright);
129 cairo_stroke(cr);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500130 rounded_rect(cr, 3, 3, width - 2, height - 2, radius - 1);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500131 cairo_set_source(cr, dim);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500132 cairo_stroke(cr);
Kristian Høgsbergca1d1f62008-11-03 06:59:52 -0500133
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500134 rounded_rect(cr, 2, 2, width - 2, height - 2, radius - 1);
Kristian Høgsberg6e635f32008-11-09 09:15:46 -0500135 gradient = cairo_pattern_create_linear (0, 0, 0, 100);
Kristian Høgsberge9d550b2008-11-19 00:49:39 -0500136 cairo_pattern_add_color_stop_rgb(gradient, 0, 0.6, 0.6, 0.4);
137 cairo_pattern_add_color_stop_rgb(gradient, 1, 0.8, 0.8, 0.7);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500138 cairo_set_source(cr, gradient);
139 cairo_fill(cr);
140 cairo_pattern_destroy(gradient);
141
142 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
143 cairo_move_to(cr, 10, 50);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500144 cairo_line_to(cr, width - 10, 50);
145 cairo_line_to(cr, width - 10, height - 10);
146 cairo_line_to(cr, 10, height - 10);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500147 cairo_close_path(cr);
148 cairo_set_source(cr, dim);
149 cairo_stroke(cr);
150
151 cairo_move_to(cr, 11, 51);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500152 cairo_line_to(cr, width - 10, 51);
153 cairo_line_to(cr, width - 10, height - 10);
154 cairo_line_to(cr, 11, height - 10);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500155 cairo_close_path(cr);
156 cairo_set_source(cr, bright);
157 cairo_stroke(cr);
158
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500159 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
160 cairo_set_font_size(cr, 14);
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500161 cairo_text_extents(cr, window->title, &extents);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500162 cairo_move_to(cr, (width - extents.width) / 2, 10 - extents.y_bearing);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500163 cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
164 cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
165 cairo_set_line_width (cr, 4);
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500166 cairo_text_path(cr, window->title);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500167 cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
168 cairo_stroke_preserve(cr);
169 cairo_set_source_rgb(cr, 1, 1, 1);
170 cairo_fill(cr);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500171 cairo_destroy(cr);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500172
Kristian Høgsbergde31d5c2008-12-18 17:55:33 -0500173 visual = wl_display_get_premultiplied_argb_visual(window->display);
Kristian Høgsberg40979232008-11-25 22:40:39 -0500174 wl_surface_attach(window->surface,
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -0500175 cairo_drm_surface_get_name(window->cairo_surface),
176 window->allocation.width,
177 window->allocation.height,
178 cairo_drm_surface_get_stride(window->cairo_surface),
Kristian Høgsbergde31d5c2008-12-18 17:55:33 -0500179 visual);
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500180
Kristian Høgsbergfbdbbdc2008-11-28 17:06:06 -0500181 wl_surface_map(window->surface,
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500182 window->allocation.x - window->margin,
183 window->allocation.y - window->margin,
184 window->allocation.width,
185 window->allocation.height);
186}
187
188static void
189window_draw_fullscreen(struct window *window)
190{
191 struct wl_visual *visual;
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500192
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -0500193 window->cairo_surface =
194 cairo_drm_surface_create(window->ctx,
195 CAIRO_CONTENT_COLOR_ALPHA,
196 window->allocation.width,
197 window->allocation.height);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500198
199 visual = wl_display_get_premultiplied_argb_visual(window->display);
200 wl_surface_attach(window->surface,
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -0500201 cairo_drm_surface_get_name(window->cairo_surface),
202 window->allocation.width,
203 window->allocation.height,
204 cairo_drm_surface_get_stride(window->cairo_surface),
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500205 visual);
206
207 wl_surface_map(window->surface,
208 window->allocation.x,
209 window->allocation.y,
210 window->allocation.width,
211 window->allocation.height);
212}
213
214void
215window_draw(struct window *window)
216{
217 if (window->fullscreen)
218 window_draw_fullscreen(window);
219 else
220 window_draw_decorations(window);
Kristian Høgsberg44f36e32008-11-26 12:57:31 -0500221}
222
Kristian Høgsberg94448c02008-12-30 11:03:33 -0500223static void
224window_handle_acknowledge(void *data,
225 struct wl_compositor *compositor,
226 uint32_t key, uint32_t frame)
227{
228 struct window *window = data;
229
230 /* The acknowledge event means that the server
231 * processed our last commit request and we can now
232 * safely free the old window buffer if we resized and
233 * render the next frame into our back buffer.. */
234
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -0500235 if (key == 0 && window->cairo_surface != NULL) {
236 cairo_surface_destroy(window->cairo_surface);
237 window->cairo_surface = NULL;
Kristian Høgsberg94448c02008-12-30 11:03:33 -0500238 }
239}
240
241static void
242window_handle_frame(void *data,
243 struct wl_compositor *compositor,
244 uint32_t frame, uint32_t timestamp)
245{
246}
247
248static const struct wl_compositor_listener compositor_listener = {
249 window_handle_acknowledge,
250 window_handle_frame,
251};
252
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500253enum window_state {
254 WINDOW_STABLE,
255 WINDOW_MOVING,
256 WINDOW_RESIZING_UPPER_LEFT,
257 WINDOW_RESIZING_UPPER_RIGHT,
258 WINDOW_RESIZING_LOWER_LEFT,
259 WINDOW_RESIZING_LOWER_RIGHT
260};
261
262enum location {
263 LOCATION_INTERIOR,
264 LOCATION_UPPER_LEFT,
265 LOCATION_UPPER_RIGHT,
266 LOCATION_LOWER_LEFT,
267 LOCATION_LOWER_RIGHT,
268 LOCATION_OUTSIDE
269};
270
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500271static void
Kristian Høgsberg94448c02008-12-30 11:03:33 -0500272window_handle_motion(void *data, struct wl_input_device *input_device,
273 int32_t x, int32_t y, int32_t sx, int32_t sy)
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500274{
275 struct window *window = data;
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500276
Kristian Høgsberg94448c02008-12-30 11:03:33 -0500277 switch (window->state) {
278 case WINDOW_MOVING:
279 if (window->fullscreen)
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500280 break;
Kristian Høgsberg94448c02008-12-30 11:03:33 -0500281 if (window->grab_device != input_device)
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500282 break;
Kristian Høgsberg94448c02008-12-30 11:03:33 -0500283 window->allocation.x = window->drag_x + x;
284 window->allocation.y = window->drag_y + y;
285 wl_surface_map(window->surface,
286 window->allocation.x - window->margin,
287 window->allocation.y - window->margin,
288 window->allocation.width,
289 window->allocation.height);
290 wl_compositor_commit(window->compositor, 1);
291 break;
292 case WINDOW_RESIZING_LOWER_RIGHT:
293 if (window->fullscreen)
294 break;
295 if (window->grab_device != input_device)
296 break;
297 window->allocation.width = window->drag_x + x;
298 window->allocation.height = window->drag_y + y;
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500299
Kristian Høgsberg94448c02008-12-30 11:03:33 -0500300 if (window->resize_handler)
301 (*window->resize_handler)(window,
302 window->user_data);
Kristian Høgsberg40979232008-11-25 22:40:39 -0500303
Kristian Høgsberg94448c02008-12-30 11:03:33 -0500304 break;
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500305 }
306}
307
Kristian Høgsberg94448c02008-12-30 11:03:33 -0500308static void window_handle_button(void *data, struct wl_input_device *input_device,
309 uint32_t button, uint32_t state,
310 int32_t x, int32_t y, int32_t sx, int32_t sy)
311{
312 struct window *window = data;
313 int32_t left = window->allocation.x;
314 int32_t right = window->allocation.x +
315 window->allocation.width - window->margin * 2;
316 int32_t top = window->allocation.y;
317 int32_t bottom = window->allocation.y +
318 window->allocation.height - window->margin * 2;
319 int grip_size = 16, location;
320
321 if (right - grip_size <= x && x < right &&
322 bottom - grip_size <= y && y < bottom) {
323 location = LOCATION_LOWER_RIGHT;
324 } else if (left <= x && x < right && top <= y && y < bottom) {
325 location = LOCATION_INTERIOR;
326 } else {
327 location = LOCATION_OUTSIDE;
328 }
329
330 if (button == BTN_LEFT && state == 1) {
331 switch (location) {
332 case LOCATION_INTERIOR:
333 window->drag_x = window->allocation.x - x;
334 window->drag_y = window->allocation.y - y;
335 window->state = WINDOW_MOVING;
336 window->grab_device = input_device;
337 break;
338 case LOCATION_LOWER_RIGHT:
339 window->drag_x = window->allocation.width - x;
340 window->drag_y = window->allocation.height - y;
341 window->state = WINDOW_RESIZING_LOWER_RIGHT;
342 window->grab_device = input_device;
343 break;
344 default:
345 window->state = WINDOW_STABLE;
346 break;
347 }
348 } else if (button == BTN_LEFT &&
349 state == 0 && window->grab_device == input_device) {
350 window->state = WINDOW_STABLE;
351 }
352}
353
354static void
355window_handle_key(void *data, struct wl_input_device *input_device,
356 uint32_t button, uint32_t state)
357{
358 struct window *window = data;
359
360 if (window->key_handler)
361 (*window->key_handler)(window, button, state,
362 window->user_data);
363}
364
365static const struct wl_input_device_listener input_device_listener = {
366 window_handle_motion,
367 window_handle_button,
368 window_handle_key,
369};
370
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500371void
372window_get_child_rectangle(struct window *window,
373 struct rectangle *rectangle)
Kristian Høgsberg8a9cda82008-11-03 15:31:30 -0500374{
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500375 if (window->fullscreen) {
376 *rectangle = window->allocation;
377 } else {
378 rectangle->x = window->margin + 10;
379 rectangle->y = window->margin + 50;
380 rectangle->width = window->allocation.width - 20 - window->margin * 2;
381 rectangle->height = window->allocation.height - 60 - window->margin * 2;
382 }
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500383}
384
385void
Kristian Høgsberg22106762008-12-08 13:50:07 -0500386window_set_child_size(struct window *window,
387 struct rectangle *rectangle)
388{
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500389 if (!window->fullscreen) {
390 window->allocation.width = rectangle->width + 20 + window->margin * 2;
391 window->allocation.height = rectangle->height + 60 + window->margin * 2;
392 }
Kristian Høgsberg22106762008-12-08 13:50:07 -0500393}
394
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -0500395cairo_surface_t *
396window_create_surface(struct window *window,
397 struct rectangle *rectangle)
398{
399 return cairo_drm_surface_create(window->ctx,
400 CAIRO_CONTENT_COLOR_ALPHA,
401 rectangle->width,
402 rectangle->height);
403}
404
Kristian Høgsberg22106762008-12-08 13:50:07 -0500405void
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500406window_copy(struct window *window,
407 struct rectangle *rectangle,
408 uint32_t name, uint32_t stride)
409{
410 wl_surface_copy(window->surface,
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500411 rectangle->x,
412 rectangle->y,
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500413 name, stride,
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500414 0, 0,
415 rectangle->width,
416 rectangle->height);
417}
418
419void
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -0500420window_copy_surface(struct window *window,
421 struct rectangle *rectangle,
422 cairo_surface_t *surface)
423{
424 wl_surface_copy(window->surface,
425 rectangle->x,
426 rectangle->y,
427 cairo_drm_surface_get_name(surface),
428 cairo_drm_surface_get_stride(surface),
429 0, 0,
430 rectangle->width,
431 rectangle->height);
432}
433
434void
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500435window_set_fullscreen(struct window *window, int fullscreen)
436{
437 window->fullscreen = fullscreen;
438 if (window->fullscreen) {
439 window->saved_allocation = window->allocation;
Kristian Høgsberg94448c02008-12-30 11:03:33 -0500440 window->allocation = window->screen_allocation;
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500441 } else {
442 window->allocation = window->saved_allocation;
443 }
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500444}
445
446void
447window_set_resize_handler(struct window *window,
448 window_resize_handler_t handler, void *data)
449{
450 window->resize_handler = handler;
451 window->user_data = data;
452}
453
454void
Kristian Høgsberg6e83d582008-12-08 00:01:36 -0500455window_set_key_handler(struct window *window,
456 window_key_handler_t handler, void *data)
457{
458 window->key_handler = handler;
459 window->user_data = data;
460}
461
Kristian Høgsberg94448c02008-12-30 11:03:33 -0500462static void
463window_handle_geometry(void *data,
464 struct wl_output *output,
465 int32_t width, int32_t height)
466{
467 struct window *window = data;
468
469 window->screen_allocation.x = 0;
470 window->screen_allocation.y = 0;
471 window->screen_allocation.width = width;
472 window->screen_allocation.height = height;
473}
474
475static const struct wl_output_listener output_listener = {
476 window_handle_geometry,
477};
478
479static void
480window_handle_global(struct wl_display *display,
481 struct wl_object *object, void *data)
482{
483 struct window *window = data;
484
485 if (wl_object_implements(object, "compositor", 1)) {
486 window->compositor = (struct wl_compositor *) object;
487 wl_compositor_add_listener(window->compositor,
488 &compositor_listener, window);
489 } else if (wl_object_implements(object, "output", 1)) {
490 struct wl_output *output = (struct wl_output *) object;
491
492 wl_output_add_listener(output,
493 &output_listener, window);
494 } else if (wl_object_implements(object, "input_device", 1)) {
495 struct wl_input_device *input_device =
496 (struct wl_input_device *) object;
497
498 wl_input_device_add_listener(input_device,
499 &input_device_listener, window);
500 }
501}
502
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500503struct window *
504window_create(struct wl_display *display, int fd,
505 const char *title,
506 int32_t x, int32_t y, int32_t width, int32_t height)
507{
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -0500508 struct window *window;
509
510 window = malloc(sizeof *window);
511 if (window == NULL)
512 return NULL;
513
Kristian Høgsberg78231c82008-11-08 15:06:01 -0500514 memset(window, 0, sizeof *window);
Kristian Høgsberg40979232008-11-25 22:40:39 -0500515 window->display = display;
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500516 window->title = strdup(title);
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500517 window->compositor = wl_display_get_compositor(display);
518 window->surface = wl_compositor_create_surface(window->compositor);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500519 window->allocation.x = x;
520 window->allocation.y = y;
521 window->allocation.width = width;
522 window->allocation.height = height;
523 window->saved_allocation = window->allocation;
Kristian Høgsberg40979232008-11-25 22:40:39 -0500524 window->margin = 16;
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -0500525 window->state = WINDOW_STABLE;
Kristian Høgsberg0ac16f02009-01-15 11:37:43 -0500526 window->ctx = cairo_drm_context_get_for_fd(fd);
527 if (window->ctx == NULL) {
528 fprintf(stderr, "failed to get cairo drm context\n");
529 return NULL;
530 }
Kristian Høgsberg8a9cda82008-11-03 15:31:30 -0500531
Kristian Høgsberg94448c02008-12-30 11:03:33 -0500532 wl_display_add_global_listener(display,
533 window_handle_global, window);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500534
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500535 return window;
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500536}