compositor-drm: Don't page flip before a mode is set
[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, *box);
862         s->dest_x = tbox.x1;
863         s->dest_y = tbox.y1;
864         s->dest_w = tbox.x2 - tbox.x1;
865         s->dest_h = tbox.y2 - tbox.y1;
866         pixman_region32_fini(&dest_rect);
867
868         pixman_region32_init(&src_rect);
869         pixman_region32_intersect(&src_rect, &es->transform.boundingbox,
870                                   &output_base->region);
871         box = pixman_region32_extents(&src_rect);
872
873         weston_surface_from_global_fixed(es,
874                                          wl_fixed_from_int(box->x1),
875                                          wl_fixed_from_int(box->y1),
876                                          &sx1, &sy1);
877         weston_surface_from_global_fixed(es,
878                                          wl_fixed_from_int(box->x2),
879                                          wl_fixed_from_int(box->y2),
880                                          &sx2, &sy2);
881
882         if (sx1 < 0)
883                 sx1 = 0;
884         if (sy1 < 0)
885                 sy1 = 0;
886         if (sx2 > wl_fixed_from_int(es->geometry.width))
887                 sx2 = wl_fixed_from_int(es->geometry.width);
888         if (sy2 > wl_fixed_from_int(es->geometry.height))
889                 sy2 = wl_fixed_from_int(es->geometry.height);
890
891         tbox.x1 = sx1;
892         tbox.y1 = sy1;
893         tbox.x2 = sx2;
894         tbox.y2 = sy2;
895
896         tbox = weston_transformed_rect(wl_fixed_from_int(es->geometry.width),
897                                        wl_fixed_from_int(es->geometry.height),
898                                        es->buffer_transform, tbox);
899
900         s->src_x = tbox.x1 << 8;
901         s->src_y = tbox.y1 << 8;
902         s->src_w = (tbox.x2 - tbox.x1) << 8;
903         s->src_h = (tbox.y2 - tbox.y1) << 8;
904         pixman_region32_fini(&src_rect);
905
906         return &s->plane;
907 }
908
909 static struct weston_plane *
910 drm_output_prepare_cursor_surface(struct weston_output *output_base,
911                                   struct weston_surface *es)
912 {
913         struct drm_compositor *c =
914                 (struct drm_compositor *) output_base->compositor;
915         struct drm_output *output = (struct drm_output *) output_base;
916
917         if (c->gbm == NULL)
918                 return NULL;
919         if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
920                 return NULL;
921         if (output->cursor_surface)
922                 return NULL;
923         if (es->output_mask != (1u << output_base->id))
924                 return NULL;
925         if (c->cursors_are_broken)
926                 return NULL;
927         if (es->buffer_ref.buffer == NULL ||
928             !wl_buffer_is_shm(es->buffer_ref.buffer) ||
929             es->geometry.width > 64 || es->geometry.height > 64)
930                 return NULL;
931
932         output->cursor_surface = es;
933
934         return &output->cursor_plane;
935 }
936
937 static void
938 drm_output_set_cursor(struct drm_output *output)
939 {
940         struct weston_surface *es = output->cursor_surface;
941         struct drm_compositor *c =
942                 (struct drm_compositor *) output->base.compositor;
943         EGLint handle, stride;
944         struct gbm_bo *bo;
945         uint32_t buf[64 * 64];
946         unsigned char *s;
947         int i, x, y;
948
949         output->cursor_surface = NULL;
950         if (es == NULL) {
951                 drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
952                 return;
953         }
954
955         if (es->buffer_ref.buffer &&
956             pixman_region32_not_empty(&output->cursor_plane.damage)) {
957                 pixman_region32_fini(&output->cursor_plane.damage);
958                 pixman_region32_init(&output->cursor_plane.damage);
959                 output->current_cursor ^= 1;
960                 bo = output->cursor_bo[output->current_cursor];
961                 memset(buf, 0, sizeof buf);
962                 stride = wl_shm_buffer_get_stride(es->buffer_ref.buffer);
963                 s = wl_shm_buffer_get_data(es->buffer_ref.buffer);
964                 for (i = 0; i < es->geometry.height; i++)
965                         memcpy(buf + i * 64, s + i * stride,
966                                es->geometry.width * 4);
967
968                 if (gbm_bo_write(bo, buf, sizeof buf) < 0)
969                         weston_log("failed update cursor: %m\n");
970
971                 handle = gbm_bo_get_handle(bo).s32;
972                 if (drmModeSetCursor(c->drm.fd,
973                                      output->crtc_id, handle, 64, 64)) {
974                         weston_log("failed to set cursor: %m\n");
975                         c->cursors_are_broken = 1;
976                 }
977         }
978
979         x = es->geometry.x - output->base.x;
980         y = es->geometry.y - output->base.y;
981         if (output->cursor_plane.x != x || output->cursor_plane.y != y) {
982                 if (drmModeMoveCursor(c->drm.fd, output->crtc_id, x, y)) {
983                         weston_log("failed to move cursor: %m\n");
984                         c->cursors_are_broken = 1;
985                 }
986
987                 output->cursor_plane.x = x;
988                 output->cursor_plane.y = y;
989         }
990 }
991
992 static void
993 drm_assign_planes(struct weston_output *output)
994 {
995         struct drm_compositor *c =
996                 (struct drm_compositor *) output->compositor;
997         struct weston_surface *es, *next;
998         pixman_region32_t overlap, surface_overlap;
999         struct weston_plane *primary, *next_plane;
1000
1001         /*
1002          * Find a surface for each sprite in the output using some heuristics:
1003          * 1) size
1004          * 2) frequency of update
1005          * 3) opacity (though some hw might support alpha blending)
1006          * 4) clipping (this can be fixed with color keys)
1007          *
1008          * The idea is to save on blitting since this should save power.
1009          * If we can get a large video surface on the sprite for example,
1010          * the main display surface may not need to update at all, and
1011          * the client buffer can be used directly for the sprite surface
1012          * as we do for flipping full screen surfaces.
1013          */
1014         pixman_region32_init(&overlap);
1015         primary = &c->base.primary_plane;
1016         wl_list_for_each_safe(es, next, &c->base.surface_list, link) {
1017                 /* test whether this buffer can ever go into a plane:
1018                  * non-shm, or small enough to be a cursor
1019                  */
1020                 if ((es->buffer_ref.buffer &&
1021                      !wl_buffer_is_shm(es->buffer_ref.buffer)) ||
1022                     (es->geometry.width <= 64 && es->geometry.height <= 64))
1023                         es->keep_buffer = 1;
1024                 else
1025                         es->keep_buffer = 0;
1026
1027                 pixman_region32_init(&surface_overlap);
1028                 pixman_region32_intersect(&surface_overlap, &overlap,
1029                                           &es->transform.boundingbox);
1030
1031                 next_plane = NULL;
1032                 if (pixman_region32_not_empty(&surface_overlap))
1033                         next_plane = primary;
1034                 if (next_plane == NULL)
1035                         next_plane = drm_output_prepare_cursor_surface(output, es);
1036                 if (next_plane == NULL)
1037                         next_plane = drm_output_prepare_scanout_surface(output, es);
1038                 if (next_plane == NULL)
1039                         next_plane = drm_output_prepare_overlay_surface(output, es);
1040                 if (next_plane == NULL)
1041                         next_plane = primary;
1042                 weston_surface_move_to_plane(es, next_plane);
1043                 if (next_plane == primary)
1044                         pixman_region32_union(&overlap, &overlap,
1045                                               &es->transform.boundingbox);
1046
1047                 pixman_region32_fini(&surface_overlap);
1048         }
1049         pixman_region32_fini(&overlap);
1050 }
1051
1052 static void
1053 drm_output_fini_pixman(struct drm_output *output);
1054
1055 static void
1056 drm_output_destroy(struct weston_output *output_base)
1057 {
1058         struct drm_output *output = (struct drm_output *) output_base;
1059         struct drm_compositor *c =
1060                 (struct drm_compositor *) output->base.compositor;
1061         drmModeCrtcPtr origcrtc = output->original_crtc;
1062
1063         if (output->backlight)
1064                 backlight_destroy(output->backlight);
1065
1066         /* Turn off hardware cursor */
1067         drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
1068
1069         /* Restore original CRTC state */
1070         drmModeSetCrtc(c->drm.fd, origcrtc->crtc_id, origcrtc->buffer_id,
1071                        origcrtc->x, origcrtc->y,
1072                        &output->connector_id, 1, &origcrtc->mode);
1073         drmModeFreeCrtc(origcrtc);
1074
1075         c->crtc_allocator &= ~(1 << output->crtc_id);
1076         c->connector_allocator &= ~(1 << output->connector_id);
1077
1078         if (c->use_pixman) {
1079                 drm_output_fini_pixman(output);
1080         } else {
1081                 gl_renderer_output_destroy(output_base);
1082                 gbm_surface_destroy(output->surface);
1083         }
1084
1085         weston_plane_release(&output->fb_plane);
1086         weston_plane_release(&output->cursor_plane);
1087
1088         weston_output_destroy(&output->base);
1089         wl_list_remove(&output->base.link);
1090
1091         free(output);
1092 }
1093
1094 static struct drm_mode *
1095 choose_mode (struct drm_output *output, struct weston_mode *target_mode)
1096 {
1097         struct drm_mode *tmp_mode = NULL, *mode;
1098
1099         if (output->base.current->width == target_mode->width && 
1100             output->base.current->height == target_mode->height &&
1101             (output->base.current->refresh == target_mode->refresh ||
1102              target_mode->refresh == 0))
1103                 return (struct drm_mode *)output->base.current;
1104
1105         wl_list_for_each(mode, &output->base.mode_list, base.link) {
1106                 if (mode->mode_info.hdisplay == target_mode->width &&
1107                     mode->mode_info.vdisplay == target_mode->height) {
1108                         if (mode->mode_info.vrefresh == target_mode->refresh || 
1109                             target_mode->refresh == 0) {
1110                                 return mode;
1111                         } else if (!tmp_mode) 
1112                                 tmp_mode = mode;
1113                 }
1114         }
1115
1116         return tmp_mode;
1117 }
1118
1119 static int
1120 drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec);
1121 static int
1122 drm_output_init_pixman(struct drm_output *output, struct drm_compositor *c);
1123
1124 static int
1125 drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mode)
1126 {
1127         struct drm_output *output;
1128         struct drm_mode *drm_mode;
1129         struct drm_compositor *ec;
1130
1131         if (output_base == NULL) {
1132                 weston_log("output is NULL.\n");
1133                 return -1;
1134         }
1135
1136         if (mode == NULL) {
1137                 weston_log("mode is NULL.\n");
1138                 return -1;
1139         }
1140
1141         ec = (struct drm_compositor *)output_base->compositor;
1142         output = (struct drm_output *)output_base;
1143         drm_mode  = choose_mode (output, mode);
1144
1145         if (!drm_mode) {
1146                 weston_log("%s, invalid resolution:%dx%d\n", __func__, mode->width, mode->height);
1147                 return -1;
1148         }
1149
1150         if (&drm_mode->base == output->base.current)
1151                 return 0;
1152
1153         output->base.current->flags = 0;
1154
1155         output->base.current = &drm_mode->base;
1156         output->base.current->flags =
1157                 WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
1158
1159         /* reset rendering stuff. */
1160         drm_output_release_fb(output, output->current);
1161         drm_output_release_fb(output, output->next);
1162         output->current = output->next = NULL;
1163
1164         if (ec->use_pixman) {
1165                 drm_output_fini_pixman(output);
1166                 if (drm_output_init_pixman(output, ec) < 0) {
1167                         weston_log("failed to init output pixman state with "
1168                                    "new mode\n");
1169                         return -1;
1170                 }
1171         } else {
1172                 gl_renderer_output_destroy(&output->base);
1173                 gbm_surface_destroy(output->surface);
1174
1175                 if (drm_output_init_egl(output, ec) < 0) {
1176                         weston_log("failed to init output egl state with "
1177                                    "new mode");
1178                         return -1;
1179                 }
1180         }
1181
1182         return 0;
1183 }
1184
1185 static int
1186 on_drm_input(int fd, uint32_t mask, void *data)
1187 {
1188         drmEventContext evctx;
1189
1190         memset(&evctx, 0, sizeof evctx);
1191         evctx.version = DRM_EVENT_CONTEXT_VERSION;
1192         evctx.page_flip_handler = page_flip_handler;
1193         evctx.vblank_handler = vblank_handler;
1194         drmHandleEvent(fd, &evctx);
1195
1196         return 1;
1197 }
1198
1199 static int
1200 init_drm(struct drm_compositor *ec, struct udev_device *device)
1201 {
1202         const char *filename, *sysnum;
1203         uint64_t cap;
1204         int fd, ret;
1205
1206         sysnum = udev_device_get_sysnum(device);
1207         if (sysnum)
1208                 ec->drm.id = atoi(sysnum);
1209         if (!sysnum || ec->drm.id < 0) {
1210                 weston_log("cannot get device sysnum\n");
1211                 return -1;
1212         }
1213
1214         filename = udev_device_get_devnode(device);
1215         fd = open(filename, O_RDWR | O_CLOEXEC);
1216         if (fd < 0) {
1217                 /* Probably permissions error */
1218                 weston_log("couldn't open %s, skipping\n",
1219                         udev_device_get_devnode(device));
1220                 return -1;
1221         }
1222
1223         weston_log("using %s\n", filename);
1224
1225         ec->drm.fd = fd;
1226
1227         ret = drmGetCap(fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap);
1228         if (ret == 0 && cap == 1)
1229                 ec->clock = CLOCK_MONOTONIC;
1230         else
1231                 ec->clock = CLOCK_REALTIME;
1232
1233         return 0;
1234 }
1235
1236 static int
1237 init_egl(struct drm_compositor *ec)
1238 {
1239         ec->gbm = gbm_create_device(ec->drm.fd);
1240
1241         if (!ec->gbm)
1242                 return -1;
1243
1244         if (gl_renderer_create(&ec->base, ec->gbm, gl_renderer_opaque_attribs,
1245                         NULL) < 0) {
1246                 gbm_device_destroy(ec->gbm);
1247                 return -1;
1248         }
1249
1250         return 0;
1251 }
1252
1253 static int
1254 init_pixman(struct drm_compositor *ec)
1255 {
1256         return pixman_renderer_init(&ec->base);
1257 }
1258
1259 static struct drm_mode *
1260 drm_output_add_mode(struct drm_output *output, drmModeModeInfo *info)
1261 {
1262         struct drm_mode *mode;
1263         uint64_t refresh;
1264
1265         mode = malloc(sizeof *mode);
1266         if (mode == NULL)
1267                 return NULL;
1268
1269         mode->base.flags = 0;
1270         mode->base.width = info->hdisplay;
1271         mode->base.height = info->vdisplay;
1272
1273         /* Calculate higher precision (mHz) refresh rate */
1274         refresh = (info->clock * 1000000LL / info->htotal +
1275                    info->vtotal / 2) / info->vtotal;
1276
1277         if (info->flags & DRM_MODE_FLAG_INTERLACE)
1278                 refresh *= 2;
1279         if (info->flags & DRM_MODE_FLAG_DBLSCAN)
1280                 refresh /= 2;
1281         if (info->vscan > 1)
1282             refresh /= info->vscan;
1283
1284         mode->base.refresh = refresh;
1285         mode->mode_info = *info;
1286
1287         if (info->type & DRM_MODE_TYPE_PREFERRED)
1288                 mode->base.flags |= WL_OUTPUT_MODE_PREFERRED;
1289
1290         wl_list_insert(output->base.mode_list.prev, &mode->base.link);
1291
1292         return mode;
1293 }
1294
1295 static int
1296 drm_subpixel_to_wayland(int drm_value)
1297 {
1298         switch (drm_value) {
1299         default:
1300         case DRM_MODE_SUBPIXEL_UNKNOWN:
1301                 return WL_OUTPUT_SUBPIXEL_UNKNOWN;
1302         case DRM_MODE_SUBPIXEL_NONE:
1303                 return WL_OUTPUT_SUBPIXEL_NONE;
1304         case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
1305                 return WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
1306         case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
1307                 return WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR;
1308         case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
1309                 return WL_OUTPUT_SUBPIXEL_VERTICAL_RGB;
1310         case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
1311                 return WL_OUTPUT_SUBPIXEL_VERTICAL_BGR;
1312         }
1313 }
1314
1315 /* returns a value between 0-255 range, where higher is brighter */
1316 static uint32_t
1317 drm_get_backlight(struct drm_output *output)
1318 {
1319         long brightness, max_brightness, norm;
1320
1321         brightness = backlight_get_brightness(output->backlight);
1322         max_brightness = backlight_get_max_brightness(output->backlight);
1323
1324         /* convert it on a scale of 0 to 255 */
1325         norm = (brightness * 255)/(max_brightness);
1326
1327         return (uint32_t) norm;
1328 }
1329
1330 /* values accepted are between 0-255 range */
1331 static void
1332 drm_set_backlight(struct weston_output *output_base, uint32_t value)
1333 {
1334         struct drm_output *output = (struct drm_output *) output_base;
1335         long max_brightness, new_brightness;
1336
1337         if (!output->backlight)
1338                 return;
1339
1340         if (value > 255)
1341                 return;
1342
1343         max_brightness = backlight_get_max_brightness(output->backlight);
1344
1345         /* get denormalized value */
1346         new_brightness = (value * max_brightness) / 255;
1347
1348         backlight_set_brightness(output->backlight, new_brightness);
1349 }
1350
1351 static drmModePropertyPtr
1352 drm_get_prop(int fd, drmModeConnectorPtr connector, const char *name)
1353 {
1354         drmModePropertyPtr props;
1355         int i;
1356
1357         for (i = 0; i < connector->count_props; i++) {
1358                 props = drmModeGetProperty(fd, connector->props[i]);
1359                 if (!props)
1360                         continue;
1361
1362                 if (!strcmp(props->name, name))
1363                         return props;
1364
1365                 drmModeFreeProperty(props);
1366         }
1367
1368         return NULL;
1369 }
1370
1371 static void
1372 drm_set_dpms(struct weston_output *output_base, enum dpms_enum level)
1373 {
1374         struct drm_output *output = (struct drm_output *) output_base;
1375         struct weston_compositor *ec = output_base->compositor;
1376         struct drm_compositor *c = (struct drm_compositor *) ec;
1377         drmModeConnectorPtr connector;
1378         drmModePropertyPtr prop;
1379
1380         connector = drmModeGetConnector(c->drm.fd, output->connector_id);
1381         if (!connector)
1382                 return;
1383
1384         prop = drm_get_prop(c->drm.fd, connector, "DPMS");
1385         if (!prop) {
1386                 drmModeFreeConnector(connector);
1387                 return;
1388         }
1389
1390         drmModeConnectorSetProperty(c->drm.fd, connector->connector_id,
1391                                     prop->prop_id, level);
1392         drmModeFreeProperty(prop);
1393         drmModeFreeConnector(connector);
1394 }
1395
1396 static const char *connector_type_names[] = {
1397         "None",
1398         "VGA",
1399         "DVI",
1400         "DVI",
1401         "DVI",
1402         "Composite",
1403         "TV",
1404         "LVDS",
1405         "CTV",
1406         "DIN",
1407         "DP",
1408         "HDMI",
1409         "HDMI",
1410         "TV",
1411         "eDP",
1412 };
1413
1414 static int
1415 find_crtc_for_connector(struct drm_compositor *ec,
1416                         drmModeRes *resources, drmModeConnector *connector)
1417 {
1418         drmModeEncoder *encoder;
1419         uint32_t possible_crtcs;
1420         int i, j;
1421
1422         for (j = 0; j < connector->count_encoders; j++) {
1423                 encoder = drmModeGetEncoder(ec->drm.fd, connector->encoders[j]);
1424                 if (encoder == NULL) {
1425                         weston_log("Failed to get encoder.\n");
1426                         return -1;
1427                 }
1428                 possible_crtcs = encoder->possible_crtcs;
1429                 drmModeFreeEncoder(encoder);
1430
1431                 for (i = 0; i < resources->count_crtcs; i++) {
1432                         if (possible_crtcs & (1 << i) &&
1433                             !(ec->crtc_allocator & (1 << resources->crtcs[i])))
1434                                 return i;
1435                 }
1436         }
1437
1438         return -1;
1439 }
1440
1441 /* Init output state that depends on gl or gbm */
1442 static int
1443 drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec)
1444 {
1445         int i, flags;
1446
1447         output->surface = gbm_surface_create(ec->gbm,
1448                                              output->base.current->width,
1449                                              output->base.current->height,
1450                                              GBM_FORMAT_XRGB8888,
1451                                              GBM_BO_USE_SCANOUT |
1452                                              GBM_BO_USE_RENDERING);
1453         if (!output->surface) {
1454                 weston_log("failed to create gbm surface\n");
1455                 return -1;
1456         }
1457
1458         if (gl_renderer_output_create(&output->base, output->surface) < 0) {
1459                 weston_log("failed to create gl renderer output state\n");
1460                 gbm_surface_destroy(output->surface);
1461                 return -1;
1462         }
1463
1464         flags = GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE;
1465
1466         for (i = 0; i < 2; i++) {
1467                 if (output->cursor_bo[i])
1468                         continue;
1469
1470                 output->cursor_bo[i] =
1471                         gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
1472                                       flags);
1473         }
1474
1475         if (output->cursor_bo[0] == NULL || output->cursor_bo[1] == NULL) {
1476                 weston_log("cursor buffers unavailable, using gl cursors\n");
1477                 ec->cursors_are_broken = 1;
1478         }
1479
1480         return 0;
1481 }
1482
1483 static int
1484 drm_output_init_pixman(struct drm_output *output, struct drm_compositor *c)
1485 {
1486         int w = output->base.current->width;
1487         int h = output->base.current->height;
1488         unsigned int i;
1489
1490         /* FIXME error checking */
1491
1492         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
1493                 output->dumb[i] = drm_fb_create_dumb(c, w, h);
1494                 if (!output->dumb[i])
1495                         goto err;
1496
1497                 output->image[i] =
1498                         pixman_image_create_bits(PIXMAN_x8r8g8b8, w, h,
1499                                                  output->dumb[i]->map,
1500                                                  output->dumb[i]->stride);
1501                 if (!output->image[i])
1502                         goto err;
1503         }
1504
1505         if (pixman_renderer_output_create(&output->base) < 0)
1506                 goto err;
1507
1508         pixman_region32_init_rect(&output->previous_damage,
1509                                   output->base.x, output->base.y, w, h);
1510
1511         return 0;
1512
1513 err:
1514         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
1515                 if (output->dumb[i])
1516                         drm_fb_destroy_dumb(output->dumb[i]);
1517                 if (output->image[i])
1518                         pixman_image_unref(output->image[i]);
1519
1520                 output->dumb[i] = NULL;
1521                 output->image[i] = NULL;
1522         }
1523
1524         return -1;
1525 }
1526
1527 static void
1528 drm_output_fini_pixman(struct drm_output *output)
1529 {
1530         unsigned int i;
1531
1532         pixman_renderer_output_destroy(&output->base);
1533         pixman_region32_fini(&output->previous_damage);
1534
1535         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
1536                 drm_fb_destroy_dumb(output->dumb[i]);
1537                 pixman_image_unref(output->image[i]);
1538                 output->dumb[i] = NULL;
1539                 output->image[i] = NULL;
1540         }
1541 }
1542
1543 static void
1544 edid_parse_string(const uint8_t *data, char text[])
1545 {
1546         int i;
1547         int replaced = 0;
1548
1549         /* this is always 12 bytes, but we can't guarantee it's null
1550          * terminated or not junk. */
1551         strncpy(text, (const char *) data, 12);
1552
1553         /* remove insane chars */
1554         for (i = 0; text[i] != '\0'; i++) {
1555                 if (text[i] == '\n' ||
1556                     text[i] == '\r') {
1557                         text[i] = '\0';
1558                         break;
1559                 }
1560         }
1561
1562         /* ensure string is printable */
1563         for (i = 0; text[i] != '\0'; i++) {
1564                 if (!isprint(text[i])) {
1565                         text[i] = '-';
1566                         replaced++;
1567                 }
1568         }
1569
1570         /* if the string is random junk, ignore the string */
1571         if (replaced > 4)
1572                 text[0] = '\0';
1573 }
1574
1575 #define EDID_DESCRIPTOR_ALPHANUMERIC_DATA_STRING        0xfe
1576 #define EDID_DESCRIPTOR_DISPLAY_PRODUCT_NAME            0xfc
1577 #define EDID_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER   0xff
1578 #define EDID_OFFSET_DATA_BLOCKS                         0x36
1579 #define EDID_OFFSET_LAST_BLOCK                          0x6c
1580 #define EDID_OFFSET_PNPID                               0x08
1581 #define EDID_OFFSET_SERIAL                              0x0c
1582
1583 static int
1584 edid_parse(struct drm_edid *edid, const uint8_t *data, size_t length)
1585 {
1586         int i;
1587         uint32_t serial_number;
1588
1589         /* check header */
1590         if (length < 128)
1591                 return -1;
1592         if (data[0] != 0x00 || data[1] != 0xff)
1593                 return -1;
1594
1595         /* decode the PNP ID from three 5 bit words packed into 2 bytes
1596          * /--08--\/--09--\
1597          * 7654321076543210
1598          * |\---/\---/\---/
1599          * R  C1   C2   C3 */
1600         edid->pnp_id[0] = 'A' + ((data[EDID_OFFSET_PNPID + 0] & 0x7c) / 4) - 1;
1601         edid->pnp_id[1] = 'A' + ((data[EDID_OFFSET_PNPID + 0] & 0x3) * 8) + ((data[EDID_OFFSET_PNPID + 1] & 0xe0) / 32) - 1;
1602         edid->pnp_id[2] = 'A' + (data[EDID_OFFSET_PNPID + 1] & 0x1f) - 1;
1603         edid->pnp_id[3] = '\0';
1604
1605         /* maybe there isn't a ASCII serial number descriptor, so use this instead */
1606         serial_number = (uint32_t) data[EDID_OFFSET_SERIAL + 0];
1607         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 1] * 0x100;
1608         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 2] * 0x10000;
1609         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 3] * 0x1000000;
1610         if (serial_number > 0)
1611                 sprintf(edid->serial_number, "%lu", (unsigned long) serial_number);
1612
1613         /* parse EDID data */
1614         for (i = EDID_OFFSET_DATA_BLOCKS;
1615              i <= EDID_OFFSET_LAST_BLOCK;
1616              i += 18) {
1617                 /* ignore pixel clock data */
1618                 if (data[i] != 0)
1619                         continue;
1620                 if (data[i+2] != 0)
1621                         continue;
1622
1623                 /* any useful blocks? */
1624                 if (data[i+3] == EDID_DESCRIPTOR_DISPLAY_PRODUCT_NAME) {
1625                         edid_parse_string(&data[i+5],
1626                                           edid->monitor_name);
1627                 } else if (data[i+3] == EDID_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER) {
1628                         edid_parse_string(&data[i+5],
1629                                           edid->serial_number);
1630                 } else if (data[i+3] == EDID_DESCRIPTOR_ALPHANUMERIC_DATA_STRING) {
1631                         edid_parse_string(&data[i+5],
1632                                           edid->eisa_id);
1633                 }
1634         }
1635         return 0;
1636 }
1637
1638 static void
1639 find_and_parse_output_edid(struct drm_compositor *ec,
1640                            struct drm_output *output,
1641                            drmModeConnector *connector)
1642 {
1643         drmModePropertyBlobPtr edid_blob = NULL;
1644         drmModePropertyPtr property;
1645         int i;
1646         int rc;
1647
1648         for (i = 0; i < connector->count_props && !edid_blob; i++) {
1649                 property = drmModeGetProperty(ec->drm.fd, connector->props[i]);
1650                 if (!property)
1651                         continue;
1652                 if ((property->flags & DRM_MODE_PROP_BLOB) &&
1653                     !strcmp(property->name, "EDID")) {
1654                         edid_blob = drmModeGetPropertyBlob(ec->drm.fd,
1655                                                            connector->prop_values[i]);
1656                 }
1657                 drmModeFreeProperty(property);
1658         }
1659         if (!edid_blob)
1660                 return;
1661
1662         rc = edid_parse(&output->edid,
1663                         edid_blob->data,
1664                         edid_blob->length);
1665         if (!rc) {
1666                 weston_log("EDID data '%s', '%s', '%s'\n",
1667                            output->edid.pnp_id,
1668                            output->edid.monitor_name,
1669                            output->edid.serial_number);
1670                 if (output->edid.pnp_id[0] != '\0')
1671                         output->base.make = output->edid.pnp_id;
1672                 if (output->edid.monitor_name[0] != '\0')
1673                         output->base.model = output->edid.monitor_name;
1674                 if (output->edid.serial_number[0] != '\0')
1675                         output->base.serial_number = output->edid.serial_number;
1676         }
1677         drmModeFreePropertyBlob(edid_blob);
1678 }
1679
1680 static int
1681 create_output_for_connector(struct drm_compositor *ec,
1682                             drmModeRes *resources,
1683                             drmModeConnector *connector,
1684                             int x, int y, struct udev_device *drm_device)
1685 {
1686         struct drm_output *output;
1687         struct drm_mode *drm_mode, *next, *preferred, *current, *configured;
1688         struct weston_mode *m;
1689         struct drm_configured_output *o = NULL, *temp;
1690         drmModeEncoder *encoder;
1691         drmModeModeInfo crtc_mode;
1692         drmModeCrtc *crtc;
1693         int i;
1694         char name[32];
1695         const char *type_name;
1696
1697         i = find_crtc_for_connector(ec, resources, connector);
1698         if (i < 0) {
1699                 weston_log("No usable crtc/encoder pair for connector.\n");
1700                 return -1;
1701         }
1702
1703         output = malloc(sizeof *output);
1704         if (output == NULL)
1705                 return -1;
1706
1707         memset(output, 0, sizeof *output);
1708         output->base.subpixel = drm_subpixel_to_wayland(connector->subpixel);
1709         output->base.make = "unknown";
1710         output->base.model = "unknown";
1711         output->base.serial_number = "unknown";
1712         wl_list_init(&output->base.mode_list);
1713
1714         if (connector->connector_type < ARRAY_LENGTH(connector_type_names))
1715                 type_name = connector_type_names[connector->connector_type];
1716         else
1717                 type_name = "UNKNOWN";
1718         snprintf(name, 32, "%s%d", type_name, connector->connector_type_id);
1719         output->base.name = strdup(name);
1720
1721         output->crtc_id = resources->crtcs[i];
1722         output->pipe = i;
1723         ec->crtc_allocator |= (1 << output->crtc_id);
1724         output->connector_id = connector->connector_id;
1725         ec->connector_allocator |= (1 << output->connector_id);
1726
1727         output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id);
1728
1729         /* Get the current mode on the crtc that's currently driving
1730          * this connector. */
1731         encoder = drmModeGetEncoder(ec->drm.fd, connector->encoder_id);
1732         memset(&crtc_mode, 0, sizeof crtc_mode);
1733         if (encoder != NULL) {
1734                 crtc = drmModeGetCrtc(ec->drm.fd, encoder->crtc_id);
1735                 drmModeFreeEncoder(encoder);
1736                 if (crtc == NULL)
1737                         goto err_free;
1738                 if (crtc->mode_valid)
1739                         crtc_mode = crtc->mode;
1740                 drmModeFreeCrtc(crtc);
1741         }
1742
1743         for (i = 0; i < connector->count_modes; i++) {
1744                 drm_mode = drm_output_add_mode(output, &connector->modes[i]);
1745                 if (!drm_mode)
1746                         goto err_free;
1747         }
1748
1749         preferred = NULL;
1750         current = NULL;
1751         configured = NULL;
1752
1753         wl_list_for_each(temp, &configured_output_list, link) {
1754                 if (strcmp(temp->name, output->base.name) == 0) {
1755                         if (temp->mode)
1756                                 weston_log("%s mode \"%s\" in config\n",
1757                                                         temp->name, temp->mode);
1758                         o = temp;
1759                         break;
1760                 }
1761         }
1762
1763         if (o && o->config == OUTPUT_CONFIG_OFF) {
1764                 weston_log("Disabling output %s\n", o->name);
1765
1766                 drmModeSetCrtc(ec->drm.fd, output->crtc_id,
1767                                                         0, 0, 0, 0, 0, NULL);
1768                 goto err_free;
1769         }
1770
1771         wl_list_for_each(drm_mode, &output->base.mode_list, base.link) {
1772                 if (o && o->config == OUTPUT_CONFIG_MODE &&
1773                         o->width == drm_mode->base.width &&
1774                         o->height == drm_mode->base.height)
1775                         configured = drm_mode;
1776                 if (!memcmp(&crtc_mode, &drm_mode->mode_info, sizeof crtc_mode))
1777                         current = drm_mode;
1778                 if (drm_mode->base.flags & WL_OUTPUT_MODE_PREFERRED)
1779                         preferred = drm_mode;
1780         }
1781
1782         if (o && o->config == OUTPUT_CONFIG_MODELINE) {
1783                 configured = drm_output_add_mode(output, &o->crtc_mode);
1784                 if (!configured)
1785                         goto err_free;
1786                 current = configured;
1787         }
1788
1789         if (current == NULL && crtc_mode.clock != 0) {
1790                 current = drm_output_add_mode(output, &crtc_mode);
1791                 if (!current)
1792                         goto err_free;
1793         }
1794
1795         if (o && o->config == OUTPUT_CONFIG_CURRENT)
1796                 configured = current;
1797
1798         if (option_current_mode && current)
1799                 output->base.current = &current->base;
1800         else if (configured)
1801                 output->base.current = &configured->base;
1802         else if (preferred)
1803                 output->base.current = &preferred->base;
1804         else if (current)
1805                 output->base.current = &current->base;
1806
1807         if (output->base.current == NULL) {
1808                 weston_log("no available modes for %s\n", output->base.name);
1809                 goto err_free;
1810         }
1811
1812         output->base.current->flags |= WL_OUTPUT_MODE_CURRENT;
1813
1814         weston_output_init(&output->base, &ec->base, x, y,
1815                            connector->mmWidth, connector->mmHeight,
1816                            o ? o->transform : WL_OUTPUT_TRANSFORM_NORMAL);
1817
1818         if (ec->use_pixman) {
1819                 if (drm_output_init_pixman(output, ec) < 0) {
1820                         weston_log("Failed to init output pixman state\n");
1821                         goto err_output;
1822                 }
1823         } else if (drm_output_init_egl(output, ec) < 0) {
1824                 weston_log("Failed to init output gl state\n");
1825                 goto err_output;
1826         }
1827
1828         output->backlight = backlight_init(drm_device,
1829                                            connector->connector_type);
1830         if (output->backlight) {
1831                 output->base.set_backlight = drm_set_backlight;
1832                 output->base.backlight_current = drm_get_backlight(output);
1833         }
1834
1835         wl_list_insert(ec->base.output_list.prev, &output->base.link);
1836
1837         find_and_parse_output_edid(ec, output, connector);
1838         if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
1839                 output->base.connection_internal = 1;
1840
1841         output->base.origin = output->base.current;
1842         output->base.start_repaint_loop = drm_output_start_repaint_loop;
1843         output->base.repaint = drm_output_repaint;
1844         output->base.destroy = drm_output_destroy;
1845         output->base.assign_planes = drm_assign_planes;
1846         output->base.set_dpms = drm_set_dpms;
1847         output->base.switch_mode = drm_output_switch_mode;
1848
1849         output->base.gamma_size = output->original_crtc->gamma_size;
1850         output->base.set_gamma = drm_output_set_gamma;
1851
1852         weston_plane_init(&output->cursor_plane, 0, 0);
1853         weston_plane_init(&output->fb_plane, 0, 0);
1854
1855         weston_compositor_stack_plane(&ec->base, &output->cursor_plane, NULL);
1856         weston_compositor_stack_plane(&ec->base, &output->fb_plane,
1857                                       &ec->base.primary_plane);
1858
1859         weston_log("Output %s, (connector %d, crtc %d)\n",
1860                    output->base.name, output->connector_id, output->crtc_id);
1861         wl_list_for_each(m, &output->base.mode_list, link)
1862                 weston_log_continue("  mode %dx%d@%.1f%s%s%s\n",
1863                                     m->width, m->height, m->refresh / 1000.0,
1864                                     m->flags & WL_OUTPUT_MODE_PREFERRED ?
1865                                     ", preferred" : "",
1866                                     m->flags & WL_OUTPUT_MODE_CURRENT ?
1867                                     ", current" : "",
1868                                     connector->count_modes == 0 ?
1869                                     ", built-in" : "");
1870
1871         return 0;
1872
1873 err_output:
1874         weston_output_destroy(&output->base);
1875 err_free:
1876         wl_list_for_each_safe(drm_mode, next, &output->base.mode_list,
1877                                                         base.link) {
1878                 wl_list_remove(&drm_mode->base.link);
1879                 free(drm_mode);
1880         }
1881
1882         drmModeFreeCrtc(output->original_crtc);
1883         ec->crtc_allocator &= ~(1 << output->crtc_id);
1884         ec->connector_allocator &= ~(1 << output->connector_id);
1885         free(output);
1886
1887         return -1;
1888 }
1889
1890 static void
1891 create_sprites(struct drm_compositor *ec)
1892 {
1893         struct drm_sprite *sprite;
1894         drmModePlaneRes *plane_res;
1895         drmModePlane *plane;
1896         uint32_t i;
1897
1898         plane_res = drmModeGetPlaneResources(ec->drm.fd);
1899         if (!plane_res) {
1900                 weston_log("failed to get plane resources: %s\n",
1901                         strerror(errno));
1902                 return;
1903         }
1904
1905         for (i = 0; i < plane_res->count_planes; i++) {
1906                 plane = drmModeGetPlane(ec->drm.fd, plane_res->planes[i]);
1907                 if (!plane)
1908                         continue;
1909
1910                 sprite = malloc(sizeof(*sprite) + ((sizeof(uint32_t)) *
1911                                                    plane->count_formats));
1912                 if (!sprite) {
1913                         weston_log("%s: out of memory\n",
1914                                 __func__);
1915                         free(plane);
1916                         continue;
1917                 }
1918
1919                 memset(sprite, 0, sizeof *sprite);
1920
1921                 sprite->possible_crtcs = plane->possible_crtcs;
1922                 sprite->plane_id = plane->plane_id;
1923                 sprite->current = NULL;
1924                 sprite->next = NULL;
1925                 sprite->compositor = ec;
1926                 sprite->count_formats = plane->count_formats;
1927                 memcpy(sprite->formats, plane->formats,
1928                        plane->count_formats * sizeof(plane->formats[0]));
1929                 drmModeFreePlane(plane);
1930                 weston_plane_init(&sprite->plane, 0, 0);
1931                 weston_compositor_stack_plane(&ec->base, &sprite->plane,
1932                                               &ec->base.primary_plane);
1933
1934                 wl_list_insert(&ec->sprite_list, &sprite->link);
1935         }
1936
1937         free(plane_res->planes);
1938         free(plane_res);
1939 }
1940
1941 static void
1942 destroy_sprites(struct drm_compositor *compositor)
1943 {
1944         struct drm_sprite *sprite, *next;
1945         struct drm_output *output;
1946
1947         output = container_of(compositor->base.output_list.next,
1948                               struct drm_output, base.link);
1949
1950         wl_list_for_each_safe(sprite, next, &compositor->sprite_list, link) {
1951                 drmModeSetPlane(compositor->drm.fd,
1952                                 sprite->plane_id,
1953                                 output->crtc_id, 0, 0,
1954                                 0, 0, 0, 0, 0, 0, 0, 0);
1955                 drm_output_release_fb(output, sprite->current);
1956                 drm_output_release_fb(output, sprite->next);
1957                 weston_plane_release(&sprite->plane);
1958                 free(sprite);
1959         }
1960 }
1961
1962 static int
1963 create_outputs(struct drm_compositor *ec, uint32_t option_connector,
1964                struct udev_device *drm_device)
1965 {
1966         drmModeConnector *connector;
1967         drmModeRes *resources;
1968         int i;
1969         int x = 0, y = 0;
1970
1971         resources = drmModeGetResources(ec->drm.fd);
1972         if (!resources) {
1973                 weston_log("drmModeGetResources failed\n");
1974                 return -1;
1975         }
1976
1977         ec->crtcs = calloc(resources->count_crtcs, sizeof(uint32_t));
1978         if (!ec->crtcs) {
1979                 drmModeFreeResources(resources);
1980                 return -1;
1981         }
1982
1983         ec->min_width  = resources->min_width;
1984         ec->max_width  = resources->max_width;
1985         ec->min_height = resources->min_height;
1986         ec->max_height = resources->max_height;
1987
1988         ec->num_crtcs = resources->count_crtcs;
1989         memcpy(ec->crtcs, resources->crtcs, sizeof(uint32_t) * ec->num_crtcs);
1990
1991         for (i = 0; i < resources->count_connectors; i++) {
1992                 connector = drmModeGetConnector(ec->drm.fd,
1993                                                 resources->connectors[i]);
1994                 if (connector == NULL)
1995                         continue;
1996
1997                 if (connector->connection == DRM_MODE_CONNECTED &&
1998                     (option_connector == 0 ||
1999                      connector->connector_id == option_connector)) {
2000                         if (create_output_for_connector(ec, resources,
2001                                                         connector, x, y,
2002                                                         drm_device) < 0) {
2003                                 drmModeFreeConnector(connector);
2004                                 continue;
2005                         }
2006
2007                         x += container_of(ec->base.output_list.prev,
2008                                           struct weston_output,
2009                                           link)->width;
2010                 }
2011
2012                 drmModeFreeConnector(connector);
2013         }
2014
2015         if (wl_list_empty(&ec->base.output_list)) {
2016                 weston_log("No currently active connector found.\n");
2017                 drmModeFreeResources(resources);
2018                 return -1;
2019         }
2020
2021         drmModeFreeResources(resources);
2022
2023         return 0;
2024 }
2025
2026 static void
2027 update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
2028 {
2029         drmModeConnector *connector;
2030         drmModeRes *resources;
2031         struct drm_output *output, *next;
2032         int x = 0, y = 0;
2033         int x_offset = 0, y_offset = 0;
2034         uint32_t connected = 0, disconnects = 0;
2035         int i;
2036
2037         resources = drmModeGetResources(ec->drm.fd);
2038         if (!resources) {
2039                 weston_log("drmModeGetResources failed\n");
2040                 return;
2041         }
2042
2043         /* collect new connects */
2044         for (i = 0; i < resources->count_connectors; i++) {
2045                 int connector_id = resources->connectors[i];
2046
2047                 connector = drmModeGetConnector(ec->drm.fd, connector_id);
2048                 if (connector == NULL)
2049                         continue;
2050
2051                 if (connector->connection != DRM_MODE_CONNECTED) {
2052                         drmModeFreeConnector(connector);
2053                         continue;
2054                 }
2055
2056                 connected |= (1 << connector_id);
2057
2058                 if (!(ec->connector_allocator & (1 << connector_id))) {
2059                         struct weston_output *last =
2060                                 container_of(ec->base.output_list.prev,
2061                                              struct weston_output, link);
2062
2063                         /* XXX: not yet needed, we die with 0 outputs */
2064                         if (!wl_list_empty(&ec->base.output_list))
2065                                 x = last->x + last->width;
2066                         else
2067                                 x = 0;
2068                         y = 0;
2069                         create_output_for_connector(ec, resources,
2070                                                     connector, x, y,
2071                                                     drm_device);
2072                         weston_log("connector %d connected\n", connector_id);
2073
2074                 }
2075                 drmModeFreeConnector(connector);
2076         }
2077         drmModeFreeResources(resources);
2078
2079         disconnects = ec->connector_allocator & ~connected;
2080         if (disconnects) {
2081                 wl_list_for_each_safe(output, next, &ec->base.output_list,
2082                                       base.link) {
2083                         if (x_offset != 0 || y_offset != 0) {
2084                                 weston_output_move(&output->base,
2085                                                  output->base.x - x_offset,
2086                                                  output->base.y - y_offset);
2087                         }
2088
2089                         if (disconnects & (1 << output->connector_id)) {
2090                                 disconnects &= ~(1 << output->connector_id);
2091                                 weston_log("connector %d disconnected\n",
2092                                        output->connector_id);
2093                                 x_offset += output->base.width;
2094                                 drm_output_destroy(&output->base);
2095                         }
2096                 }
2097         }
2098
2099         /* FIXME: handle zero outputs, without terminating */   
2100         if (ec->connector_allocator == 0)
2101                 wl_display_terminate(ec->base.wl_display);
2102 }
2103
2104 static int
2105 udev_event_is_hotplug(struct drm_compositor *ec, struct udev_device *device)
2106 {
2107         const char *sysnum;
2108         const char *val;
2109
2110         sysnum = udev_device_get_sysnum(device);
2111         if (!sysnum || atoi(sysnum) != ec->drm.id)
2112                 return 0;
2113
2114         val = udev_device_get_property_value(device, "HOTPLUG");
2115         if (!val)
2116                 return 0;
2117
2118         return strcmp(val, "1") == 0;
2119 }
2120
2121 static int
2122 udev_drm_event(int fd, uint32_t mask, void *data)
2123 {
2124         struct drm_compositor *ec = data;
2125         struct udev_device *event;
2126
2127         event = udev_monitor_receive_device(ec->udev_monitor);
2128
2129         if (udev_event_is_hotplug(ec, event))
2130                 update_outputs(ec, event);
2131
2132         udev_device_unref(event);
2133
2134         return 1;
2135 }
2136
2137 static void
2138 drm_restore(struct weston_compositor *ec)
2139 {
2140         struct drm_compositor *d = (struct drm_compositor *) ec;
2141
2142         if (weston_launcher_drm_set_master(&d->base, d->drm.fd, 0) < 0)
2143                 weston_log("failed to drop master: %m\n");
2144         tty_reset(d->tty);
2145 }
2146
2147 static void
2148 drm_free_configured_output(struct drm_configured_output *output)
2149 {
2150         free(output->name);
2151         free(output->mode);
2152         free(output);
2153 }
2154
2155 static void
2156 drm_destroy(struct weston_compositor *ec)
2157 {
2158         struct drm_compositor *d = (struct drm_compositor *) ec;
2159         struct udev_seat *seat, *next;
2160         struct drm_configured_output *o, *n;
2161
2162         wl_list_for_each_safe(seat, next, &ec->seat_list, base.link)
2163                 udev_seat_destroy(seat);
2164         wl_list_for_each_safe(o, n, &configured_output_list, link)
2165                 drm_free_configured_output(o);
2166
2167         wl_event_source_remove(d->udev_drm_source);
2168         wl_event_source_remove(d->drm_source);
2169
2170         destroy_sprites(d);
2171
2172         weston_compositor_shutdown(ec);
2173
2174         ec->renderer->destroy(ec);
2175
2176         if (d->gbm)
2177                 gbm_device_destroy(d->gbm);
2178
2179         if (weston_launcher_drm_set_master(&d->base, d->drm.fd, 0) < 0)
2180                 weston_log("failed to drop master: %m\n");
2181         tty_destroy(d->tty);
2182
2183         free(d);
2184 }
2185
2186 static void
2187 drm_compositor_set_modes(struct drm_compositor *compositor)
2188 {
2189         struct drm_output *output;
2190         struct drm_mode *drm_mode;
2191         int ret;
2192
2193         wl_list_for_each(output, &compositor->base.output_list, base.link) {
2194                 if (!output->current) {
2195                         /* If something that would cause the output to
2196                          * switch mode happened while in another vt, we
2197                          * might not have a current drm_fb. In that case,
2198                          * schedule a repaint and let drm_output_repaint
2199                          * handle setting the mode. */
2200                         weston_output_schedule_repaint(&output->base);
2201                         continue;
2202                 }
2203
2204                 drm_mode = (struct drm_mode *) output->base.current;
2205                 ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
2206                                      output->current->fb_id, 0, 0,
2207                                      &output->connector_id, 1,
2208                                      &drm_mode->mode_info);
2209                 if (ret < 0) {
2210                         weston_log(
2211                                 "failed to set mode %dx%d for output at %d,%d: %m\n",
2212                                 drm_mode->base.width, drm_mode->base.height, 
2213                                 output->base.x, output->base.y);
2214                 }
2215         }
2216 }
2217
2218 static void
2219 vt_func(struct weston_compositor *compositor, int event)
2220 {
2221         struct drm_compositor *ec = (struct drm_compositor *) compositor;
2222         struct udev_seat *seat;
2223         struct drm_sprite *sprite;
2224         struct drm_output *output;
2225
2226         switch (event) {
2227         case TTY_ENTER_VT:
2228                 weston_log("entering VT\n");
2229                 compositor->focus = 1;
2230                 if (weston_launcher_drm_set_master(&ec->base, ec->drm.fd, 1)) {
2231                         weston_log("failed to set master: %m\n");
2232                         wl_display_terminate(compositor->wl_display);
2233                 }
2234                 compositor->state = ec->prev_state;
2235                 drm_compositor_set_modes(ec);
2236                 weston_compositor_damage_all(compositor);
2237                 wl_list_for_each(seat, &compositor->seat_list, base.link)
2238                         udev_seat_enable(seat, ec->udev);
2239                 break;
2240         case TTY_LEAVE_VT:
2241                 weston_log("leaving VT\n");
2242                 wl_list_for_each(seat, &compositor->seat_list, base.link)
2243                         udev_seat_disable(seat);
2244
2245                 compositor->focus = 0;
2246                 ec->prev_state = compositor->state;
2247                 weston_compositor_offscreen(compositor);
2248
2249                 /* If we have a repaint scheduled (either from a
2250                  * pending pageflip or the idle handler), make sure we
2251                  * cancel that so we don't try to pageflip when we're
2252                  * vt switched away.  The OFFSCREEN state will prevent
2253                  * further attemps at repainting.  When we switch
2254                  * back, we schedule a repaint, which will process
2255                  * pending frame callbacks. */
2256
2257                 wl_list_for_each(output, &ec->base.output_list, base.link) {
2258                         output->base.repaint_needed = 0;
2259                         drmModeSetCursor(ec->drm.fd, output->crtc_id, 0, 0, 0);
2260                 }
2261
2262                 output = container_of(ec->base.output_list.next,
2263                                       struct drm_output, base.link);
2264
2265                 wl_list_for_each(sprite, &ec->sprite_list, link)
2266                         drmModeSetPlane(ec->drm.fd,
2267                                         sprite->plane_id,
2268                                         output->crtc_id, 0, 0,
2269                                         0, 0, 0, 0, 0, 0, 0, 0);
2270
2271                 if (weston_launcher_drm_set_master(&ec->base, ec->drm.fd, 0) < 0)
2272                         weston_log("failed to drop master: %m\n");
2273
2274                 break;
2275         };
2276 }
2277
2278 static void
2279 switch_vt_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
2280 {
2281         struct drm_compositor *ec = data;
2282
2283         tty_activate_vt(ec->tty, key - KEY_F1 + 1);
2284 }
2285
2286 /*
2287  * Find primary GPU
2288  * Some systems may have multiple DRM devices attached to a single seat. This
2289  * function loops over all devices and tries to find a PCI device with the
2290  * boot_vga sysfs attribute set to 1.
2291  * If no such device is found, the first DRM device reported by udev is used.
2292  */
2293 static struct udev_device*
2294 find_primary_gpu(struct drm_compositor *ec, const char *seat)
2295 {
2296         struct udev_enumerate *e;
2297         struct udev_list_entry *entry;
2298         const char *path, *device_seat, *id;
2299         struct udev_device *device, *drm_device, *pci;
2300
2301         e = udev_enumerate_new(ec->udev);
2302         udev_enumerate_add_match_subsystem(e, "drm");
2303         udev_enumerate_add_match_sysname(e, "card[0-9]*");
2304
2305         udev_enumerate_scan_devices(e);
2306         drm_device = NULL;
2307         udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
2308                 path = udev_list_entry_get_name(entry);
2309                 device = udev_device_new_from_syspath(ec->udev, path);
2310                 if (!device)
2311                         continue;
2312                 device_seat = udev_device_get_property_value(device, "ID_SEAT");
2313                 if (!device_seat)
2314                         device_seat = default_seat;
2315                 if (strcmp(device_seat, seat)) {
2316                         udev_device_unref(device);
2317                         continue;
2318                 }
2319
2320                 pci = udev_device_get_parent_with_subsystem_devtype(device,
2321                                                                 "pci", NULL);
2322                 if (pci) {
2323                         id = udev_device_get_sysattr_value(pci, "boot_vga");
2324                         if (id && !strcmp(id, "1")) {
2325                                 if (drm_device)
2326                                         udev_device_unref(drm_device);
2327                                 drm_device = device;
2328                                 break;
2329                         }
2330                 }
2331
2332                 if (!drm_device)
2333                         drm_device = device;
2334                 else
2335                         udev_device_unref(device);
2336         }
2337
2338         udev_enumerate_unref(e);
2339         return drm_device;
2340 }
2341
2342 static void
2343 planes_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
2344 {
2345         struct drm_compositor *c = data;
2346
2347         switch (key) {
2348         case KEY_C:
2349                 c->cursors_are_broken ^= 1;
2350                 break;
2351         case KEY_V:
2352                 c->sprites_are_broken ^= 1;
2353                 break;
2354         case KEY_O:
2355                 c->sprites_hidden ^= 1;
2356                 break;
2357         default:
2358                 break;
2359         }
2360 }
2361
2362 static struct weston_compositor *
2363 drm_compositor_create(struct wl_display *display,
2364                       int connector, const char *seat, int tty, int pixman,
2365                       int *argc, char *argv[], const char *config_file)
2366 {
2367         struct drm_compositor *ec;
2368         struct udev_device *drm_device;
2369         struct wl_event_loop *loop;
2370         struct udev_seat *udev_seat, *next;
2371         const char *path;
2372         uint32_t key;
2373
2374         weston_log("initializing drm backend\n");
2375
2376         ec = malloc(sizeof *ec);
2377         if (ec == NULL)
2378                 return NULL;
2379         memset(ec, 0, sizeof *ec);
2380
2381         /* KMS support for sprites is not complete yet, so disable the
2382          * functionality for now. */
2383         ec->sprites_are_broken = 1;
2384
2385         ec->use_pixman = pixman;
2386
2387         if (weston_compositor_init(&ec->base, display, argc, argv,
2388                                    config_file) < 0) {
2389                 weston_log("%s failed\n", __func__);
2390                 goto err_base;
2391         }
2392
2393         /* Check if we run drm-backend using weston-launch */
2394         if (ec->base.launcher_sock == -1 && geteuid() != 0) {
2395                 weston_log("fatal: drm backend should be run "
2396                            "using weston-launch binary or as root\n");
2397                 goto err_compositor;
2398         }
2399
2400         ec->udev = udev_new();
2401         if (ec->udev == NULL) {
2402                 weston_log("failed to initialize udev context\n");
2403                 goto err_compositor;
2404         }
2405
2406         ec->base.wl_display = display;
2407         ec->tty = tty_create(&ec->base, vt_func, tty);
2408         if (!ec->tty) {
2409                 weston_log("failed to initialize tty\n");
2410                 goto err_udev;
2411         }
2412
2413         drm_device = find_primary_gpu(ec, seat);
2414         if (drm_device == NULL) {
2415                 weston_log("no drm device found\n");
2416                 goto err_tty;
2417         }
2418         path = udev_device_get_syspath(drm_device);
2419
2420         if (init_drm(ec, drm_device) < 0) {
2421                 weston_log("failed to initialize kms\n");
2422                 goto err_udev_dev;
2423         }
2424
2425         if (ec->use_pixman) {
2426                 if (init_pixman(ec) < 0) {
2427                         weston_log("failed to initialize pixman renderer\n");
2428                         goto err_udev_dev;
2429                 }
2430         } else {
2431                 if (init_egl(ec) < 0) {
2432                         weston_log("failed to initialize egl\n");
2433                         goto err_udev_dev;
2434                 }
2435         }
2436
2437         ec->base.destroy = drm_destroy;
2438         ec->base.restore = drm_restore;
2439
2440         ec->base.focus = 1;
2441
2442         ec->prev_state = WESTON_COMPOSITOR_ACTIVE;
2443
2444         for (key = KEY_F1; key < KEY_F9; key++)
2445                 weston_compositor_add_key_binding(&ec->base, key,
2446                                                   MODIFIER_CTRL | MODIFIER_ALT,
2447                                                   switch_vt_binding, ec);
2448
2449         wl_list_init(&ec->sprite_list);
2450         create_sprites(ec);
2451
2452         if (create_outputs(ec, connector, drm_device) < 0) {
2453                 weston_log("failed to create output for %s\n", path);
2454                 goto err_sprite;
2455         }
2456
2457         path = NULL;
2458
2459         if (udev_seat_create(&ec->base, ec->udev, seat) == NULL) {
2460                 weston_log("failed to create input devices\n");
2461                 goto err_sprite;
2462         }
2463
2464         loop = wl_display_get_event_loop(ec->base.wl_display);
2465         ec->drm_source =
2466                 wl_event_loop_add_fd(loop, ec->drm.fd,
2467                                      WL_EVENT_READABLE, on_drm_input, ec);
2468
2469         ec->udev_monitor = udev_monitor_new_from_netlink(ec->udev, "udev");
2470         if (ec->udev_monitor == NULL) {
2471                 weston_log("failed to intialize udev monitor\n");
2472                 goto err_drm_source;
2473         }
2474         udev_monitor_filter_add_match_subsystem_devtype(ec->udev_monitor,
2475                                                         "drm", NULL);
2476         ec->udev_drm_source =
2477                 wl_event_loop_add_fd(loop,
2478                                      udev_monitor_get_fd(ec->udev_monitor),
2479                                      WL_EVENT_READABLE, udev_drm_event, ec);
2480
2481         if (udev_monitor_enable_receiving(ec->udev_monitor) < 0) {
2482                 weston_log("failed to enable udev-monitor receiving\n");
2483                 goto err_udev_monitor;
2484         }
2485
2486         udev_device_unref(drm_device);
2487
2488         weston_compositor_add_debug_binding(&ec->base, KEY_O,
2489                                             planes_binding, ec);
2490         weston_compositor_add_debug_binding(&ec->base, KEY_C,
2491                                             planes_binding, ec);
2492         weston_compositor_add_debug_binding(&ec->base, KEY_V,
2493                                             planes_binding, ec);
2494
2495         return &ec->base;
2496
2497 err_udev_monitor:
2498         wl_event_source_remove(ec->udev_drm_source);
2499         udev_monitor_unref(ec->udev_monitor);
2500 err_drm_source:
2501         wl_event_source_remove(ec->drm_source);
2502         wl_list_for_each_safe(udev_seat, next, &ec->base.seat_list, base.link)
2503                 udev_seat_destroy(udev_seat);
2504 err_sprite:
2505         ec->base.renderer->destroy(&ec->base);
2506         gbm_device_destroy(ec->gbm);
2507         destroy_sprites(ec);
2508 err_udev_dev:
2509         udev_device_unref(drm_device);
2510 err_tty:
2511         if (weston_launcher_drm_set_master(&ec->base, ec->drm.fd, 0) < 0)
2512                 weston_log("failed to drop master: %m\n");
2513         tty_destroy(ec->tty);
2514 err_udev:
2515         udev_unref(ec->udev);
2516 err_compositor:
2517         weston_compositor_shutdown(&ec->base);
2518 err_base:
2519         free(ec);
2520         return NULL;
2521 }
2522
2523 static int
2524 set_sync_flags(drmModeModeInfo *mode, char *hsync, char *vsync)
2525 {
2526         mode->flags = 0;
2527
2528         if (strcmp(hsync, "+hsync") == 0)
2529                 mode->flags |= DRM_MODE_FLAG_PHSYNC;
2530         else if (strcmp(hsync, "-hsync") == 0)
2531                 mode->flags |= DRM_MODE_FLAG_NHSYNC;
2532         else
2533                 return -1;
2534
2535         if (strcmp(vsync, "+vsync") == 0)
2536                 mode->flags |= DRM_MODE_FLAG_PVSYNC;
2537         else if (strcmp(vsync, "-vsync") == 0)
2538                 mode->flags |= DRM_MODE_FLAG_NVSYNC;
2539         else
2540                 return -1;
2541
2542         return 0;
2543 }
2544
2545 static int
2546 check_for_modeline(struct drm_configured_output *output)
2547 {
2548         drmModeModeInfo mode;
2549         char hsync[16];
2550         char vsync[16];
2551         char mode_name[16];
2552         float fclock;
2553
2554         mode.type = DRM_MODE_TYPE_USERDEF;
2555         mode.hskew = 0;
2556         mode.vscan = 0;
2557         mode.vrefresh = 0;
2558
2559         if (sscanf(output_mode, "%f %hd %hd %hd %hd %hd %hd %hd %hd %s %s",
2560                                                 &fclock, &mode.hdisplay,
2561                                                 &mode.hsync_start,
2562                                                 &mode.hsync_end, &mode.htotal,
2563                                                 &mode.vdisplay,
2564                                                 &mode.vsync_start,
2565                                                 &mode.vsync_end, &mode.vtotal,
2566                                                 hsync, vsync) == 11) {
2567                 if (set_sync_flags(&mode, hsync, vsync))
2568                         return -1;
2569
2570                 sprintf(mode_name, "%dx%d", mode.hdisplay, mode.vdisplay);
2571                 strcpy(mode.name, mode_name);
2572
2573                 mode.clock = fclock * 1000;
2574         } else
2575                 return -1;
2576
2577         output->crtc_mode = mode;
2578
2579         return 0;
2580 }
2581
2582 static void
2583 drm_output_set_transform(struct drm_configured_output *output)
2584 {
2585         if (!output_transform) {
2586                 output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
2587                 return;
2588         }
2589
2590         if (!strcmp(output_transform, "normal"))
2591                 output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
2592         else if (!strcmp(output_transform, "90"))
2593                 output->transform = WL_OUTPUT_TRANSFORM_90;
2594         else if (!strcmp(output_transform, "180"))
2595                 output->transform = WL_OUTPUT_TRANSFORM_180;
2596         else if (!strcmp(output_transform, "270"))
2597                 output->transform = WL_OUTPUT_TRANSFORM_270;
2598         else if (!strcmp(output_transform, "flipped"))
2599                 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED;
2600         else if (!strcmp(output_transform, "flipped-90"))
2601                 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;
2602         else if (!strcmp(output_transform, "flipped-180"))
2603                 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
2604         else if (!strcmp(output_transform, "flipped-270"))
2605                 output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270;
2606         else {
2607                 weston_log("Invalid transform \"%s\" for output %s\n",
2608                                                 output_transform, output_name);
2609                 output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
2610         }
2611
2612         free(output_transform);
2613         output_transform = NULL;
2614 }
2615
2616 static void
2617 output_section_done(void *data)
2618 {
2619         struct drm_configured_output *output;
2620
2621         output = malloc(sizeof *output);
2622
2623         if (!output || !output_name || (output_name[0] == 'X') ||
2624                                         (!output_mode && !output_transform)) {
2625                 free(output_name);
2626                 free(output_mode);
2627                 free(output_transform);
2628                 free(output);
2629                 output_name = NULL;
2630                 output_mode = NULL;
2631                 output_transform = NULL;
2632                 return;
2633         }
2634
2635         output->config = OUTPUT_CONFIG_INVALID;
2636         output->name = output_name;
2637         output->mode = output_mode;
2638
2639         if (output_mode) {
2640                 if (strcmp(output_mode, "off") == 0)
2641                         output->config = OUTPUT_CONFIG_OFF;
2642                 else if (strcmp(output_mode, "preferred") == 0)
2643                         output->config = OUTPUT_CONFIG_PREFERRED;
2644                 else if (strcmp(output_mode, "current") == 0)
2645                         output->config = OUTPUT_CONFIG_CURRENT;
2646                 else if (sscanf(output_mode, "%dx%d",
2647                                         &output->width, &output->height) == 2)
2648                         output->config = OUTPUT_CONFIG_MODE;
2649                 else if (check_for_modeline(output) == 0)
2650                         output->config = OUTPUT_CONFIG_MODELINE;
2651
2652                 if (output->config == OUTPUT_CONFIG_INVALID)
2653                         weston_log("Invalid mode \"%s\" for output %s\n",
2654                                                         output_mode, output_name);
2655                 output_mode = NULL;
2656         }
2657
2658         drm_output_set_transform(output);
2659
2660         wl_list_insert(&configured_output_list, &output->link);
2661
2662         if (output_transform)
2663                 free(output_transform);
2664         output_transform = NULL;
2665 }
2666
2667 WL_EXPORT struct weston_compositor *
2668 backend_init(struct wl_display *display, int *argc, char *argv[],
2669              const char *config_file)
2670 {
2671         int connector = 0, tty = 0, use_pixman = 0;
2672         const char *seat = default_seat;
2673
2674         const struct weston_option drm_options[] = {
2675                 { WESTON_OPTION_INTEGER, "connector", 0, &connector },
2676                 { WESTON_OPTION_STRING, "seat", 0, &seat },
2677                 { WESTON_OPTION_INTEGER, "tty", 0, &tty },
2678                 { WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode },
2679                 { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &use_pixman },
2680         };
2681
2682         parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv);
2683
2684         wl_list_init(&configured_output_list);
2685
2686         const struct config_key drm_config_keys[] = {
2687                 { "name", CONFIG_KEY_STRING, &output_name },
2688                 { "mode", CONFIG_KEY_STRING, &output_mode },
2689                 { "transform", CONFIG_KEY_STRING, &output_transform },
2690         };
2691
2692         const struct config_section config_section[] = {
2693                 { "output", drm_config_keys,
2694                 ARRAY_LENGTH(drm_config_keys), output_section_done },
2695         };
2696
2697         parse_config_file(config_file, config_section,
2698                                 ARRAY_LENGTH(config_section), NULL);
2699
2700         return drm_compositor_create(display, connector, seat, tty, use_pixman,
2701                                      argc, argv, config_file);
2702 }