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