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