compositor-drm: Disable hw cursor if allocation fails
[profile/ivi/weston.git] / src / compositor-drm.c
1 /*
2  * Copyright © 2008-2011 Kristian Høgsberg
3  * Copyright © 2011 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 #define _GNU_SOURCE
25
26 #include <errno.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <linux/input.h>
32 #include <assert.h>
33
34 #include <xf86drm.h>
35 #include <xf86drmMode.h>
36 #include <drm_fourcc.h>
37
38 #include <gbm.h>
39 #include <libbacklight.h>
40 #include <libudev.h>
41
42 #include "compositor.h"
43 #include "evdev.h"
44 #include "launcher-util.h"
45
46 static int option_current_mode = 0;
47 static char *output_name;
48 static char *output_mode;
49 static char *output_transform;
50 static struct wl_list configured_output_list;
51
52 enum output_config {
53         OUTPUT_CONFIG_INVALID = 0,
54         OUTPUT_CONFIG_OFF,
55         OUTPUT_CONFIG_PREFERRED,
56         OUTPUT_CONFIG_CURRENT,
57         OUTPUT_CONFIG_MODE,
58         OUTPUT_CONFIG_MODELINE
59 };
60
61 struct drm_configured_output {
62         char *name;
63         char *mode;
64         uint32_t transform;
65         int32_t width, height;
66         drmModeModeInfo crtc_mode;
67         enum output_config config;
68         struct wl_list link;
69 };
70
71 struct drm_compositor {
72         struct weston_compositor base;
73
74         struct udev *udev;
75         struct wl_event_source *drm_source;
76
77         struct udev_monitor *udev_monitor;
78         struct wl_event_source *udev_drm_source;
79
80         struct {
81                 int id;
82                 int fd;
83         } drm;
84         struct gbm_device *gbm;
85         uint32_t *crtcs;
86         int num_crtcs;
87         uint32_t crtc_allocator;
88         uint32_t connector_allocator;
89         struct tty *tty;
90
91         /* we need these parameters in order to not fail drmModeAddFB2()
92          * due to out of bounds dimensions, and then mistakenly set
93          * sprites_are_broken:
94          */
95         int32_t min_width, max_width;
96         int32_t min_height, max_height;
97
98         struct wl_list sprite_list;
99         int sprites_are_broken;
100
101         int cursors_are_broken;
102
103         uint32_t prev_state;
104 };
105
106 struct drm_mode {
107         struct weston_mode base;
108         drmModeModeInfo mode_info;
109 };
110
111 struct drm_output;
112
113 struct drm_fb {
114         struct gbm_bo *bo;
115         struct drm_output *output;
116         uint32_t fb_id;
117         int is_client_buffer;
118         struct wl_buffer *buffer;
119         struct wl_listener buffer_destroy_listener;
120 };
121
122 struct drm_output {
123         struct weston_output   base;
124
125         char *name;
126         uint32_t crtc_id;
127         int pipe;
128         uint32_t connector_id;
129         drmModeCrtcPtr original_crtc;
130
131         int vblank_pending;
132         int page_flip_pending;
133
134         struct gbm_surface *surface;
135         struct gbm_bo *cursor_bo[2];
136         struct weston_plane cursor_plane;
137         struct weston_plane fb_plane;
138         struct weston_surface *cursor_surface;
139         int current_cursor;
140         struct drm_fb *current, *next;
141         struct backlight *backlight;
142 };
143
144 /*
145  * An output has a primary display plane plus zero or more sprites for
146  * blending display contents.
147  */
148 struct drm_sprite {
149         struct wl_list link;
150
151         uint32_t fb_id;
152         uint32_t pending_fb_id;
153         struct weston_surface *surface;
154         struct weston_surface *pending_surface;
155         struct weston_plane plane;
156
157         struct drm_output *output;
158
159         struct drm_compositor *compositor;
160
161         struct wl_listener destroy_listener;
162         struct wl_listener pending_destroy_listener;
163
164         uint32_t possible_crtcs;
165         uint32_t plane_id;
166         uint32_t count_formats;
167
168         int32_t src_x, src_y;
169         uint32_t src_w, src_h;
170         uint32_t dest_x, dest_y;
171         uint32_t dest_w, dest_h;
172
173         uint32_t formats[];
174 };
175
176 struct drm_seat {
177         struct weston_seat base;
178         struct wl_list devices_list;
179         struct udev_monitor *udev_monitor;
180         struct wl_event_source *udev_monitor_source;
181         char *seat_id;
182 };
183
184 static void
185 drm_output_set_cursor(struct drm_output *output);
186 static void
187 drm_disable_unused_sprites(struct weston_output *output_base);
188
189 static int
190 drm_sprite_crtc_supported(struct weston_output *output_base, uint32_t supported)
191 {
192         struct weston_compositor *ec = output_base->compositor;
193         struct drm_compositor *c =(struct drm_compositor *) ec;
194         struct drm_output *output = (struct drm_output *) output_base;
195         int crtc;
196
197         for (crtc = 0; crtc < c->num_crtcs; crtc++) {
198                 if (c->crtcs[crtc] != output->crtc_id)
199                         continue;
200
201                 if (supported & (1 << crtc))
202                         return -1;
203         }
204
205         return 0;
206 }
207
208 static void
209 drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
210 {
211         struct drm_fb *fb = data;
212         struct gbm_device *gbm = gbm_bo_get_device(bo);
213
214         if (fb->fb_id)
215                 drmModeRmFB(gbm_device_get_fd(gbm), fb->fb_id);
216
217         if (fb->buffer) {
218                 weston_buffer_post_release(fb->buffer);
219                 wl_list_remove(&fb->buffer_destroy_listener.link);
220         }
221
222         free(data);
223 }
224
225 static struct drm_fb *
226 drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_output *output)
227 {
228         struct drm_fb *fb = gbm_bo_get_user_data(bo);
229         struct drm_compositor *compositor =
230                 (struct drm_compositor *) output->base.compositor;
231         uint32_t width, height, stride, handle;
232         int ret;
233
234         if (fb)
235                 return fb;
236
237         fb = malloc(sizeof *fb);
238
239         fb->bo = bo;
240         fb->output = output;
241         fb->is_client_buffer = 0;
242         fb->buffer = NULL;
243
244         width = gbm_bo_get_width(bo);
245         height = gbm_bo_get_height(bo);
246         stride = gbm_bo_get_stride(bo);
247         handle = gbm_bo_get_handle(bo).u32;
248
249         ret = drmModeAddFB(compositor->drm.fd, width, height, 24, 32,
250                            stride, handle, &fb->fb_id);
251         if (ret) {
252                 weston_log("failed to create kms fb: %m\n");
253                 free(fb);
254                 return NULL;
255         }
256
257         gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);
258
259         return fb;
260 }
261
262 static void
263 fb_handle_buffer_destroy(struct wl_listener *listener, void *data)
264 {
265         struct drm_fb *fb = container_of(listener, struct drm_fb,
266                                          buffer_destroy_listener);
267
268         fb->buffer = NULL;
269
270         if (fb == fb->output->next ||
271             (fb == fb->output->current && !fb->output->next))
272                 weston_output_schedule_repaint(&fb->output->base);
273 }
274
275 static struct weston_plane *
276 drm_output_prepare_scanout_surface(struct weston_output *_output,
277                                    struct weston_surface *es)
278 {
279         struct drm_output *output = (struct drm_output *) _output;
280         struct drm_compositor *c =
281                 (struct drm_compositor *) output->base.compositor;
282         struct gbm_bo *bo;
283
284         if (es->geometry.x != output->base.x ||
285             es->geometry.y != output->base.y ||
286             es->geometry.width != output->base.current->width ||
287             es->geometry.height != output->base.current->height ||
288             es->transform.enabled ||
289             es->buffer == NULL)
290                 return NULL;
291
292         bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
293                            es->buffer, GBM_BO_USE_SCANOUT);
294
295         /* Unable to use the buffer for scanout */
296         if (!bo)
297                 return NULL;
298
299         /* Need to verify output->region contained in surface opaque
300          * region.  Or maybe just that format doesn't have alpha.
301          * For now, scanout only if format is XRGB8888. */
302         if (gbm_bo_get_format(bo) != GBM_FORMAT_XRGB8888) {
303                 gbm_bo_destroy(bo);
304                 return NULL;
305         }
306
307         output->next = drm_fb_get_from_bo(bo, output);
308         if (!output->next) {
309                 gbm_bo_destroy(bo);
310                 return NULL;
311         }
312
313         output->next->is_client_buffer = 1;
314         output->next->buffer = es->buffer;
315         output->next->buffer->busy_count++;
316         output->next->buffer_destroy_listener.notify = fb_handle_buffer_destroy;
317
318         wl_signal_add(&output->next->buffer->resource.destroy_signal,
319                       &output->next->buffer_destroy_listener);
320
321         return &output->fb_plane;
322 }
323
324 static void
325 drm_output_render(struct drm_output *output, pixman_region32_t *damage)
326 {
327         struct weston_compositor *ec = output->base.compositor;
328         struct gbm_bo *bo;
329
330         ec->renderer->repaint_output(&output->base, damage);
331
332         bo = gbm_surface_lock_front_buffer(output->surface);
333         if (!bo) {
334                 weston_log("failed to lock front buffer: %m\n");
335                 return;
336         }
337
338         output->next = drm_fb_get_from_bo(bo, output);
339         if (!output->next) {
340                 weston_log("failed to get drm_fb for bo\n");
341                 gbm_surface_release_buffer(output->surface, bo);
342                 return;
343         }
344 }
345
346 static void
347 drm_output_repaint(struct weston_output *output_base,
348                    pixman_region32_t *damage)
349 {
350         struct drm_output *output = (struct drm_output *) output_base;
351         struct drm_compositor *compositor =
352                 (struct drm_compositor *) output->base.compositor;
353         struct drm_sprite *s;
354         struct drm_mode *mode;
355         int ret = 0;
356
357         if (!output->next)
358                 drm_output_render(output, damage);
359         if (!output->next)
360                 return;
361
362         mode = container_of(output->base.current, struct drm_mode, base);
363         if (!output->current) {
364                 ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
365                                      output->next->fb_id, 0, 0,
366                                      &output->connector_id, 1,
367                                      &mode->mode_info);
368                 if (ret) {
369                         weston_log("set mode failed: %m\n");
370                         return;
371                 }
372         }
373
374         if (drmModePageFlip(compositor->drm.fd, output->crtc_id,
375                             output->next->fb_id,
376                             DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
377                 weston_log("queueing pageflip failed: %m\n");
378                 return;
379         }
380
381         output->page_flip_pending = 1;
382
383         drm_output_set_cursor(output);
384
385         /*
386          * Now, update all the sprite surfaces
387          */
388         wl_list_for_each(s, &compositor->sprite_list, link) {
389                 uint32_t flags = 0;
390                 drmVBlank vbl = {
391                         .request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT,
392                         .request.sequence = 1,
393                 };
394
395                 if (!drm_sprite_crtc_supported(output_base, s->possible_crtcs))
396                         continue;
397
398                 ret = drmModeSetPlane(compositor->drm.fd, s->plane_id,
399                                       output->crtc_id, s->pending_fb_id, flags,
400                                       s->dest_x, s->dest_y,
401                                       s->dest_w, s->dest_h,
402                                       s->src_x, s->src_y,
403                                       s->src_w, s->src_h);
404                 if (ret)
405                         weston_log("setplane failed: %d: %s\n",
406                                 ret, strerror(errno));
407
408                 if (output->pipe > 0)
409                         vbl.request.type |= DRM_VBLANK_SECONDARY;
410
411                 /*
412                  * Queue a vblank signal so we know when the surface
413                  * becomes active on the display or has been replaced.
414                  */
415                 vbl.request.signal = (unsigned long)s;
416                 ret = drmWaitVBlank(compositor->drm.fd, &vbl);
417                 if (ret) {
418                         weston_log("vblank event request failed: %d: %s\n",
419                                 ret, strerror(errno));
420                 }
421
422                 s->output = output;
423                 output->vblank_pending = 1;
424         }
425
426         drm_disable_unused_sprites(&output->base);
427
428         return;
429 }
430
431 static void
432 vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,
433                void *data)
434 {
435         struct drm_sprite *s = (struct drm_sprite *)data;
436         struct drm_compositor *c = s->compositor;
437         struct drm_output *output = s->output;
438         uint32_t msecs;
439
440         output->vblank_pending = 0;
441
442         if (s->surface) {
443                 weston_buffer_post_release(s->surface->buffer);
444                 wl_list_remove(&s->destroy_listener.link);
445                 s->surface = NULL;
446                 drmModeRmFB(c->drm.fd, s->fb_id);
447                 s->fb_id = 0;
448         }
449
450         if (s->pending_surface) {
451                 wl_list_remove(&s->pending_destroy_listener.link);
452                 wl_signal_add(&s->pending_surface->buffer->resource.destroy_signal,
453                               &s->destroy_listener);
454                 s->surface = s->pending_surface;
455                 s->pending_surface = NULL;
456                 s->fb_id = s->pending_fb_id;
457                 s->pending_fb_id = 0;
458         }
459
460         if (!output->page_flip_pending) {
461                 msecs = sec * 1000 + usec / 1000;
462                 weston_output_finish_frame(&output->base, msecs);
463         }
464 }
465
466 static void
467 page_flip_handler(int fd, unsigned int frame,
468                   unsigned int sec, unsigned int usec, void *data)
469 {
470         struct drm_output *output = (struct drm_output *) data;
471         uint32_t msecs;
472
473         output->page_flip_pending = 0;
474
475         if (output->current) {
476                 if (output->current->is_client_buffer)
477                         gbm_bo_destroy(output->current->bo);
478                 else
479                         gbm_surface_release_buffer(output->surface,
480                                                    output->current->bo);
481         }
482
483         output->current = output->next;
484         output->next = NULL;
485
486         if (!output->vblank_pending) {
487                 msecs = sec * 1000 + usec / 1000;
488                 weston_output_finish_frame(&output->base, msecs);
489         }
490 }
491
492 static int
493 drm_surface_format_supported(struct drm_sprite *s, uint32_t format)
494 {
495         uint32_t i;
496
497         for (i = 0; i < s->count_formats; i++)
498                 if (s->formats[i] == format)
499                         return 1;
500
501         return 0;
502 }
503
504 static int
505 drm_surface_transform_supported(struct weston_surface *es)
506 {
507         struct weston_matrix *matrix = &es->transform.matrix;
508         int i;
509
510         if (!es->transform.enabled)
511                 return 1;
512
513         for (i = 0; i < 16; i++) {
514                 switch (i) {
515                 case 10:
516                 case 15:
517                         if (matrix->d[i] != 1.0)
518                                 return 0;
519                         break;
520                 case 0:
521                 case 5:
522                 case 12:
523                 case 13:
524                         break;
525                 default:
526                         if (matrix->d[i] != 0.0)
527                                 return 0;
528                         break;
529                 }
530         }
531
532         return 1;
533 }
534
535 static void
536 drm_disable_unused_sprites(struct weston_output *output_base)
537 {
538         struct weston_compositor *ec = output_base->compositor;
539         struct drm_compositor *c =(struct drm_compositor *) ec;
540         struct drm_output *output = (struct drm_output *) output_base;
541         struct drm_sprite *s;
542         int ret;
543
544         wl_list_for_each(s, &c->sprite_list, link) {
545                 if (s->pending_fb_id)
546                         continue;
547
548                 ret = drmModeSetPlane(c->drm.fd, s->plane_id,
549                                       output->crtc_id, 0, 0,
550                                       0, 0, 0, 0, 0, 0, 0, 0);
551                 if (ret)
552                         weston_log("failed to disable plane: %d: %s\n",
553                                 ret, strerror(errno));
554                 drmModeRmFB(c->drm.fd, s->fb_id);
555
556                 if (s->surface) {
557                         s->surface = NULL;
558                         wl_list_remove(&s->destroy_listener.link);
559                 }
560
561                 assert(!s->pending_surface);
562                 s->fb_id = 0;
563                 s->pending_fb_id = 0;
564         }
565 }
566
567 /*
568  * This function must take care to damage any previously assigned surface
569  * if the sprite ends up binding to a different surface than in the
570  * previous frame.
571  */
572 static struct weston_plane *
573 drm_output_prepare_overlay_surface(struct weston_output *output_base,
574                                    struct weston_surface *es)
575 {
576         struct weston_compositor *ec = output_base->compositor;
577         struct drm_compositor *c =(struct drm_compositor *) ec;
578         struct drm_sprite *s;
579         int found = 0;
580         EGLint handle, stride;
581         struct gbm_bo *bo;
582         uint32_t fb_id = 0;
583         uint32_t handles[4], pitches[4], offsets[4];
584         int ret = 0;
585         pixman_region32_t dest_rect, src_rect;
586         pixman_box32_t *box;
587         uint32_t format;
588         wl_fixed_t sx1, sy1, sx2, sy2;
589         int32_t width, height;
590
591         if (c->sprites_are_broken)
592                 return NULL;
593
594         if (es->output_mask != (1u << output_base->id))
595                 return NULL;
596
597         if (es->buffer == NULL)
598                 return NULL;
599
600         if (wl_buffer_is_shm(es->buffer))
601                 return NULL;
602
603         if (!drm_surface_transform_supported(es))
604                 return NULL;
605
606         wl_list_for_each(s, &c->sprite_list, link) {
607                 if (!drm_sprite_crtc_supported(output_base, s->possible_crtcs))
608                         continue;
609
610                 if (!s->pending_fb_id) {
611                         found = 1;
612                         break;
613                 }
614         }
615
616         /* No sprites available */
617         if (!found)
618                 return NULL;
619
620         width = es->geometry.width;
621         height = es->geometry.height;
622
623         /* If geometry is out of bounds, don't even bother trying because
624          * we know the AddFB2() call will fail:
625          */
626         if (c->min_width > width || width > c->max_width ||
627             c->min_height > height || height > c->max_height)
628                 return NULL;
629
630         bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
631                            es->buffer, GBM_BO_USE_SCANOUT);
632         if (!bo)
633                 return NULL;
634
635         format = gbm_bo_get_format(bo);
636         handle = gbm_bo_get_handle(bo).s32;
637         stride = gbm_bo_get_stride(bo);
638
639         gbm_bo_destroy(bo);
640
641         if (!drm_surface_format_supported(s, format))
642                 return NULL;
643
644         if (!handle)
645                 return NULL;
646
647         handles[0] = handle;
648         pitches[0] = stride;
649         offsets[0] = 0;
650
651         ret = drmModeAddFB2(c->drm.fd, width, height,
652                             format, handles, pitches, offsets,
653                             &fb_id, 0);
654         if (ret) {
655                 weston_log("addfb2 failed: %d\n", ret);
656                 c->sprites_are_broken = 1;
657                 return NULL;
658         }
659
660         s->pending_fb_id = fb_id;
661         s->pending_surface = es;
662         es->buffer->busy_count++;
663
664         box = pixman_region32_extents(&es->transform.boundingbox);
665         s->plane.x = box->x1;
666         s->plane.y = box->y1;
667
668         /*
669          * Calculate the source & dest rects properly based on actual
670          * position (note the caller has called weston_surface_update_transform()
671          * for us already).
672          */
673         pixman_region32_init(&dest_rect);
674         pixman_region32_intersect(&dest_rect, &es->transform.boundingbox,
675                                   &output_base->region);
676         pixman_region32_translate(&dest_rect, -output_base->x, -output_base->y);
677         box = pixman_region32_extents(&dest_rect);
678         s->dest_x = box->x1;
679         s->dest_y = box->y1;
680         s->dest_w = box->x2 - box->x1;
681         s->dest_h = box->y2 - box->y1;
682         pixman_region32_fini(&dest_rect);
683
684         pixman_region32_init(&src_rect);
685         pixman_region32_intersect(&src_rect, &es->transform.boundingbox,
686                                   &output_base->region);
687         box = pixman_region32_extents(&src_rect);
688
689         weston_surface_from_global_fixed(es,
690                                          wl_fixed_from_int(box->x1),
691                                          wl_fixed_from_int(box->y1),
692                                          &sx1, &sy1);
693         weston_surface_from_global_fixed(es,
694                                          wl_fixed_from_int(box->x2),
695                                          wl_fixed_from_int(box->y2),
696                                          &sx2, &sy2);
697
698         if (sx1 < 0)
699                 sx1 = 0;
700         if (sy1 < 0)
701                 sy1 = 0;
702         if (sx2 > wl_fixed_from_int(es->geometry.width))
703                 sx2 = wl_fixed_from_int(es->geometry.width);
704         if (sy2 > wl_fixed_from_int(es->geometry.height))
705                 sy2 = wl_fixed_from_int(es->geometry.height);
706
707         s->src_x = sx1 << 8;
708         s->src_y = sy1 << 8;
709         s->src_w = (sx2 - sx1) << 8;
710         s->src_h = (sy2 - sy1) << 8;
711         pixman_region32_fini(&src_rect);
712
713         wl_signal_add(&es->buffer->resource.destroy_signal,
714                       &s->pending_destroy_listener);
715
716         return &s->plane;
717 }
718
719 static struct weston_plane *
720 drm_output_prepare_cursor_surface(struct weston_output *output_base,
721                                   struct weston_surface *es)
722 {
723         struct drm_compositor *c =
724                 (struct drm_compositor *) output_base->compositor;
725         struct drm_output *output = (struct drm_output *) output_base;
726
727         if (output->cursor_surface)
728                 return NULL;
729         if (es->output_mask != (1u << output_base->id))
730                 return NULL;
731         if (c->cursors_are_broken)
732                 return NULL;
733         if (es->buffer == NULL || !wl_buffer_is_shm(es->buffer) ||
734             es->geometry.width > 64 || es->geometry.height > 64)
735                 return NULL;
736
737         output->cursor_surface = es;
738
739         return &output->cursor_plane;
740 }
741
742 static void
743 drm_output_set_cursor(struct drm_output *output)
744 {
745         struct weston_surface *es = output->cursor_surface;
746         struct drm_compositor *c =
747                 (struct drm_compositor *) output->base.compositor;
748         EGLint handle, stride;
749         struct gbm_bo *bo;
750         uint32_t buf[64 * 64];
751         unsigned char *s;
752         int i, x, y;
753
754         output->cursor_surface = NULL;
755         if (es == NULL) {
756                 drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
757                 return;
758         }
759
760         if (es->buffer && pixman_region32_not_empty(&output->cursor_plane.damage)) {
761                 pixman_region32_fini(&output->cursor_plane.damage);
762                 pixman_region32_init(&output->cursor_plane.damage);
763                 output->current_cursor ^= 1;
764                 bo = output->cursor_bo[output->current_cursor];
765                 memset(buf, 0, sizeof buf);
766                 stride = wl_shm_buffer_get_stride(es->buffer);
767                 s = wl_shm_buffer_get_data(es->buffer);
768                 for (i = 0; i < es->geometry.height; i++)
769                         memcpy(buf + i * 64, s + i * stride,
770                                es->geometry.width * 4);
771
772                 if (gbm_bo_write(bo, buf, sizeof buf) < 0)
773                         weston_log("failed update cursor: %m\n");
774
775                 handle = gbm_bo_get_handle(bo).s32;
776                 if (drmModeSetCursor(c->drm.fd,
777                                      output->crtc_id, handle, 64, 64)) {
778                         weston_log("failed to set cursor: %m\n");
779                         c->cursors_are_broken = 1;
780                 }
781         }
782
783         x = es->geometry.x - output->base.x;
784         y = es->geometry.y - output->base.y;
785         if (output->cursor_plane.x != x || output->cursor_plane.y != y) {
786                 if (drmModeMoveCursor(c->drm.fd, output->crtc_id, x, y)) {
787                         weston_log("failed to move cursor: %m\n");
788                         c->cursors_are_broken = 1;
789                 }
790
791                 output->cursor_plane.x = x;
792                 output->cursor_plane.y = y;
793         }
794 }
795
796 static void
797 drm_assign_planes(struct weston_output *output)
798 {
799         struct drm_compositor *c =
800                 (struct drm_compositor *) output->compositor;
801         struct weston_surface *es, *next;
802         pixman_region32_t overlap, surface_overlap;
803         struct weston_plane *primary, *next_plane;
804
805         /*
806          * Find a surface for each sprite in the output using some heuristics:
807          * 1) size
808          * 2) frequency of update
809          * 3) opacity (though some hw might support alpha blending)
810          * 4) clipping (this can be fixed with color keys)
811          *
812          * The idea is to save on blitting since this should save power.
813          * If we can get a large video surface on the sprite for example,
814          * the main display surface may not need to update at all, and
815          * the client buffer can be used directly for the sprite surface
816          * as we do for flipping full screen surfaces.
817          */
818         pixman_region32_init(&overlap);
819         primary = &c->base.primary_plane;
820         wl_list_for_each_safe(es, next, &c->base.surface_list, link) {
821                 pixman_region32_init(&surface_overlap);
822                 pixman_region32_intersect(&surface_overlap, &overlap,
823                                           &es->transform.boundingbox);
824
825                 next_plane = NULL;
826                 if (pixman_region32_not_empty(&surface_overlap))
827                         next_plane = primary;
828                 if (next_plane == NULL)
829                         next_plane = drm_output_prepare_cursor_surface(output, es);
830                 if (next_plane == NULL)
831                         next_plane = drm_output_prepare_scanout_surface(output, es);
832                 if (next_plane == NULL)
833                         next_plane = drm_output_prepare_overlay_surface(output, es);
834                 if (next_plane == NULL)
835                         next_plane = primary;
836                 weston_surface_move_to_plane(es, next_plane);
837                 if (next_plane == primary)
838                         pixman_region32_union(&overlap, &overlap,
839                                               &es->transform.boundingbox);
840
841                 pixman_region32_fini(&surface_overlap);
842         }
843         pixman_region32_fini(&overlap);
844 }
845
846 static void
847 drm_output_destroy(struct weston_output *output_base)
848 {
849         struct drm_output *output = (struct drm_output *) output_base;
850         struct drm_compositor *c =
851                 (struct drm_compositor *) output->base.compositor;
852         drmModeCrtcPtr origcrtc = output->original_crtc;
853
854         if (output->backlight)
855                 backlight_destroy(output->backlight);
856
857         /* Turn off hardware cursor */
858         drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
859
860         /* Restore original CRTC state */
861         drmModeSetCrtc(c->drm.fd, origcrtc->crtc_id, origcrtc->buffer_id,
862                        origcrtc->x, origcrtc->y,
863                        &output->connector_id, 1, &origcrtc->mode);
864         drmModeFreeCrtc(origcrtc);
865
866         c->crtc_allocator &= ~(1 << output->crtc_id);
867         c->connector_allocator &= ~(1 << output->connector_id);
868
869         eglDestroySurface(c->base.egl_display, output->base.egl_surface);
870         gbm_surface_destroy(output->surface);
871
872         weston_plane_release(&output->fb_plane);
873         weston_plane_release(&output->cursor_plane);
874
875         weston_output_destroy(&output->base);
876         wl_list_remove(&output->base.link);
877
878         free(output->name);
879         free(output);
880 }
881
882 static struct drm_mode *
883 choose_mode (struct drm_output *output, struct weston_mode *target_mode)
884 {
885         struct drm_mode *tmp_mode = NULL, *mode;
886
887         if (output->base.current->width == target_mode->width && 
888             output->base.current->height == target_mode->height &&
889             (output->base.current->refresh == target_mode->refresh ||
890              target_mode->refresh == 0))
891                 return (struct drm_mode *)output->base.current;
892
893         wl_list_for_each(mode, &output->base.mode_list, base.link) {
894                 if (mode->mode_info.hdisplay == target_mode->width &&
895                     mode->mode_info.vdisplay == target_mode->height) {
896                         if (mode->mode_info.vrefresh == target_mode->refresh || 
897                             target_mode->refresh == 0) {
898                                 return mode;
899                         } else if (!tmp_mode) 
900                                 tmp_mode = mode;
901                 }
902         }
903
904         return tmp_mode;
905 }
906
907 static int
908 drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mode)
909 {
910         struct drm_output *output;
911         struct drm_mode *drm_mode;
912         int ret;
913         struct drm_compositor *ec;
914         struct gbm_surface *surface;
915         EGLSurface egl_surface;
916
917         if (output_base == NULL) {
918                 weston_log("output is NULL.\n");
919                 return -1;
920         }
921
922         if (mode == NULL) {
923                 weston_log("mode is NULL.\n");
924                 return -1;
925         }
926
927         ec = (struct drm_compositor *)output_base->compositor;
928         output = (struct drm_output *)output_base;
929         drm_mode  = choose_mode (output, mode);
930
931         if (!drm_mode) {
932                 weston_log("%s, invalid resolution:%dx%d\n", __func__, mode->width, mode->height);
933                 return -1;
934         } else if (&drm_mode->base == output->base.current) {
935                 return 0;
936         } else if (drm_mode->base.width == output->base.current->width &&
937                    drm_mode->base.height == output->base.current->height) {
938                 /* only change refresh value */
939                 ret = drmModeSetCrtc(ec->drm.fd,
940                                      output->crtc_id,
941                                      output->current->fb_id, 0, 0,
942                                      &output->connector_id, 1, &drm_mode->mode_info);
943
944                 if (ret) {
945                         weston_log("failed to set mode (%dx%d) %u Hz\n",
946                                 drm_mode->base.width,
947                                 drm_mode->base.height,
948                                 drm_mode->base.refresh / 1000);
949                         ret = -1;
950                 } else {
951                         output->base.current->flags = 0;
952                         output->base.current = &drm_mode->base;
953                         drm_mode->base.flags = 
954                                 WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
955                         ret = 0;
956                 }
957
958                 return ret;
959         }
960
961         drm_mode->base.flags =
962                 WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
963
964         surface = gbm_surface_create(ec->gbm,
965                                  drm_mode->base.width,
966                                  drm_mode->base.height,
967                                  GBM_FORMAT_XRGB8888,
968                                  GBM_BO_USE_SCANOUT |
969                                  GBM_BO_USE_RENDERING);
970         if (!surface) {
971                 weston_log("failed to create gbm surface\n");
972                 return -1;
973         }
974
975         egl_surface =
976                 eglCreateWindowSurface(ec->base.egl_display,
977                                        ec->base.egl_config,
978                                        surface, NULL);
979
980         if (egl_surface == EGL_NO_SURFACE) {
981                 weston_log("failed to create egl surface\n");
982                 goto err;
983         }
984
985         ret = drmModeSetCrtc(ec->drm.fd,
986                              output->crtc_id,
987                              output->current->fb_id, 0, 0,
988                              &output->connector_id, 1, &drm_mode->mode_info);
989         if (ret) {
990                 weston_log("failed to set mode\n");
991                 goto err;
992         }
993
994         /* reset rendering stuff. */
995         if (output->current) {
996                 if (output->current->is_client_buffer)
997                         gbm_bo_destroy(output->current->bo);
998                 else
999                         gbm_surface_release_buffer(output->surface,
1000                                                    output->current->bo);
1001         }
1002         output->current = NULL;
1003
1004         if (output->next) {
1005                 if (output->next->is_client_buffer)
1006                         gbm_bo_destroy(output->next->bo);
1007                 else
1008                         gbm_surface_release_buffer(output->surface,
1009                                                    output->next->bo);
1010         }
1011         output->next = NULL;
1012
1013         eglDestroySurface(ec->base.egl_display, output->base.egl_surface);
1014         gbm_surface_destroy(output->surface);
1015         output->base.egl_surface = egl_surface;
1016         output->surface = surface;
1017
1018         /*update output*/
1019         output->base.current = &drm_mode->base;
1020         output->base.dirty = 1;
1021         weston_output_move(&output->base, output->base.x, output->base.y);
1022         return 0;
1023
1024 err:
1025         eglDestroySurface(ec->base.egl_display, egl_surface);
1026         gbm_surface_destroy(surface);
1027         return -1;
1028 }
1029
1030 static int
1031 on_drm_input(int fd, uint32_t mask, void *data)
1032 {
1033         drmEventContext evctx;
1034
1035         memset(&evctx, 0, sizeof evctx);
1036         evctx.version = DRM_EVENT_CONTEXT_VERSION;
1037         evctx.page_flip_handler = page_flip_handler;
1038         evctx.vblank_handler = vblank_handler;
1039         drmHandleEvent(fd, &evctx);
1040
1041         return 1;
1042 }
1043
1044 static int
1045 init_egl(struct drm_compositor *ec, struct udev_device *device)
1046 {
1047         EGLint major, minor, n;
1048         const char *filename, *sysnum;
1049         int fd;
1050         static const EGLint config_attribs[] = {
1051                 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
1052                 EGL_RED_SIZE, 1,
1053                 EGL_GREEN_SIZE, 1,
1054                 EGL_BLUE_SIZE, 1,
1055                 EGL_ALPHA_SIZE, 0,
1056                 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
1057                 EGL_NONE
1058         };
1059
1060         sysnum = udev_device_get_sysnum(device);
1061         if (sysnum)
1062                 ec->drm.id = atoi(sysnum);
1063         if (!sysnum || ec->drm.id < 0) {
1064                 weston_log("cannot get device sysnum\n");
1065                 return -1;
1066         }
1067
1068         filename = udev_device_get_devnode(device);
1069         fd = open(filename, O_RDWR | O_CLOEXEC);
1070         if (fd < 0) {
1071                 /* Probably permissions error */
1072                 weston_log("couldn't open %s, skipping\n",
1073                         udev_device_get_devnode(device));
1074                 return -1;
1075         }
1076
1077         weston_log("using %s\n", filename);
1078
1079         ec->drm.fd = fd;
1080         ec->gbm = gbm_create_device(ec->drm.fd);
1081         ec->base.egl_display = eglGetDisplay(ec->gbm);
1082         if (ec->base.egl_display == NULL) {
1083                 weston_log("failed to create display\n");
1084                 return -1;
1085         }
1086
1087         if (!eglInitialize(ec->base.egl_display, &major, &minor)) {
1088                 weston_log("failed to initialize display\n");
1089                 return -1;
1090         }
1091
1092         if (!eglChooseConfig(ec->base.egl_display, config_attribs,
1093                              &ec->base.egl_config, 1, &n) || n != 1) {
1094                 weston_log("failed to choose config: %d\n", n);
1095                 return -1;
1096         }
1097
1098         return 0;
1099 }
1100
1101 static struct drm_mode *
1102 drm_output_add_mode(struct drm_output *output, drmModeModeInfo *info)
1103 {
1104         struct drm_mode *mode;
1105         uint64_t refresh;
1106
1107         mode = malloc(sizeof *mode);
1108         if (mode == NULL)
1109                 return NULL;
1110
1111         mode->base.flags = 0;
1112         mode->base.width = info->hdisplay;
1113         mode->base.height = info->vdisplay;
1114
1115         /* Calculate higher precision (mHz) refresh rate */
1116         refresh = (info->clock * 1000000LL / info->htotal +
1117                    info->vtotal / 2) / info->vtotal;
1118
1119         if (info->flags & DRM_MODE_FLAG_INTERLACE)
1120                 refresh *= 2;
1121         if (info->flags & DRM_MODE_FLAG_DBLSCAN)
1122                 refresh /= 2;
1123         if (info->vscan > 1)
1124             refresh /= info->vscan;
1125
1126         mode->base.refresh = refresh;
1127         mode->mode_info = *info;
1128
1129         if (info->type & DRM_MODE_TYPE_PREFERRED)
1130                 mode->base.flags |= WL_OUTPUT_MODE_PREFERRED;
1131
1132         wl_list_insert(output->base.mode_list.prev, &mode->base.link);
1133
1134         return mode;
1135 }
1136
1137 static int
1138 drm_subpixel_to_wayland(int drm_value)
1139 {
1140         switch (drm_value) {
1141         default:
1142         case DRM_MODE_SUBPIXEL_UNKNOWN:
1143                 return WL_OUTPUT_SUBPIXEL_UNKNOWN;
1144         case DRM_MODE_SUBPIXEL_NONE:
1145                 return WL_OUTPUT_SUBPIXEL_NONE;
1146         case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
1147                 return WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
1148         case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
1149                 return WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR;
1150         case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
1151                 return WL_OUTPUT_SUBPIXEL_VERTICAL_RGB;
1152         case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
1153                 return WL_OUTPUT_SUBPIXEL_VERTICAL_BGR;
1154         }
1155 }
1156
1157 static void
1158 sprite_handle_buffer_destroy(struct wl_listener *listener, void *data)
1159 {
1160         struct drm_sprite *sprite =
1161                 container_of(listener, struct drm_sprite,
1162                              destroy_listener);
1163         struct drm_compositor *compositor = sprite->compositor;
1164
1165         sprite->surface = NULL;
1166         drmModeRmFB(compositor->drm.fd, sprite->fb_id);
1167         sprite->fb_id = 0;
1168 }
1169
1170 static void
1171 sprite_handle_pending_buffer_destroy(struct wl_listener *listener, void *data)
1172 {
1173         struct drm_sprite *sprite =
1174                 container_of(listener, struct drm_sprite,
1175                              pending_destroy_listener);
1176         struct drm_compositor *compositor = sprite->compositor;
1177
1178         sprite->pending_surface = NULL;
1179         drmModeRmFB(compositor->drm.fd, sprite->pending_fb_id);
1180         sprite->pending_fb_id = 0;
1181 }
1182
1183 /* returns a value between 0-255 range, where higher is brighter */
1184 static uint32_t
1185 drm_get_backlight(struct drm_output *output)
1186 {
1187         long brightness, max_brightness, norm;
1188
1189         brightness = backlight_get_brightness(output->backlight);
1190         max_brightness = backlight_get_max_brightness(output->backlight);
1191
1192         /* convert it on a scale of 0 to 255 */
1193         norm = (brightness * 255)/(max_brightness);
1194
1195         return (uint32_t) norm;
1196 }
1197
1198 /* values accepted are between 0-255 range */
1199 static void
1200 drm_set_backlight(struct weston_output *output_base, uint32_t value)
1201 {
1202         struct drm_output *output = (struct drm_output *) output_base;
1203         long max_brightness, new_brightness;
1204
1205         if (!output->backlight)
1206                 return;
1207
1208         if (value > 255)
1209                 return;
1210
1211         max_brightness = backlight_get_max_brightness(output->backlight);
1212
1213         /* get denormalized value */
1214         new_brightness = (value * max_brightness) / 255;
1215
1216         backlight_set_brightness(output->backlight, new_brightness);
1217 }
1218
1219 static drmModePropertyPtr
1220 drm_get_prop(int fd, drmModeConnectorPtr connector, const char *name)
1221 {
1222         drmModePropertyPtr props;
1223         int i;
1224
1225         for (i = 0; i < connector->count_props; i++) {
1226                 props = drmModeGetProperty(fd, connector->props[i]);
1227                 if (!props)
1228                         continue;
1229
1230                 if (!strcmp(props->name, name))
1231                         return props;
1232
1233                 drmModeFreeProperty(props);
1234         }
1235
1236         return NULL;
1237 }
1238
1239 static void
1240 drm_set_dpms(struct weston_output *output_base, enum dpms_enum level)
1241 {
1242         struct drm_output *output = (struct drm_output *) output_base;
1243         struct weston_compositor *ec = output_base->compositor;
1244         struct drm_compositor *c = (struct drm_compositor *) ec;
1245         drmModeConnectorPtr connector;
1246         drmModePropertyPtr prop;
1247
1248         connector = drmModeGetConnector(c->drm.fd, output->connector_id);
1249         if (!connector)
1250                 return;
1251
1252         prop = drm_get_prop(c->drm.fd, connector, "DPMS");
1253         if (!prop) {
1254                 drmModeFreeConnector(connector);
1255                 return;
1256         }
1257
1258         drmModeConnectorSetProperty(c->drm.fd, connector->connector_id,
1259                                     prop->prop_id, level);
1260         drmModeFreeProperty(prop);
1261         drmModeFreeConnector(connector);
1262 }
1263
1264 static const char *connector_type_names[] = {
1265         "None",
1266         "VGA",
1267         "DVI",
1268         "DVI",
1269         "DVI",
1270         "Composite",
1271         "TV",
1272         "LVDS",
1273         "CTV",
1274         "DIN",
1275         "DP",
1276         "HDMI",
1277         "HDMI",
1278         "TV",
1279         "eDP",
1280 };
1281
1282 static int
1283 find_crtc_for_connector(struct drm_compositor *ec,
1284                         drmModeRes *resources, drmModeConnector *connector)
1285 {
1286         drmModeEncoder *encoder;
1287         uint32_t possible_crtcs;
1288         int i, j;
1289
1290         for (j = 0; j < connector->count_encoders; j++) {
1291                 encoder = drmModeGetEncoder(ec->drm.fd, connector->encoders[j]);
1292                 if (encoder == NULL) {
1293                         weston_log("Failed to get encoder.\n");
1294                         return -1;
1295                 }
1296                 possible_crtcs = encoder->possible_crtcs;
1297                 drmModeFreeEncoder(encoder);
1298
1299                 for (i = 0; i < resources->count_crtcs; i++) {
1300                         if (possible_crtcs & (1 << i) &&
1301                             !(ec->crtc_allocator & (1 << resources->crtcs[i])))
1302                                 return i;
1303                 }
1304         }
1305
1306         return -1;
1307 }
1308
1309 static int
1310 create_output_for_connector(struct drm_compositor *ec,
1311                             drmModeRes *resources,
1312                             drmModeConnector *connector,
1313                             int x, int y, struct udev_device *drm_device)
1314 {
1315         struct drm_output *output;
1316         struct drm_mode *drm_mode, *next, *preferred, *current, *configured;
1317         struct weston_mode *m;
1318         struct drm_configured_output *o = NULL, *temp;
1319         drmModeEncoder *encoder;
1320         drmModeModeInfo crtc_mode;
1321         drmModeCrtc *crtc;
1322         int i;
1323         char name[32];
1324         const char *type_name;
1325
1326         i = find_crtc_for_connector(ec, resources, connector);
1327         if (i < 0) {
1328                 weston_log("No usable crtc/encoder pair for connector.\n");
1329                 return -1;
1330         }
1331
1332         output = malloc(sizeof *output);
1333         if (output == NULL)
1334                 return -1;
1335
1336         memset(output, 0, sizeof *output);
1337         output->base.subpixel = drm_subpixel_to_wayland(connector->subpixel);
1338         output->base.make = "unknown";
1339         output->base.model = "unknown";
1340         wl_list_init(&output->base.mode_list);
1341
1342         if (connector->connector_type < ARRAY_LENGTH(connector_type_names))
1343                 type_name = connector_type_names[connector->connector_type];
1344         else
1345                 type_name = "UNKNOWN";
1346         snprintf(name, 32, "%s%d", type_name, connector->connector_type_id);
1347         output->name = strdup(name);
1348
1349         output->crtc_id = resources->crtcs[i];
1350         output->pipe = i;
1351         ec->crtc_allocator |= (1 << output->crtc_id);
1352         output->connector_id = connector->connector_id;
1353         ec->connector_allocator |= (1 << output->connector_id);
1354
1355         output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id);
1356
1357         /* Get the current mode on the crtc that's currently driving
1358          * this connector. */
1359         encoder = drmModeGetEncoder(ec->drm.fd, connector->encoder_id);
1360         memset(&crtc_mode, 0, sizeof crtc_mode);
1361         if (encoder != NULL) {
1362                 crtc = drmModeGetCrtc(ec->drm.fd, encoder->crtc_id);
1363                 drmModeFreeEncoder(encoder);
1364                 if (crtc == NULL)
1365                         goto err_free;
1366                 if (crtc->mode_valid)
1367                         crtc_mode = crtc->mode;
1368                 drmModeFreeCrtc(crtc);
1369         }
1370
1371         for (i = 0; i < connector->count_modes; i++) {
1372                 drm_mode = drm_output_add_mode(output, &connector->modes[i]);
1373                 if (!drm_mode)
1374                         goto err_free;
1375         }
1376
1377         preferred = NULL;
1378         current = NULL;
1379         configured = NULL;
1380
1381         wl_list_for_each(temp, &configured_output_list, link) {
1382                 if (strcmp(temp->name, output->name) == 0) {
1383                         if (temp->mode)
1384                                 weston_log("%s mode \"%s\" in config\n",
1385                                                         temp->name, temp->mode);
1386                         o = temp;
1387                         break;
1388                 }
1389         }
1390
1391         if (o && o->config == OUTPUT_CONFIG_OFF) {
1392                 weston_log("Disabling output %s\n", o->name);
1393
1394                 drmModeSetCrtc(ec->drm.fd, output->crtc_id,
1395                                                         0, 0, 0, 0, 0, NULL);
1396                 goto err_free;
1397         }
1398
1399         wl_list_for_each(drm_mode, &output->base.mode_list, base.link) {
1400                 if (o && o->config == OUTPUT_CONFIG_MODE &&
1401                         o->width == drm_mode->base.width &&
1402                         o->height == drm_mode->base.height)
1403                         configured = drm_mode;
1404                 if (!memcmp(&crtc_mode, &drm_mode->mode_info, sizeof crtc_mode))
1405                         current = drm_mode;
1406                 if (drm_mode->base.flags & WL_OUTPUT_MODE_PREFERRED)
1407                         preferred = drm_mode;
1408         }
1409
1410         if (o && o->config == OUTPUT_CONFIG_MODELINE) {
1411                 configured = drm_output_add_mode(output, &o->crtc_mode);
1412                 if (!configured)
1413                         goto err_free;
1414                 current = configured;
1415         }
1416
1417         if (current == NULL && crtc_mode.clock != 0) {
1418                 current = drm_output_add_mode(output, &crtc_mode);
1419                 if (!current)
1420                         goto err_free;
1421         }
1422
1423         if (o && o->config == OUTPUT_CONFIG_CURRENT)
1424                 configured = current;
1425
1426         if (option_current_mode && current)
1427                 output->base.current = &current->base;
1428         else if (configured)
1429                 output->base.current = &configured->base;
1430         else if (preferred)
1431                 output->base.current = &preferred->base;
1432         else if (current)
1433                 output->base.current = &current->base;
1434
1435         if (output->base.current == NULL) {
1436                 weston_log("no available modes for %s\n", output->name);
1437                 goto err_free;
1438         }
1439
1440         output->base.current->flags |= WL_OUTPUT_MODE_CURRENT;
1441
1442         output->surface = gbm_surface_create(ec->gbm,
1443                                              output->base.current->width,
1444                                              output->base.current->height,
1445                                              GBM_FORMAT_XRGB8888,
1446                                              GBM_BO_USE_SCANOUT |
1447                                              GBM_BO_USE_RENDERING);
1448         if (!output->surface) {
1449                 weston_log("failed to create gbm surface\n");
1450                 goto err_free;
1451         }
1452
1453         output->base.egl_surface =
1454                 eglCreateWindowSurface(ec->base.egl_display,
1455                                        ec->base.egl_config,
1456                                        output->surface,
1457                                        NULL);
1458         if (output->base.egl_surface == EGL_NO_SURFACE) {
1459                 weston_log("failed to create egl surface\n");
1460                 goto err_surface;
1461         }
1462
1463         output->cursor_bo[0] =
1464                 gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
1465                               GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
1466         output->cursor_bo[1] =
1467                 gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
1468                               GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
1469         if (output->cursor_bo[0] == NULL || output->cursor_bo[1] == NULL) {
1470                 weston_log("cursor buffers unavailable, using gl cursors\n");
1471                 ec->cursors_are_broken = 1;
1472         }
1473
1474         output->backlight = backlight_init(drm_device,
1475                                            connector->connector_type);
1476         if (output->backlight) {
1477                 output->base.set_backlight = drm_set_backlight;
1478                 output->base.backlight_current = drm_get_backlight(output);
1479         }
1480
1481         weston_output_init(&output->base, &ec->base, x, y,
1482                            connector->mmWidth, connector->mmHeight,
1483                            o ? o->transform : WL_OUTPUT_TRANSFORM_NORMAL);
1484
1485         wl_list_insert(ec->base.output_list.prev, &output->base.link);
1486
1487         output->base.origin = output->base.current;
1488         output->base.repaint = drm_output_repaint;
1489         output->base.destroy = drm_output_destroy;
1490         output->base.assign_planes = drm_assign_planes;
1491         output->base.set_dpms = drm_set_dpms;
1492         output->base.switch_mode = drm_output_switch_mode;
1493
1494         weston_plane_init(&output->cursor_plane, 0, 0);
1495         weston_plane_init(&output->fb_plane, 0, 0);
1496
1497         weston_log("Output %s, (connector %d, crtc %d)\n",
1498                    output->name, output->connector_id, output->crtc_id);
1499         wl_list_for_each(m, &output->base.mode_list, link)
1500                 weston_log_continue("  mode %dx%d@%.1f%s%s%s\n",
1501                                     m->width, m->height, m->refresh / 1000.0,
1502                                     m->flags & WL_OUTPUT_MODE_PREFERRED ?
1503                                     ", preferred" : "",
1504                                     m->flags & WL_OUTPUT_MODE_CURRENT ?
1505                                     ", current" : "",
1506                                     connector->count_modes == 0 ?
1507                                     ", built-in" : "");
1508
1509         return 0;
1510
1511 err_surface:
1512         gbm_surface_destroy(output->surface);
1513 err_free:
1514         wl_list_for_each_safe(drm_mode, next, &output->base.mode_list,
1515                                                         base.link) {
1516                 wl_list_remove(&drm_mode->base.link);
1517                 free(drm_mode);
1518         }
1519
1520         drmModeFreeCrtc(output->original_crtc);
1521         ec->crtc_allocator &= ~(1 << output->crtc_id);
1522         ec->connector_allocator &= ~(1 << output->connector_id);
1523         free(output->name);
1524         free(output);
1525
1526         return -1;
1527 }
1528
1529 static void
1530 create_sprites(struct drm_compositor *ec)
1531 {
1532         struct drm_sprite *sprite;
1533         drmModePlaneRes *plane_res;
1534         drmModePlane *plane;
1535         uint32_t i;
1536
1537         plane_res = drmModeGetPlaneResources(ec->drm.fd);
1538         if (!plane_res) {
1539                 weston_log("failed to get plane resources: %s\n",
1540                         strerror(errno));
1541                 return;
1542         }
1543
1544         for (i = 0; i < plane_res->count_planes; i++) {
1545                 plane = drmModeGetPlane(ec->drm.fd, plane_res->planes[i]);
1546                 if (!plane)
1547                         continue;
1548
1549                 sprite = malloc(sizeof(*sprite) + ((sizeof(uint32_t)) *
1550                                                    plane->count_formats));
1551                 if (!sprite) {
1552                         weston_log("%s: out of memory\n",
1553                                 __func__);
1554                         free(plane);
1555                         continue;
1556                 }
1557
1558                 memset(sprite, 0, sizeof *sprite);
1559
1560                 sprite->possible_crtcs = plane->possible_crtcs;
1561                 sprite->plane_id = plane->plane_id;
1562                 sprite->surface = NULL;
1563                 sprite->pending_surface = NULL;
1564                 sprite->fb_id = 0;
1565                 sprite->pending_fb_id = 0;
1566                 sprite->destroy_listener.notify = sprite_handle_buffer_destroy;
1567                 sprite->pending_destroy_listener.notify =
1568                         sprite_handle_pending_buffer_destroy;
1569                 sprite->compositor = ec;
1570                 sprite->count_formats = plane->count_formats;
1571                 memcpy(sprite->formats, plane->formats,
1572                        plane->count_formats * sizeof(plane->formats[0]));
1573                 drmModeFreePlane(plane);
1574                 weston_plane_init(&sprite->plane, 0, 0);
1575
1576                 wl_list_insert(&ec->sprite_list, &sprite->link);
1577         }
1578
1579         free(plane_res->planes);
1580         free(plane_res);
1581 }
1582
1583 static void
1584 destroy_sprites(struct drm_compositor *compositor)
1585 {
1586         struct drm_sprite *sprite, *next;
1587         struct drm_output *output;
1588
1589         output = container_of(compositor->base.output_list.next,
1590                               struct drm_output, base.link);
1591
1592         wl_list_for_each_safe(sprite, next, &compositor->sprite_list, link) {
1593                 drmModeSetPlane(compositor->drm.fd,
1594                                 sprite->plane_id,
1595                                 output->crtc_id, 0, 0,
1596                                 0, 0, 0, 0, 0, 0, 0, 0);
1597                 drmModeRmFB(compositor->drm.fd, sprite->fb_id);
1598                 weston_plane_release(&sprite->plane);
1599                 free(sprite);
1600         }
1601 }
1602
1603 static int
1604 create_outputs(struct drm_compositor *ec, uint32_t option_connector,
1605                struct udev_device *drm_device)
1606 {
1607         drmModeConnector *connector;
1608         drmModeRes *resources;
1609         int i;
1610         int x = 0, y = 0;
1611
1612         resources = drmModeGetResources(ec->drm.fd);
1613         if (!resources) {
1614                 weston_log("drmModeGetResources failed\n");
1615                 return -1;
1616         }
1617
1618         ec->crtcs = calloc(resources->count_crtcs, sizeof(uint32_t));
1619         if (!ec->crtcs) {
1620                 drmModeFreeResources(resources);
1621                 return -1;
1622         }
1623
1624         ec->min_width  = resources->min_width;
1625         ec->max_width  = resources->max_width;
1626         ec->min_height = resources->min_height;
1627         ec->max_height = resources->max_height;
1628
1629         ec->num_crtcs = resources->count_crtcs;
1630         memcpy(ec->crtcs, resources->crtcs, sizeof(uint32_t) * ec->num_crtcs);
1631
1632         for (i = 0; i < resources->count_connectors; i++) {
1633                 connector = drmModeGetConnector(ec->drm.fd,
1634                                                 resources->connectors[i]);
1635                 if (connector == NULL)
1636                         continue;
1637
1638                 if (connector->connection == DRM_MODE_CONNECTED &&
1639                     (option_connector == 0 ||
1640                      connector->connector_id == option_connector)) {
1641                         if (create_output_for_connector(ec, resources,
1642                                                         connector, x, y,
1643                                                         drm_device) < 0) {
1644                                 drmModeFreeConnector(connector);
1645                                 continue;
1646                         }
1647
1648                         x += container_of(ec->base.output_list.prev,
1649                                           struct weston_output,
1650                                           link)->width;
1651                 }
1652
1653                 drmModeFreeConnector(connector);
1654         }
1655
1656         if (wl_list_empty(&ec->base.output_list)) {
1657                 weston_log("No currently active connector found.\n");
1658                 drmModeFreeResources(resources);
1659                 return -1;
1660         }
1661
1662         drmModeFreeResources(resources);
1663
1664         return 0;
1665 }
1666
1667 static void
1668 update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
1669 {
1670         drmModeConnector *connector;
1671         drmModeRes *resources;
1672         struct drm_output *output, *next;
1673         int x = 0, y = 0;
1674         int x_offset = 0, y_offset = 0;
1675         uint32_t connected = 0, disconnects = 0;
1676         int i;
1677
1678         resources = drmModeGetResources(ec->drm.fd);
1679         if (!resources) {
1680                 weston_log("drmModeGetResources failed\n");
1681                 return;
1682         }
1683
1684         /* collect new connects */
1685         for (i = 0; i < resources->count_connectors; i++) {
1686                 int connector_id = resources->connectors[i];
1687
1688                 connector = drmModeGetConnector(ec->drm.fd, connector_id);
1689                 if (connector == NULL)
1690                         continue;
1691
1692                 if (connector->connection != DRM_MODE_CONNECTED) {
1693                         drmModeFreeConnector(connector);
1694                         continue;
1695                 }
1696
1697                 connected |= (1 << connector_id);
1698
1699                 if (!(ec->connector_allocator & (1 << connector_id))) {
1700                         struct weston_output *last =
1701                                 container_of(ec->base.output_list.prev,
1702                                              struct weston_output, link);
1703
1704                         /* XXX: not yet needed, we die with 0 outputs */
1705                         if (!wl_list_empty(&ec->base.output_list))
1706                                 x = last->x + last->width;
1707                         else
1708                                 x = 0;
1709                         y = 0;
1710                         create_output_for_connector(ec, resources,
1711                                                     connector, x, y,
1712                                                     drm_device);
1713                         weston_log("connector %d connected\n", connector_id);
1714
1715                 }
1716                 drmModeFreeConnector(connector);
1717         }
1718         drmModeFreeResources(resources);
1719
1720         disconnects = ec->connector_allocator & ~connected;
1721         if (disconnects) {
1722                 wl_list_for_each_safe(output, next, &ec->base.output_list,
1723                                       base.link) {
1724                         if (x_offset != 0 || y_offset != 0) {
1725                                 weston_output_move(&output->base,
1726                                                  output->base.x - x_offset,
1727                                                  output->base.y - y_offset);
1728                         }
1729
1730                         if (disconnects & (1 << output->connector_id)) {
1731                                 disconnects &= ~(1 << output->connector_id);
1732                                 weston_log("connector %d disconnected\n",
1733                                        output->connector_id);
1734                                 x_offset += output->base.width;
1735                                 drm_output_destroy(&output->base);
1736                         }
1737                 }
1738         }
1739
1740         /* FIXME: handle zero outputs, without terminating */   
1741         if (ec->connector_allocator == 0)
1742                 wl_display_terminate(ec->base.wl_display);
1743 }
1744
1745 static int
1746 udev_event_is_hotplug(struct drm_compositor *ec, struct udev_device *device)
1747 {
1748         const char *sysnum;
1749         const char *val;
1750
1751         sysnum = udev_device_get_sysnum(device);
1752         if (!sysnum || atoi(sysnum) != ec->drm.id)
1753                 return 0;
1754
1755         val = udev_device_get_property_value(device, "HOTPLUG");
1756         if (!val)
1757                 return 0;
1758
1759         return strcmp(val, "1") == 0;
1760 }
1761
1762 static int
1763 udev_drm_event(int fd, uint32_t mask, void *data)
1764 {
1765         struct drm_compositor *ec = data;
1766         struct udev_device *event;
1767
1768         event = udev_monitor_receive_device(ec->udev_monitor);
1769
1770         if (udev_event_is_hotplug(ec, event))
1771                 update_outputs(ec, event);
1772
1773         udev_device_unref(event);
1774
1775         return 1;
1776 }
1777
1778 static void
1779 drm_restore(struct weston_compositor *ec)
1780 {
1781         struct drm_compositor *d = (struct drm_compositor *) ec;
1782
1783         if (weston_launcher_drm_set_master(&d->base, d->drm.fd, 0) < 0)
1784                 weston_log("failed to drop master: %m\n");
1785         tty_reset(d->tty);
1786 }
1787
1788 static const char default_seat[] = "seat0";
1789
1790 static void
1791 device_added(struct udev_device *udev_device, struct drm_seat *master)
1792 {
1793         struct weston_compositor *c;
1794         struct evdev_device *device;
1795         const char *devnode;
1796         const char *device_seat;
1797         int fd;
1798
1799         device_seat = udev_device_get_property_value(udev_device, "ID_SEAT");
1800         if (!device_seat)
1801                 device_seat = default_seat;
1802
1803         if (strcmp(device_seat, master->seat_id))
1804                 return;
1805
1806         c = master->base.compositor;
1807         devnode = udev_device_get_devnode(udev_device);
1808
1809         /* Use non-blocking mode so that we can loop on read on
1810          * evdev_device_data() until all events on the fd are
1811          * read.  mtdev_get() also expects this. */
1812         fd = weston_launcher_open(c, devnode, O_RDWR | O_NONBLOCK);
1813         if (fd < 0) {
1814                 weston_log("opening input device '%s' failed.\n", devnode);
1815                 return;
1816         }
1817
1818         device = evdev_device_create(&master->base, devnode, fd);
1819         if (!device) {
1820                 close(fd);
1821                 weston_log("not using input device '%s'.\n", devnode);
1822                 return;
1823         }
1824
1825         wl_list_insert(master->devices_list.prev, &device->link);
1826 }
1827
1828 static void
1829 evdev_add_devices(struct udev *udev, struct weston_seat *seat_base)
1830 {
1831         struct drm_seat *seat = (struct drm_seat *) seat_base;
1832         struct udev_enumerate *e;
1833         struct udev_list_entry *entry;
1834         struct udev_device *device;
1835         const char *path, *sysname;
1836
1837         e = udev_enumerate_new(udev);
1838         udev_enumerate_add_match_subsystem(e, "input");
1839         udev_enumerate_scan_devices(e);
1840         udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
1841                 path = udev_list_entry_get_name(entry);
1842                 device = udev_device_new_from_syspath(udev, path);
1843
1844                 sysname = udev_device_get_sysname(device);
1845                 if (strncmp("event", sysname, 5) != 0) {
1846                         udev_device_unref(device);
1847                         continue;
1848                 }
1849
1850                 device_added(device, seat);
1851
1852                 udev_device_unref(device);
1853         }
1854         udev_enumerate_unref(e);
1855
1856         evdev_notify_keyboard_focus(&seat->base, &seat->devices_list);
1857
1858         if (wl_list_empty(&seat->devices_list)) {
1859                 weston_log(
1860                         "warning: no input devices on entering Weston. "
1861                         "Possible causes:\n"
1862                         "\t- no permissions to read /dev/input/event*\n"
1863                         "\t- seats misconfigured "
1864                         "(Weston backend option 'seat', "
1865                         "udev device property ID_SEAT)\n");
1866         }
1867 }
1868
1869 static int
1870 evdev_udev_handler(int fd, uint32_t mask, void *data)
1871 {
1872         struct drm_seat *seat = data;
1873         struct udev_device *udev_device;
1874         struct evdev_device *device, *next;
1875         const char *action;
1876         const char *devnode;
1877
1878         udev_device = udev_monitor_receive_device(seat->udev_monitor);
1879         if (!udev_device)
1880                 return 1;
1881
1882         action = udev_device_get_action(udev_device);
1883         if (!action)
1884                 goto out;
1885
1886         if (strncmp("event", udev_device_get_sysname(udev_device), 5) != 0)
1887                 goto out;
1888
1889         if (!strcmp(action, "add")) {
1890                 device_added(udev_device, seat);
1891         }
1892         else if (!strcmp(action, "remove")) {
1893                 devnode = udev_device_get_devnode(udev_device);
1894                 wl_list_for_each_safe(device, next, &seat->devices_list, link)
1895                         if (!strcmp(device->devnode, devnode)) {
1896                                 weston_log("input device %s, %s removed\n",
1897                                            device->devname, device->devnode);
1898                                 evdev_device_destroy(device);
1899                                 break;
1900                         }
1901         }
1902
1903 out:
1904         udev_device_unref(udev_device);
1905
1906         return 0;
1907 }
1908
1909 static int
1910 evdev_enable_udev_monitor(struct udev *udev, struct weston_seat *seat_base)
1911 {
1912         struct drm_seat *master = (struct drm_seat *) seat_base;
1913         struct wl_event_loop *loop;
1914         struct weston_compositor *c = master->base.compositor;
1915         int fd;
1916
1917         master->udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
1918         if (!master->udev_monitor) {
1919                 weston_log("udev: failed to create the udev monitor\n");
1920                 return 0;
1921         }
1922
1923         udev_monitor_filter_add_match_subsystem_devtype(master->udev_monitor,
1924                         "input", NULL);
1925
1926         if (udev_monitor_enable_receiving(master->udev_monitor)) {
1927                 weston_log("udev: failed to bind the udev monitor\n");
1928                 udev_monitor_unref(master->udev_monitor);
1929                 return 0;
1930         }
1931
1932         loop = wl_display_get_event_loop(c->wl_display);
1933         fd = udev_monitor_get_fd(master->udev_monitor);
1934         master->udev_monitor_source =
1935                 wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
1936                                      evdev_udev_handler, master);
1937         if (!master->udev_monitor_source) {
1938                 udev_monitor_unref(master->udev_monitor);
1939                 return 0;
1940         }
1941
1942         return 1;
1943 }
1944
1945 static void
1946 evdev_disable_udev_monitor(struct weston_seat *seat_base)
1947 {
1948         struct drm_seat *seat = (struct drm_seat *) seat_base;
1949
1950         if (!seat->udev_monitor)
1951                 return;
1952
1953         udev_monitor_unref(seat->udev_monitor);
1954         seat->udev_monitor = NULL;
1955         wl_event_source_remove(seat->udev_monitor_source);
1956         seat->udev_monitor_source = NULL;
1957 }
1958
1959 static void
1960 drm_led_update(struct weston_seat *seat_base, enum weston_led leds)
1961 {
1962         struct drm_seat *seat = (struct drm_seat *) seat_base;
1963         struct evdev_device *device;
1964
1965         wl_list_for_each(device, &seat->devices_list, link)
1966                 evdev_led_update(device, leds);
1967 }
1968
1969 static void
1970 evdev_input_create(struct weston_compositor *c, struct udev *udev,
1971                    const char *seat_id)
1972 {
1973         struct drm_seat *seat;
1974
1975         seat = malloc(sizeof *seat);
1976         if (seat == NULL)
1977                 return;
1978
1979         memset(seat, 0, sizeof *seat);
1980         weston_seat_init(&seat->base, c);
1981         seat->base.led_update = drm_led_update;
1982
1983         wl_list_init(&seat->devices_list);
1984         seat->seat_id = strdup(seat_id);
1985         if (!evdev_enable_udev_monitor(udev, &seat->base)) {
1986                 free(seat->seat_id);
1987                 free(seat);
1988                 return;
1989         }
1990
1991         evdev_add_devices(udev, &seat->base);
1992 }
1993
1994 static void
1995 evdev_remove_devices(struct weston_seat *seat_base)
1996 {
1997         struct drm_seat *seat = (struct drm_seat *) seat_base;
1998         struct evdev_device *device, *next;
1999
2000         wl_list_for_each_safe(device, next, &seat->devices_list, link)
2001                 evdev_device_destroy(device);
2002
2003         if (seat->base.seat.keyboard)
2004                 notify_keyboard_focus_out(&seat->base);
2005 }
2006
2007 static void
2008 evdev_input_destroy(struct weston_seat *seat_base)
2009 {
2010         struct drm_seat *seat = (struct drm_seat *) seat_base;
2011
2012         evdev_remove_devices(seat_base);
2013         evdev_disable_udev_monitor(&seat->base);
2014
2015         weston_seat_release(seat_base);
2016         free(seat->seat_id);
2017         free(seat);
2018 }
2019
2020 static void
2021 drm_free_configured_output(struct drm_configured_output *output)
2022 {
2023         free(output->name);
2024         free(output->mode);
2025         free(output);
2026 }
2027
2028 static void
2029 drm_destroy(struct weston_compositor *ec)
2030 {
2031         struct drm_compositor *d = (struct drm_compositor *) ec;
2032         struct weston_seat *seat, *next;
2033         struct drm_configured_output *o, *n;
2034
2035         wl_list_for_each_safe(seat, next, &ec->seat_list, link)
2036                 evdev_input_destroy(seat);
2037         wl_list_for_each_safe(o, n, &configured_output_list, link)
2038                 drm_free_configured_output(o);
2039
2040         wl_event_source_remove(d->udev_drm_source);
2041         wl_event_source_remove(d->drm_source);
2042
2043         weston_compositor_shutdown(ec);
2044
2045         gles2_renderer_destroy(ec);
2046
2047         /* Work around crash in egl_dri2.c's dri2_make_current() */
2048         eglMakeCurrent(ec->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
2049                        EGL_NO_CONTEXT);
2050         eglTerminate(ec->egl_display);
2051         eglReleaseThread();
2052
2053         gbm_device_destroy(d->gbm);
2054         destroy_sprites(d);
2055         if (weston_launcher_drm_set_master(&d->base, d->drm.fd, 0) < 0)
2056                 weston_log("failed to drop master: %m\n");
2057         tty_destroy(d->tty);
2058
2059         free(d);
2060 }
2061
2062 static void
2063 drm_compositor_set_modes(struct drm_compositor *compositor)
2064 {
2065         struct drm_output *output;
2066         struct drm_mode *drm_mode;
2067         int ret;
2068
2069         wl_list_for_each(output, &compositor->base.output_list, base.link) {
2070                 drm_mode = (struct drm_mode *) output->base.current;
2071                 ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
2072                                      output->current->fb_id, 0, 0,
2073                                      &output->connector_id, 1,
2074                                      &drm_mode->mode_info);
2075                 if (ret < 0) {
2076                         weston_log(
2077                                 "failed to set mode %dx%d for output at %d,%d: %m\n",
2078                                 drm_mode->base.width, drm_mode->base.height, 
2079                                 output->base.x, output->base.y);
2080                 }
2081         }
2082 }
2083
2084 static void
2085 vt_func(struct weston_compositor *compositor, int event)
2086 {
2087         struct drm_compositor *ec = (struct drm_compositor *) compositor;
2088         struct weston_seat *seat;
2089         struct drm_sprite *sprite;
2090         struct drm_output *output;
2091
2092         switch (event) {
2093         case TTY_ENTER_VT:
2094                 weston_log("entering VT\n");
2095                 compositor->focus = 1;
2096                 if (weston_launcher_drm_set_master(&ec->base, ec->drm.fd, 1)) {
2097                         weston_log("failed to set master: %m\n");
2098                         wl_display_terminate(compositor->wl_display);
2099                 }
2100                 compositor->state = ec->prev_state;
2101                 drm_compositor_set_modes(ec);
2102                 weston_compositor_damage_all(compositor);
2103                 wl_list_for_each(seat, &compositor->seat_list, link) {
2104                         evdev_add_devices(ec->udev, seat);
2105                         evdev_enable_udev_monitor(ec->udev, seat);
2106                 }
2107                 break;
2108         case TTY_LEAVE_VT:
2109                 weston_log("leaving VT\n");
2110                 wl_list_for_each(seat, &compositor->seat_list, link) {
2111                         evdev_disable_udev_monitor(seat);
2112                         evdev_remove_devices(seat);
2113                 }
2114
2115                 compositor->focus = 0;
2116                 ec->prev_state = compositor->state;
2117                 compositor->state = WESTON_COMPOSITOR_SLEEPING;
2118
2119                 /* If we have a repaint scheduled (either from a
2120                  * pending pageflip or the idle handler), make sure we
2121                  * cancel that so we don't try to pageflip when we're
2122                  * vt switched away.  The SLEEPING state will prevent
2123                  * further attemps at repainting.  When we switch
2124                  * back, we schedule a repaint, which will process
2125                  * pending frame callbacks. */
2126
2127                 wl_list_for_each(output, &ec->base.output_list, base.link) {
2128                         output->base.repaint_needed = 0;
2129                         drmModeSetCursor(ec->drm.fd, output->crtc_id, 0, 0, 0);
2130                 }
2131
2132                 output = container_of(ec->base.output_list.next,
2133                                       struct drm_output, base.link);
2134
2135                 wl_list_for_each(sprite, &ec->sprite_list, link)
2136                         drmModeSetPlane(ec->drm.fd,
2137                                         sprite->plane_id,
2138                                         output->crtc_id, 0, 0,
2139                                         0, 0, 0, 0, 0, 0, 0, 0);
2140
2141                 if (weston_launcher_drm_set_master(&ec->base, ec->drm.fd, 0) < 0)
2142                         weston_log("failed to drop master: %m\n");
2143
2144                 break;
2145         };
2146 }
2147
2148 static void
2149 switch_vt_binding(struct wl_seat *seat, uint32_t time, uint32_t key, void *data)
2150 {
2151         struct drm_compositor *ec = data;
2152
2153         tty_activate_vt(ec->tty, key - KEY_F1 + 1);
2154 }
2155
2156 static struct weston_compositor *
2157 drm_compositor_create(struct wl_display *display,
2158                       int connector, const char *seat, int tty,
2159                       int argc, char *argv[], const char *config_file)
2160 {
2161         struct drm_compositor *ec;
2162         struct udev_enumerate *e;
2163         struct udev_list_entry *entry;
2164         struct udev_device *device, *drm_device;
2165         const char *path, *device_seat;
2166         struct wl_event_loop *loop;
2167         struct weston_seat *weston_seat, *next;
2168         uint32_t key;
2169
2170         weston_log("initializing drm backend\n");
2171
2172         ec = malloc(sizeof *ec);
2173         if (ec == NULL)
2174                 return NULL;
2175         memset(ec, 0, sizeof *ec);
2176
2177         if (weston_compositor_init(&ec->base, display, argc, argv,
2178                                    config_file) < 0) {
2179                 weston_log("weston_compositor_init failed\n");
2180                 goto err_base;
2181         }
2182
2183         ec->udev = udev_new();
2184         if (ec->udev == NULL) {
2185                 weston_log("failed to initialize udev context\n");
2186                 goto err_compositor;
2187         }
2188
2189         ec->base.wl_display = display;
2190         ec->tty = tty_create(&ec->base, vt_func, tty);
2191         if (!ec->tty) {
2192                 weston_log("failed to initialize tty\n");
2193                 goto err_udev;
2194         }
2195
2196         e = udev_enumerate_new(ec->udev);
2197         udev_enumerate_add_match_subsystem(e, "drm");
2198         udev_enumerate_add_match_sysname(e, "card[0-9]*");
2199
2200         udev_enumerate_scan_devices(e);
2201         drm_device = NULL;
2202         udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
2203                 path = udev_list_entry_get_name(entry);
2204                 device = udev_device_new_from_syspath(ec->udev, path);
2205                 device_seat =
2206                         udev_device_get_property_value(device, "ID_SEAT");
2207                 if (!device_seat)
2208                         device_seat = default_seat;
2209                 if (strcmp(device_seat, seat) == 0) {
2210                         drm_device = device;
2211                         break;
2212                 }
2213                 udev_device_unref(device);
2214         }
2215
2216         if (drm_device == NULL) {
2217                 weston_log("no drm device found\n");
2218                 goto err_udev_enum;
2219         }
2220
2221         if (init_egl(ec, drm_device) < 0) {
2222                 weston_log("failed to initialize egl\n");
2223                 goto err_udev_dev;
2224         }
2225
2226         ec->base.destroy = drm_destroy;
2227         ec->base.restore = drm_restore;
2228
2229         ec->base.focus = 1;
2230
2231         ec->prev_state = WESTON_COMPOSITOR_ACTIVE;
2232
2233         for (key = KEY_F1; key < KEY_F9; key++)
2234                 weston_compositor_add_key_binding(&ec->base, key,
2235                                                   MODIFIER_CTRL | MODIFIER_ALT,
2236                                                   switch_vt_binding, ec);
2237
2238         wl_list_init(&ec->sprite_list);
2239         create_sprites(ec);
2240
2241         if (create_outputs(ec, connector, drm_device) < 0) {
2242                 weston_log("failed to create output for %s\n", path);
2243                 goto err_sprite;
2244         }
2245
2246         if (gles2_renderer_init(&ec->base) < 0)
2247                 goto err_egl;
2248
2249         path = NULL;
2250
2251         evdev_input_create(&ec->base, ec->udev, seat);
2252
2253         loop = wl_display_get_event_loop(ec->base.wl_display);
2254         ec->drm_source =
2255                 wl_event_loop_add_fd(loop, ec->drm.fd,
2256                                      WL_EVENT_READABLE, on_drm_input, ec);
2257
2258         ec->udev_monitor = udev_monitor_new_from_netlink(ec->udev, "udev");
2259         if (ec->udev_monitor == NULL) {
2260                 weston_log("failed to intialize udev monitor\n");
2261                 goto err_drm_source;
2262         }
2263         udev_monitor_filter_add_match_subsystem_devtype(ec->udev_monitor,
2264                                                         "drm", NULL);
2265         ec->udev_drm_source =
2266                 wl_event_loop_add_fd(loop,
2267                                      udev_monitor_get_fd(ec->udev_monitor),
2268                                      WL_EVENT_READABLE, udev_drm_event, ec);
2269
2270         if (udev_monitor_enable_receiving(ec->udev_monitor) < 0) {
2271                 weston_log("failed to enable udev-monitor receiving\n");
2272                 goto err_udev_monitor;
2273         }
2274
2275         udev_device_unref(drm_device);
2276         udev_enumerate_unref(e);
2277
2278         return &ec->base;
2279
2280 err_udev_monitor:
2281         wl_event_source_remove(ec->udev_drm_source);
2282         udev_monitor_unref(ec->udev_monitor);
2283 err_drm_source:
2284         wl_event_source_remove(ec->drm_source);
2285         wl_list_for_each_safe(weston_seat, next, &ec->base.seat_list, link)
2286                 evdev_input_destroy(weston_seat);
2287 err_egl:
2288         eglMakeCurrent(ec->base.egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
2289                        EGL_NO_CONTEXT);
2290         eglTerminate(ec->base.egl_display);
2291         eglReleaseThread();
2292         gbm_device_destroy(ec->gbm);
2293 err_sprite:
2294         destroy_sprites(ec);
2295 err_udev_dev:
2296         udev_device_unref(drm_device);
2297 err_udev_enum:
2298         udev_enumerate_unref(e);
2299         tty_destroy(ec->tty);
2300 err_udev:
2301         udev_unref(ec->udev);
2302 err_compositor:
2303         weston_compositor_shutdown(&ec->base);
2304 err_base:
2305         free(ec);
2306         return NULL;
2307 }
2308
2309 static int
2310 set_sync_flags(drmModeModeInfo *mode, char *hsync, char *vsync)
2311 {
2312         mode->flags = 0;
2313
2314         if (strcmp(hsync, "+hsync") == 0)
2315                 mode->flags |= DRM_MODE_FLAG_PHSYNC;
2316         else if (strcmp(hsync, "-hsync") == 0)
2317                 mode->flags |= DRM_MODE_FLAG_NHSYNC;
2318         else
2319                 return -1;
2320
2321         if (strcmp(vsync, "+vsync") == 0)
2322                 mode->flags |= DRM_MODE_FLAG_PVSYNC;
2323         else if (strcmp(vsync, "-vsync") == 0)
2324                 mode->flags |= DRM_MODE_FLAG_NVSYNC;
2325         else
2326                 return -1;
2327
2328         return 0;
2329 }
2330
2331 static int
2332 check_for_modeline(struct drm_configured_output *output)
2333 {
2334         drmModeModeInfo mode;
2335         char hsync[16];
2336         char vsync[16];
2337         char mode_name[16];
2338         float fclock;
2339
2340         mode.type = DRM_MODE_TYPE_USERDEF;
2341         mode.hskew = 0;
2342         mode.vscan = 0;
2343         mode.vrefresh = 0;
2344
2345         if (sscanf(output_mode, "%f %hd %hd %hd %hd %hd %hd %hd %hd %s %s",
2346                                                 &fclock, &mode.hdisplay,
2347                                                 &mode.hsync_start,
2348                                                 &mode.hsync_end, &mode.htotal,
2349                                                 &mode.vdisplay,
2350                                                 &mode.vsync_start,
2351                                                 &mode.vsync_end, &mode.vtotal,
2352                                                 hsync, vsync) == 11) {
2353                 if (set_sync_flags(&mode, hsync, vsync))
2354                         return -1;
2355
2356                 sprintf(mode_name, "%dx%d", mode.hdisplay, mode.vdisplay);
2357                 strcpy(mode.name, mode_name);
2358
2359                 mode.clock = fclock * 1000;
2360         } else
2361                 return -1;
2362
2363         output->crtc_mode = mode;
2364
2365         return 0;
2366 }
2367
2368 static void
2369 drm_output_set_transform(struct drm_configured_output *output)
2370 {
2371         if (!output_transform) {
2372                 output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
2373                 return;
2374         }
2375
2376         if (!strcmp(output_transform, "normal"))
2377                 output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
2378         else if (!strcmp(output_transform, "90"))
2379                 output->transform = WL_OUTPUT_TRANSFORM_90;
2380         else if (!strcmp(output_transform, "180"))
2381                 output->transform = WL_OUTPUT_TRANSFORM_180;
2382         else if (!strcmp(output_transform, "270"))
2383                 output->transform = WL_OUTPUT_TRANSFORM_270;
2384         else if (!strcmp(output_transform, "flipped"))
2385                 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED;
2386         else if (!strcmp(output_transform, "flipped-90"))
2387                 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;
2388         else if (!strcmp(output_transform, "flipped-180"))
2389                 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
2390         else if (!strcmp(output_transform, "flipped-270"))
2391                 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270;
2392         else {
2393                 weston_log("Invalid transform \"%s\" for output %s\n",
2394                                                 output_transform, output_name);
2395                 output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
2396         }
2397
2398         free(output_transform);
2399         output_transform = NULL;
2400 }
2401
2402 static void
2403 output_section_done(void *data)
2404 {
2405         struct drm_configured_output *output;
2406
2407         output = malloc(sizeof *output);
2408
2409         if (!output || !output_name || (output_name[0] == 'X') ||
2410                                         (!output_mode && !output_transform)) {
2411                 free(output_name);
2412                 free(output_mode);
2413                 free(output_transform);
2414                 free(output);
2415                 output_name = NULL;
2416                 output_mode = NULL;
2417                 output_transform = NULL;
2418                 return;
2419         }
2420
2421         output->config = OUTPUT_CONFIG_INVALID;
2422         output->name = output_name;
2423         output->mode = output_mode;
2424
2425         if (output_mode) {
2426                 if (strcmp(output_mode, "off") == 0)
2427                         output->config = OUTPUT_CONFIG_OFF;
2428                 else if (strcmp(output_mode, "preferred") == 0)
2429                         output->config = OUTPUT_CONFIG_PREFERRED;
2430                 else if (strcmp(output_mode, "current") == 0)
2431                         output->config = OUTPUT_CONFIG_CURRENT;
2432                 else if (sscanf(output_mode, "%dx%d",
2433                                         &output->width, &output->height) == 2)
2434                         output->config = OUTPUT_CONFIG_MODE;
2435                 else if (check_for_modeline(output) == 0)
2436                         output->config = OUTPUT_CONFIG_MODELINE;
2437
2438                 if (output->config == OUTPUT_CONFIG_INVALID)
2439                         weston_log("Invalid mode \"%s\" for output %s\n",
2440                                                         output_mode, output_name);
2441                 output_mode = NULL;
2442         }
2443
2444         drm_output_set_transform(output);
2445
2446         wl_list_insert(&configured_output_list, &output->link);
2447
2448         if (output_transform)
2449                 free(output_transform);
2450         output_transform = NULL;
2451 }
2452
2453 WL_EXPORT struct weston_compositor *
2454 backend_init(struct wl_display *display, int argc, char *argv[],
2455              const char *config_file)
2456 {
2457         int connector = 0, tty = 0;
2458         const char *seat = default_seat;
2459
2460         const struct weston_option drm_options[] = {
2461                 { WESTON_OPTION_INTEGER, "connector", 0, &connector },
2462                 { WESTON_OPTION_STRING, "seat", 0, &seat },
2463                 { WESTON_OPTION_INTEGER, "tty", 0, &tty },
2464                 { WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode },
2465         };
2466
2467         parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv);
2468
2469         wl_list_init(&configured_output_list);
2470
2471         const struct config_key drm_config_keys[] = {
2472                 { "name", CONFIG_KEY_STRING, &output_name },
2473                 { "mode", CONFIG_KEY_STRING, &output_mode },
2474                 { "transform", CONFIG_KEY_STRING, &output_transform },
2475         };
2476
2477         const struct config_section config_section[] = {
2478                 { "output", drm_config_keys,
2479                 ARRAY_LENGTH(drm_config_keys), output_section_done },
2480         };
2481
2482         parse_config_file(config_file, config_section,
2483                                 ARRAY_LENGTH(config_section), NULL);
2484
2485         return drm_compositor_create(display, connector, seat, tty, argc, argv,
2486                                      config_file);
2487 }