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