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