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