input: Rename weston_device_repick() to weston_seat_repick()
[platform/upstream/weston.git] / src / compositor-headless.c
1 /*
2  * Copyright © 2010-2011 Benjamin Franzke
3  * Copyright © 2012 Intel Corporation
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and
6  * its documentation for any purpose is hereby granted without fee, provided
7  * that the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation, and that the name of the copyright holders not be used in
10  * advertising or publicity pertaining to distribution of the software
11  * without specific, written prior permission.  The copyright holders make
12  * no representations about the suitability of this software for any
13  * purpose.  It is provided "as is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/time.h>
31
32 #include "compositor.h"
33
34 struct headless_compositor {
35         struct weston_compositor base;
36         struct weston_seat fake_seat;
37 };
38
39 struct headless_output {
40         struct weston_output base;
41         struct weston_mode mode;
42         struct wl_event_source *finish_frame_timer;
43 };
44
45
46 static void
47 headless_output_start_repaint_loop(struct weston_output *output)
48 {
49         uint32_t msec;
50         struct timeval tv;
51
52         gettimeofday(&tv, NULL);
53         msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;
54         weston_output_finish_frame(output, msec);
55 }
56
57 static int
58 finish_frame_handler(void *data)
59 {
60         headless_output_start_repaint_loop(data);
61
62         return 1;
63 }
64
65 static void
66 headless_output_repaint(struct weston_output *output_base,
67                        pixman_region32_t *damage)
68 {
69         struct headless_output *output = (struct headless_output *) output_base;
70         struct weston_compositor *ec = output->base.compositor;
71
72         ec->renderer->repaint_output(&output->base, damage);
73
74         pixman_region32_subtract(&ec->primary_plane.damage,
75                                  &ec->primary_plane.damage, damage);
76
77         wl_event_source_timer_update(output->finish_frame_timer, 16);
78
79         return;
80 }
81
82 static void
83 headless_output_destroy(struct weston_output *output_base)
84 {
85         struct headless_output *output = (struct headless_output *) output_base;
86
87         wl_event_source_remove(output->finish_frame_timer);
88         free(output);
89
90         return;
91 }
92
93 static int
94 headless_compositor_create_output(struct headless_compositor *c,
95                                  int width, int height)
96 {
97         struct headless_output *output;
98         struct wl_event_loop *loop;
99
100         output = malloc(sizeof *output);
101         if (output == NULL)
102                 return -1;
103         memset(output, 0, sizeof *output);
104
105         output->mode.flags =
106                 WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
107         output->mode.width = width;
108         output->mode.height = height;
109         output->mode.refresh = 60;
110         wl_list_init(&output->base.mode_list);
111         wl_list_insert(&output->base.mode_list, &output->mode.link);
112
113         output->base.current = &output->mode;
114         weston_output_init(&output->base, &c->base, 0, 0, width, height,
115                            WL_OUTPUT_TRANSFORM_NORMAL);
116
117         output->base.make = "weston";
118         output->base.model = "headless";
119
120         weston_output_move(&output->base, 0, 0);
121
122         loop = wl_display_get_event_loop(c->base.wl_display);
123         output->finish_frame_timer =
124                 wl_event_loop_add_timer(loop, finish_frame_handler, output);
125
126         output->base.origin = output->base.current;
127         output->base.start_repaint_loop = headless_output_start_repaint_loop;
128         output->base.repaint = headless_output_repaint;
129         output->base.destroy = headless_output_destroy;
130         output->base.assign_planes = NULL;
131         output->base.set_backlight = NULL;
132         output->base.set_dpms = NULL;
133         output->base.switch_mode = NULL;
134
135         wl_list_insert(c->base.output_list.prev, &output->base.link);
136
137         return 0;
138 }
139
140 static void
141 headless_restore(struct weston_compositor *ec)
142 {
143 }
144
145 static void
146 headless_destroy(struct weston_compositor *ec)
147 {
148         struct headless_compositor *c = (struct headless_compositor *) ec;
149
150         ec->renderer->destroy(ec);
151
152         weston_seat_release(&c->fake_seat);
153         weston_compositor_shutdown(ec);
154
155         free(ec);
156 }
157
158 static struct weston_compositor *
159 headless_compositor_create(struct wl_display *display,
160                           int width, int height, const char *display_name,
161                           int *argc, char *argv[], const char *config_file)
162 {
163         struct headless_compositor *c;
164
165         c = calloc(1, sizeof *c);
166         if (c == NULL)
167                 return NULL;
168
169         memset(c, 0, sizeof *c);
170
171         if (weston_compositor_init(&c->base, display, argc, argv,
172                                    config_file) < 0)
173                 goto err_free;
174
175         weston_seat_init(&c->fake_seat, &c->base);
176
177         c->base.destroy = headless_destroy;
178         c->base.restore = headless_restore;
179
180         if (headless_compositor_create_output(c, width, height) < 0)
181                 goto err_compositor;
182
183         if (noop_renderer_init(&c->base) < 0)
184                 goto err_compositor;
185
186         return &c->base;
187
188 err_compositor:
189         weston_compositor_shutdown(&c->base);
190 err_free:
191         free(c);
192         return NULL;
193 }
194
195 WL_EXPORT struct weston_compositor *
196 backend_init(struct wl_display *display, int *argc, char *argv[],
197              const char *config_file)
198 {
199         int width = 1024, height = 640;
200         char *display_name = NULL;
201
202         const struct weston_option headless_options[] = {
203                 { WESTON_OPTION_INTEGER, "width", 0, &width },
204                 { WESTON_OPTION_INTEGER, "height", 0, &height },
205         };
206
207         parse_options(headless_options,
208                       ARRAY_LENGTH(headless_options), argc, argv);
209
210         return headless_compositor_create(display, width, height, display_name,
211                                          argc, argv, config_file);
212 }