8 static const struct ds_backend_interface tdm_backend_iface;
10 static void tdm_backend_handle_display_destroy(struct wl_listener *listener,
12 static void tdm_backend_destroy(struct ds_tdm_backend *tdm);
13 static int tdm_backend_handle_tdm_event(int fd, uint32_t mask, void *data);
15 WL_EXPORT struct ds_backend *
16 ds_tdm_backend_create(struct wl_display *display)
18 struct ds_tdm_backend *tdm;
19 struct wl_event_loop *loop;
22 ds_inf("Initializing TDM backend");
24 tdm = calloc(1, sizeof *tdm);
28 ds_backend_init(&tdm->base, display, &tdm_backend_iface);
30 tdm->wl_display = display;
31 tdm->clock = CLOCK_MONOTONIC; // FIXME
33 wl_list_init(&tdm->outputs);
34 wl_list_init(&tdm->buffers);
36 tdm->tdm_display = tdm_display_init(&err);
37 if (err != TDM_ERROR_NONE) {
38 ds_err("Could not initialize tdm_display");
42 err = tdm_display_get_fd(tdm->tdm_display, &tdm->fd);
43 if (err != TDM_ERROR_NONE || tdm->fd < 0) {
44 ds_err("Could not get fd from tdm_display: err(%d)", err);
48 loop = wl_display_get_event_loop(display);
49 tdm->tdm_event = wl_event_loop_add_fd(loop, tdm->fd, WL_EVENT_READABLE,
50 tdm_backend_handle_tdm_event, tdm);
51 if (!tdm->tdm_event) {
52 ds_err("could not add fd event handler for tdm event");
56 tdm->display_destroy.notify = tdm_backend_handle_display_destroy;
57 wl_display_add_destroy_listener(display, &tdm->display_destroy);
64 tdm_display_deinit(tdm->tdm_display);
71 struct ds_tdm_backend *
72 tdm_backend_from_backend(struct ds_backend *backend)
74 assert(backend->iface == &tdm_backend_iface);
75 return (struct ds_tdm_backend *)backend;
79 tdm_backend_destroy(struct ds_tdm_backend *tdm)
81 struct ds_tdm_output *output, *tmp_output;
82 struct ds_tdm_buffer *buffer, *tmp_buffer;
84 wl_list_for_each_safe(output, tmp_output, &tdm->outputs, link)
85 ds_output_destroy(&output->base);
87 wl_list_for_each_safe(buffer, tmp_buffer, &tdm->buffers, link)
88 destroy_tdm_buffer(buffer);
90 wl_list_remove(&tdm->display_destroy.link);
91 wl_event_source_remove(tdm->tdm_event);
93 tdm_display_deinit(tdm->tdm_display);
94 ds_backend_finish(&tdm->base);
99 tdm_backend_scan_outputs(struct ds_tdm_backend *tdm)
101 struct ds_tdm_output *output;
102 tdm_output *tdm_output;
106 err = tdm_display_get_output_count(tdm->tdm_display, &num_outputs);
107 if (err != TDM_ERROR_NONE) {
108 ds_err("Could not get number of outputs: err(%d)", err);
112 for (i = 0; i < num_outputs; i++) {
113 tdm_output = tdm_display_get_output(tdm->tdm_display, i, &err);
114 if (err != TDM_ERROR_NONE || !tdm_output) {
115 ds_err("Could not get output from tdm_display: index(%d) err(%d)",
120 output = create_tdm_output(tdm, tdm_output);
122 ds_err("Could not create output: index(%d)", i);
126 wl_list_insert(&tdm->outputs, &output->link);
128 wl_signal_emit(&tdm->base.events.new_output, &output->base);
135 tdm_backend_iface_start(struct ds_backend *backend)
137 struct ds_tdm_backend *tdm;
139 tdm = tdm_backend_from_backend(backend);
140 return tdm_backend_scan_outputs(tdm);
144 tdm_backend_iface_destroy(struct ds_backend *backend)
146 struct ds_tdm_backend *tdm;
148 tdm = tdm_backend_from_backend(backend);
149 tdm_backend_destroy(tdm);
152 static const struct ds_backend_interface tdm_backend_iface =
154 .start = tdm_backend_iface_start,
155 .destroy = tdm_backend_iface_destroy,
160 tdm_backend_handle_display_destroy(struct wl_listener *listener, void *data)
162 struct ds_tdm_backend *tdm;
164 tdm = wl_container_of(listener, tdm, display_destroy);
165 tdm_backend_destroy(tdm);
169 tdm_backend_handle_tdm_event(int fd, uint32_t mask, void *data)
171 struct ds_tdm_backend *tdm = data;
173 tdm_display_handle_events(tdm->tdm_display);