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