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