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