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