blob: 3a67c745ed292fc32e46b455d8a23607fcb335ff [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øgsberg61017b12008-11-02 18:51:48 -050033
Kristian Høgsberg5ee1a602008-12-11 23:18:45 -050034#include <linux/input.h>
Kristian Høgsberg61017b12008-11-02 18:51:48 -050035#include "wayland-client.h"
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -050036#include "wayland-glib.h"
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050037
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050038#include "cairo-util.h"
Kristian Høgsberg61017b12008-11-02 18:51:48 -050039
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -050040#include "window.h"
Kristian Høgsberg8a9cda82008-11-03 15:31:30 -050041
Kristian Høgsberg61017b12008-11-02 18:51:48 -050042struct window {
Kristian Høgsberg40979232008-11-25 22:40:39 -050043 struct wl_display *display;
Kristian Høgsbergd2412e22008-12-15 20:35:24 -050044 struct wl_compositor *compositor;
Kristian Høgsberg61017b12008-11-02 18:51:48 -050045 struct wl_surface *surface;
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -050046 const char *title;
Kristian Høgsberg0395f302008-12-22 12:14:50 -050047 struct rectangle allocation, saved_allocation;
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -050048 int minimum_width, minimum_height;
Kristian Høgsberg40979232008-11-25 22:40:39 -050049 int margin;
Kristian Høgsbergc492b482008-12-12 12:00:02 -050050 int drag_x, drag_y;
Kristian Høgsberg61017b12008-11-02 18:51:48 -050051 int state;
Kristian Høgsberg0395f302008-12-22 12:14:50 -050052 int fullscreen;
Kristian Høgsbergc492b482008-12-12 12:00:02 -050053 uint32_t grab_device;
Kristian Høgsberg61017b12008-11-02 18:51:48 -050054 uint32_t name;
55 int fd;
Kristian Høgsberg78231c82008-11-08 15:06:01 -050056
57 struct buffer *buffer;
Kristian Høgsberg8a9cda82008-11-03 15:31:30 -050058
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -050059 window_resize_handler_t resize_handler;
60 window_frame_handler_t frame_handler;
61 window_acknowledge_handler_t acknowledge_handler;
Kristian Høgsberg6e83d582008-12-08 00:01:36 -050062 window_key_handler_t key_handler;
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -050063 void *user_data;
Kristian Høgsberg61017b12008-11-02 18:51:48 -050064};
65
Kristian Høgsberge4feb562008-11-08 18:53:37 -050066static void
67rounded_rect(cairo_t *cr, int x0, int y0, int x1, int y1, int radius)
68{
69 cairo_move_to(cr, x0, y0 + radius);
70 cairo_arc(cr, x0 + radius, y0 + radius, radius, M_PI, 3 * M_PI / 2);
71 cairo_line_to(cr, x1 - radius, y0);
72 cairo_arc(cr, x1 - radius, y0 + radius, radius, 3 * M_PI / 2, 2 * M_PI);
73 cairo_line_to(cr, x1, y1 - radius);
74 cairo_arc(cr, x1 - radius, y1 - radius, radius, 0, M_PI / 2);
75 cairo_line_to(cr, x0 + radius, y1);
76 cairo_arc(cr, x0 + radius, y1 - radius, radius, M_PI / 2, M_PI);
77 cairo_close_path(cr);
78}
79
Kristian Høgsberg0395f302008-12-22 12:14:50 -050080static void
81window_draw_decorations(struct window *window)
Kristian Høgsberg61017b12008-11-02 18:51:48 -050082{
83 cairo_surface_t *surface;
84 cairo_t *cr;
Kristian Høgsberg40979232008-11-25 22:40:39 -050085 int border = 2, radius = 5;
Kristian Høgsbergca1d1f62008-11-03 06:59:52 -050086 cairo_text_extents_t extents;
Kristian Høgsberge4feb562008-11-08 18:53:37 -050087 cairo_pattern_t *gradient, *outline, *bright, *dim;
Kristian Høgsbergde31d5c2008-12-18 17:55:33 -050088 struct wl_visual *visual;
Kristian Høgsberg0395f302008-12-22 12:14:50 -050089 int width, height;
Kristian Høgsberg61017b12008-11-02 18:51:48 -050090
91 surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
Kristian Høgsberg0395f302008-12-22 12:14:50 -050092 window->allocation.width,
93 window->allocation.height);
Kristian Høgsberg61017b12008-11-02 18:51:48 -050094
Kristian Høgsberge4feb562008-11-08 18:53:37 -050095 outline = cairo_pattern_create_rgb(0.1, 0.1, 0.1);
Kristian Høgsberge9d550b2008-11-19 00:49:39 -050096 bright = cairo_pattern_create_rgb(0.8, 0.8, 0.8);
Kristian Høgsberge4feb562008-11-08 18:53:37 -050097 dim = cairo_pattern_create_rgb(0.4, 0.4, 0.4);
98
Kristian Høgsberg61017b12008-11-02 18:51:48 -050099 cr = cairo_create(surface);
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -0500100
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500101 width = window->allocation.width - window->margin * 2;
102 height = window->allocation.height - window->margin * 2;
103
Kristian Høgsberg40979232008-11-25 22:40:39 -0500104 cairo_translate(cr, window->margin + 7, window->margin + 5);
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -0500105 cairo_set_line_width (cr, border);
Kristian Høgsberge9d550b2008-11-19 00:49:39 -0500106 cairo_set_source_rgba(cr, 0, 0, 0, 0.7);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500107 rounded_rect(cr, 0, 0, width, height, radius);
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -0500108 cairo_fill(cr);
Kristian Høgsberg87330262008-11-17 22:23:55 -0500109 blur_surface(surface, 24 + radius);
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -0500110
Kristian Høgsberge9d550b2008-11-19 00:49:39 -0500111 cairo_translate(cr, -7, -5);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500112 cairo_set_line_width (cr, border);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500113 rounded_rect(cr, 1, 1, width - 1, height - 1, radius);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500114 cairo_set_source(cr, outline);
115 cairo_stroke(cr);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500116 rounded_rect(cr, 2, 2, width - 2, height - 2, radius - 1);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500117 cairo_set_source(cr, bright);
118 cairo_stroke(cr);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500119 rounded_rect(cr, 3, 3, width - 2, height - 2, radius - 1);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500120 cairo_set_source(cr, dim);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500121 cairo_stroke(cr);
Kristian Høgsbergca1d1f62008-11-03 06:59:52 -0500122
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500123 rounded_rect(cr, 2, 2, width - 2, height - 2, radius - 1);
Kristian Høgsberg6e635f32008-11-09 09:15:46 -0500124 gradient = cairo_pattern_create_linear (0, 0, 0, 100);
Kristian Høgsberge9d550b2008-11-19 00:49:39 -0500125 cairo_pattern_add_color_stop_rgb(gradient, 0, 0.6, 0.6, 0.4);
126 cairo_pattern_add_color_stop_rgb(gradient, 1, 0.8, 0.8, 0.7);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500127 cairo_set_source(cr, gradient);
128 cairo_fill(cr);
129 cairo_pattern_destroy(gradient);
130
131 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
132 cairo_move_to(cr, 10, 50);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500133 cairo_line_to(cr, width - 10, 50);
134 cairo_line_to(cr, width - 10, height - 10);
135 cairo_line_to(cr, 10, height - 10);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500136 cairo_close_path(cr);
137 cairo_set_source(cr, dim);
138 cairo_stroke(cr);
139
140 cairo_move_to(cr, 11, 51);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500141 cairo_line_to(cr, width - 10, 51);
142 cairo_line_to(cr, width - 10, height - 10);
143 cairo_line_to(cr, 11, height - 10);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500144 cairo_close_path(cr);
145 cairo_set_source(cr, bright);
146 cairo_stroke(cr);
147
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500148 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
149 cairo_set_font_size(cr, 14);
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500150 cairo_text_extents(cr, window->title, &extents);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500151 cairo_move_to(cr, (width - extents.width) / 2, 10 - extents.y_bearing);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500152 cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
153 cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
154 cairo_set_line_width (cr, 4);
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500155 cairo_text_path(cr, window->title);
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500156 cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
157 cairo_stroke_preserve(cr);
158 cairo_set_source_rgb(cr, 1, 1, 1);
159 cairo_fill(cr);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500160 cairo_destroy(cr);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500161
Kristian Høgsberg40979232008-11-25 22:40:39 -0500162 window->buffer = buffer_create_from_cairo_surface(window->fd, surface);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500163 cairo_surface_destroy(surface);
164
Kristian Høgsbergde31d5c2008-12-18 17:55:33 -0500165 visual = wl_display_get_premultiplied_argb_visual(window->display);
Kristian Høgsberg40979232008-11-25 22:40:39 -0500166 wl_surface_attach(window->surface,
167 window->buffer->name,
168 window->buffer->width,
169 window->buffer->height,
Kristian Høgsbergde31d5c2008-12-18 17:55:33 -0500170 window->buffer->stride,
171 visual);
Kristian Høgsbergb7a01922008-11-08 15:39:41 -0500172
Kristian Høgsbergfbdbbdc2008-11-28 17:06:06 -0500173 wl_surface_map(window->surface,
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500174 window->allocation.x - window->margin,
175 window->allocation.y - window->margin,
176 window->allocation.width,
177 window->allocation.height);
178}
179
180static void
181window_draw_fullscreen(struct window *window)
182{
183 struct wl_visual *visual;
184 int stride = window->allocation.width * 4;
185
186 window->buffer = buffer_create(window->fd,
187 window->allocation.width,
188 window->allocation.height,
189 stride);
190
191 visual = wl_display_get_premultiplied_argb_visual(window->display);
192 wl_surface_attach(window->surface,
193 window->buffer->name,
194 window->buffer->width,
195 window->buffer->height,
196 window->buffer->stride,
197 visual);
198
199 wl_surface_map(window->surface,
200 window->allocation.x,
201 window->allocation.y,
202 window->allocation.width,
203 window->allocation.height);
204}
205
206void
207window_draw(struct window *window)
208{
209 if (window->fullscreen)
210 window_draw_fullscreen(window);
211 else
212 window_draw_decorations(window);
Kristian Høgsberg44f36e32008-11-26 12:57:31 -0500213}
214
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500215enum window_state {
216 WINDOW_STABLE,
217 WINDOW_MOVING,
218 WINDOW_RESIZING_UPPER_LEFT,
219 WINDOW_RESIZING_UPPER_RIGHT,
220 WINDOW_RESIZING_LOWER_LEFT,
221 WINDOW_RESIZING_LOWER_RIGHT
222};
223
224enum location {
225 LOCATION_INTERIOR,
226 LOCATION_UPPER_LEFT,
227 LOCATION_UPPER_RIGHT,
228 LOCATION_LOWER_LEFT,
229 LOCATION_LOWER_RIGHT,
230 LOCATION_OUTSIDE
231};
232
Kristian Høgsberge4feb562008-11-08 18:53:37 -0500233static void
234event_handler(struct wl_display *display,
Kristian Høgsberg40979232008-11-25 22:40:39 -0500235 uint32_t object, uint32_t opcode,
236 uint32_t size, uint32_t *p, void *data)
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500237{
238 struct window *window = data;
Kristian Høgsberg40979232008-11-25 22:40:39 -0500239 int location;
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500240 int grip_size = 16;
241
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500242 /* FIXME: Object ID 2 is the compositor, for anything else we
Kristian Høgsberg40979232008-11-25 22:40:39 -0500243 * assume it's an input device. */
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500244 if (object == 2 && opcode == 0) {
Kristian Høgsbergfbdbbdc2008-11-28 17:06:06 -0500245 uint32_t key = p[0];
246
247 /* Ignore acknowledge events for window move requests. */
248 if (key != 0)
249 return;
250
Kristian Høgsberg40979232008-11-25 22:40:39 -0500251 /* The acknowledge event means that the server
Kristian Høgsberg44f36e32008-11-26 12:57:31 -0500252 * processed our last commit request and we can now
Kristian Høgsbergfbdbbdc2008-11-28 17:06:06 -0500253 * safely free the old window buffer if we resized and
254 * render the next frame into our back buffer.. */
255
Kristian Høgsberg44f36e32008-11-26 12:57:31 -0500256 if (window->buffer != NULL) {
Kristian Høgsberg40979232008-11-25 22:40:39 -0500257 buffer_destroy(window->buffer, window->fd);
258 window->buffer = NULL;
Kristian Høgsberg40979232008-11-25 22:40:39 -0500259 }
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500260 if (window->acknowledge_handler)
261 (*window->acknowledge_handler)(window, key,
262 window->user_data);
263
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500264 } else if (object == 2 && opcode == 1) {
Kristian Høgsbergfbdbbdc2008-11-28 17:06:06 -0500265 /* The frame event means that the previous frame was
266 * composited, and we can now send the request to copy
267 * the frame we've rendered in the mean time into the
268 * servers surface buffer. */
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500269 if (window->frame_handler)
270 (*window->frame_handler)(window, p[0], p[1],
271 window->user_data);
Kristian Høgsberg44f36e32008-11-26 12:57:31 -0500272 } else if (object == 1) {
273 fprintf(stderr, "unexpected event from display: %d\n",
274 opcode);
275 exit(-1);
Kristian Høgsberg40979232008-11-25 22:40:39 -0500276 } else if (opcode == 0) {
277 int x = p[0], y = p[1];
278
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500279 switch (window->state) {
280 case WINDOW_MOVING:
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500281 if (window->fullscreen)
282 break;
Kristian Høgsbergc492b482008-12-12 12:00:02 -0500283 if (window->grab_device != object)
284 break;
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500285 window->allocation.x = window->drag_x + x;
286 window->allocation.y = window->drag_y + y;
Kristian Høgsberg40979232008-11-25 22:40:39 -0500287 wl_surface_map(window->surface,
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500288 window->allocation.x - window->margin,
289 window->allocation.y - window->margin,
290 window->allocation.width,
291 window->allocation.height);
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500292 wl_compositor_commit(window->compositor, 1);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500293 break;
294 case WINDOW_RESIZING_LOWER_RIGHT:
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500295 if (window->fullscreen)
296 break;
Kristian Høgsbergc492b482008-12-12 12:00:02 -0500297 if (window->grab_device != object)
298 break;
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500299 window->allocation.width = window->drag_x + x;
300 window->allocation.height = window->drag_y + y;
Kristian Høgsbergfbdbbdc2008-11-28 17:06:06 -0500301
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500302 if (window->resize_handler)
303 (*window->resize_handler)(window,
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500304 window->user_data);
Kristian Høgsberg1584c572008-12-08 12:59:37 -0500305
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500306 break;
307 }
Kristian Høgsberg40979232008-11-25 22:40:39 -0500308 } else if (opcode == 1) {
309 int button = p[0], state = p[1];
Kristian Høgsbergc492b482008-12-12 12:00:02 -0500310 int32_t x = p[2], y = p[3];
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500311 int32_t left = window->allocation.x;
312 int32_t right = window->allocation.x +
313 window->allocation.width - window->margin * 2;
314 int32_t top = window->allocation.y;
315 int32_t bottom = window->allocation.y +
316 window->allocation.height - window->margin * 2;
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500317
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500318 if (right - grip_size <= x && x < right &&
319 bottom - grip_size <= y && y < bottom) {
Kristian Høgsberg40979232008-11-25 22:40:39 -0500320 location = LOCATION_LOWER_RIGHT;
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500321 } else if (left <= x && x < right && top <= y && y < bottom) {
Kristian Høgsberg40979232008-11-25 22:40:39 -0500322 location = LOCATION_INTERIOR;
323 } else {
324 location = LOCATION_OUTSIDE;
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500325 }
Kristian Høgsberg40979232008-11-25 22:40:39 -0500326
Kristian Høgsberg5ee1a602008-12-11 23:18:45 -0500327 if (button == BTN_LEFT && state == 1) {
Kristian Høgsberg40979232008-11-25 22:40:39 -0500328 switch (location) {
329 case LOCATION_INTERIOR:
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500330 window->drag_x = window->allocation.x - x;
331 window->drag_y = window->allocation.y - y;
Kristian Høgsberg40979232008-11-25 22:40:39 -0500332 window->state = WINDOW_MOVING;
Kristian Høgsbergc492b482008-12-12 12:00:02 -0500333 window->grab_device = object;
Kristian Høgsberg40979232008-11-25 22:40:39 -0500334 break;
335 case LOCATION_LOWER_RIGHT:
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500336 window->drag_x = window->allocation.width - x;
337 window->drag_y = window->allocation.height - y;
Kristian Høgsberg40979232008-11-25 22:40:39 -0500338 window->state = WINDOW_RESIZING_LOWER_RIGHT;
Kristian Høgsbergc492b482008-12-12 12:00:02 -0500339 window->grab_device = object;
Kristian Høgsberg40979232008-11-25 22:40:39 -0500340 break;
341 default:
342 window->state = WINDOW_STABLE;
343 break;
344 }
Kristian Høgsbergc492b482008-12-12 12:00:02 -0500345 } else if (button == BTN_LEFT &&
346 state == 0 && object == window->grab_device) {
Kristian Høgsberg40979232008-11-25 22:40:39 -0500347 window->state = WINDOW_STABLE;
348 }
Kristian Høgsberg6e83d582008-12-08 00:01:36 -0500349 } else if (opcode == 2) {
350 if (window->key_handler)
351 (*window->key_handler)(window, p[0], p[1],
352 window->user_data);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500353 }
354}
355
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500356void
357window_get_child_rectangle(struct window *window,
358 struct rectangle *rectangle)
Kristian Høgsberg8a9cda82008-11-03 15:31:30 -0500359{
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500360 if (window->fullscreen) {
361 *rectangle = window->allocation;
362 } else {
363 rectangle->x = window->margin + 10;
364 rectangle->y = window->margin + 50;
365 rectangle->width = window->allocation.width - 20 - window->margin * 2;
366 rectangle->height = window->allocation.height - 60 - window->margin * 2;
367 }
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500368}
369
370void
Kristian Høgsberg22106762008-12-08 13:50:07 -0500371window_set_child_size(struct window *window,
372 struct rectangle *rectangle)
373{
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500374 if (!window->fullscreen) {
375 window->allocation.width = rectangle->width + 20 + window->margin * 2;
376 window->allocation.height = rectangle->height + 60 + window->margin * 2;
377 }
Kristian Høgsberg22106762008-12-08 13:50:07 -0500378}
379
380void
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500381window_copy(struct window *window,
382 struct rectangle *rectangle,
383 uint32_t name, uint32_t stride)
384{
385 wl_surface_copy(window->surface,
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500386 rectangle->x,
387 rectangle->y,
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500388 name, stride,
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500389 0, 0,
390 rectangle->width,
391 rectangle->height);
392}
393
394void
395window_set_fullscreen(struct window *window, int fullscreen)
396{
397 window->fullscreen = fullscreen;
398 if (window->fullscreen) {
399 window->saved_allocation = window->allocation;
400 window->allocation.x = 0;
401 window->allocation.y = 0;
402 wl_display_get_geometry(window->display,
403 &window->allocation.width,
404 &window->allocation.height);
405 } else {
406 window->allocation = window->saved_allocation;
407 }
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500408}
409
410void
411window_set_resize_handler(struct window *window,
412 window_resize_handler_t handler, void *data)
413{
414 window->resize_handler = handler;
415 window->user_data = data;
416}
417
418void
419window_set_frame_handler(struct window *window,
420 window_frame_handler_t handler, void *data)
421{
422 window->frame_handler = handler;
423 window->user_data = data;
424}
425
426void
427window_set_acknowledge_handler(struct window *window,
428 window_acknowledge_handler_t handler, void *data)
429{
430 window->acknowledge_handler = handler;
431 window->user_data = data;
432}
433
434void
Kristian Høgsberg6e83d582008-12-08 00:01:36 -0500435window_set_key_handler(struct window *window,
436 window_key_handler_t handler, void *data)
437{
438 window->key_handler = handler;
439 window->user_data = data;
440}
441
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500442struct window *
443window_create(struct wl_display *display, int fd,
444 const char *title,
445 int32_t x, int32_t y, int32_t width, int32_t height)
446{
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -0500447 struct window *window;
448
449 window = malloc(sizeof *window);
450 if (window == NULL)
451 return NULL;
452
Kristian Høgsberg78231c82008-11-08 15:06:01 -0500453 memset(window, 0, sizeof *window);
Kristian Høgsberg40979232008-11-25 22:40:39 -0500454 window->display = display;
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500455 window->title = strdup(title);
Kristian Høgsbergd2412e22008-12-15 20:35:24 -0500456 window->compositor = wl_display_get_compositor(display);
457 window->surface = wl_compositor_create_surface(window->compositor);
Kristian Høgsberg0395f302008-12-22 12:14:50 -0500458 window->allocation.x = x;
459 window->allocation.y = y;
460 window->allocation.width = width;
461 window->allocation.height = height;
462 window->saved_allocation = window->allocation;
Kristian Høgsberg40979232008-11-25 22:40:39 -0500463 window->margin = 16;
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -0500464 window->state = WINDOW_STABLE;
465 window->fd = fd;
Kristian Høgsberg8a9cda82008-11-03 15:31:30 -0500466
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -0500467 wl_display_set_event_handler(display, event_handler, window);
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500468
Kristian Høgsberg0c4457f2008-12-07 19:59:11 -0500469 return window;
Kristian Høgsberg61017b12008-11-02 18:51:48 -0500470}