1e286fa6e3ed536edc3aba76d265c85e706c362f
[profile/ivi/weston-ivi-shell.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 int
47 finish_frame_handler(void *data)
48 {
49         struct weston_output *output = data;
50         uint32_t msec;
51         struct timeval tv;
52
53         gettimeofday(&tv, NULL);
54         msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;
55         weston_output_finish_frame(output, msec);
56
57         return 1;
58 }
59
60 static void
61 headless_output_repaint(struct weston_output *output_base,
62                        pixman_region32_t *damage)
63 {
64         struct headless_output *output = (struct headless_output *) output_base;
65         struct weston_compositor *ec = output->base.compositor;
66
67         ec->renderer->repaint_output(&output->base, damage);
68
69         pixman_region32_subtract(&ec->primary_plane.damage,
70                                  &ec->primary_plane.damage, damage);
71
72         wl_event_source_timer_update(output->finish_frame_timer, 16);
73
74         return;
75 }
76
77 static void
78 headless_output_destroy(struct weston_output *output_base)
79 {
80         struct headless_output *output = (struct headless_output *) output_base;
81
82         wl_event_source_remove(output->finish_frame_timer);
83         free(output);
84
85         return;
86 }
87
88 static int
89 headless_compositor_create_output(struct headless_compositor *c,
90                                  int width, int height)
91 {
92         struct headless_output *output;
93         struct wl_event_loop *loop;
94
95         output = malloc(sizeof *output);
96         if (output == NULL)
97                 return -1;
98         memset(output, 0, sizeof *output);
99
100         output->mode.flags =
101                 WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
102         output->mode.width = width;
103         output->mode.height = height;
104         output->mode.refresh = 60;
105         wl_list_init(&output->base.mode_list);
106         wl_list_insert(&output->base.mode_list, &output->mode.link);
107
108         output->base.current = &output->mode;
109         weston_output_init(&output->base, &c->base, 0, 0, width, height,
110                            WL_OUTPUT_TRANSFORM_NORMAL);
111
112         output->base.make = "weston";
113         output->base.model = "headless";
114
115         weston_output_move(&output->base, 0, 0);
116
117         loop = wl_display_get_event_loop(c->base.wl_display);
118         output->finish_frame_timer =
119                 wl_event_loop_add_timer(loop, finish_frame_handler, output);
120
121         output->base.origin = output->base.current;
122         output->base.repaint = headless_output_repaint;
123         output->base.destroy = headless_output_destroy;
124         output->base.assign_planes = NULL;
125         output->base.set_backlight = NULL;
126         output->base.set_dpms = NULL;
127         output->base.switch_mode = NULL;
128
129         wl_list_insert(c->base.output_list.prev, &output->base.link);
130
131         return 0;
132 }
133
134 static void
135 headless_restore(struct weston_compositor *ec)
136 {
137 }
138
139 static void
140 headless_destroy(struct weston_compositor *ec)
141 {
142         struct headless_compositor *c = (struct headless_compositor *) ec;
143
144         ec->renderer->destroy(ec);
145
146         weston_seat_release(&c->fake_seat);
147         weston_compositor_shutdown(ec);
148
149         free(ec);
150 }
151
152 static struct weston_compositor *
153 headless_compositor_create(struct wl_display *display,
154                           int width, int height, const char *display_name,
155                           int *argc, char *argv[], const char *config_file)
156 {
157         struct headless_compositor *c;
158
159         c = calloc(1, sizeof *c);
160         if (c == NULL)
161                 return NULL;
162
163         memset(c, 0, sizeof *c);
164
165         if (weston_compositor_init(&c->base, display, argc, argv,
166                                    config_file) < 0)
167                 goto err_free;
168
169         weston_seat_init(&c->fake_seat, &c->base);
170
171         c->base.destroy = headless_destroy;
172         c->base.restore = headless_restore;
173
174         if (headless_compositor_create_output(c, width, height) < 0)
175                 goto err_compositor;
176
177         if (noop_renderer_init(&c->base) < 0)
178                 goto err_compositor;
179
180         return &c->base;
181
182 err_compositor:
183         weston_compositor_shutdown(&c->base);
184 err_free:
185         free(c);
186         return NULL;
187 }
188
189 WL_EXPORT struct weston_compositor *
190 backend_init(struct wl_display *display, int *argc, char *argv[],
191              const char *config_file)
192 {
193         int width = 1024, height = 640;
194         char *display_name = NULL;
195
196         const struct weston_option headless_options[] = {
197                 { WESTON_OPTION_INTEGER, "width", 0, &width },
198                 { WESTON_OPTION_INTEGER, "height", 0, &height },
199         };
200
201         parse_options(headless_options,
202                       ARRAY_LENGTH(headless_options), argc, argv);
203
204         return headless_compositor_create(display, width, height, display_name,
205                                          argc, argv, config_file);
206 }