+tdm_output *
+virtual_display_output_create(tdm_backend_data *bdata, const char *name, tdm_error *error)
+{
+ tdm_virtual_data *virtual_data = bdata;
+ tdm_virtual_output_data *output_data = NULL;
+ tdm_virtual_layer_data *layer_data = NULL;
+ tdm_error ret;
+
+ if (!virtual_data || !name) {
+ TDM_ERR("invalid parameter");
+ *error = TDM_ERROR_INVALID_PARAMETER;
+ return NULL;
+ }
+
+ output_data = calloc(1, sizeof(tdm_virtual_output_data));
+ if (!output_data) {
+ TDM_ERR("alloc failed");
+ *error = TDM_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ LIST_INITHEAD(&output_data->layer_list);
+
+ output_data->virtual_data = virtual_data;
+ output_data->pipe = 0;
+ output_data->connector_type = TDM_OUTPUT_TYPE_Unknown;
+ output_data->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+
+ if (name)
+ snprintf(output_data->name, TDM_NAME_LEN, "%s", name);
+ else
+ snprintf(output_data->name, TDM_NAME_LEN, "unknown");
+#if 0
+ output_data->output_mode = calloc(1, sizeof(tdm_output_mode));
+ if (!output_data->output_mode) {
+ TDM_ERR("alloc failed");
+ ret = TDM_ERROR_OUT_OF_MEMORY;
+ goto create_fail;
+ }
+
+ snprintf(output_data->output_mode->name, TDM_NAME_LEN, "640x480");
+ output_data->output_mode->vrefresh = 30;
+ output_data->output_mode->clock = 25200;
+ output_data->output_mode->hdisplay = 640;
+ output_data->output_mode->hsync_start = 656;
+ output_data->output_mode->hsync_end = 752;
+ output_data->output_mode->htotal = 800;
+ output_data->output_mode->hskew = 0;
+ output_data->output_mode->vdisplay = 480;
+ output_data->output_mode->vsync_start = 490;
+ output_data->output_mode->vsync_end = 492;
+ output_data->output_mode->vtotal = 525;
+ output_data->output_mode->vscan = 0;
+ output_data->output_mode->flags = 0;
+ output_data->output_mode->type = 0;
+
+ output_data->mode_count = 1;
+#endif
+ output_data->timer = tdm_event_loop_add_timer_handler(virtual_data->dpy,
+ _tdm_virtual_display_cb_timeout,
+ output_data,
+ &ret);
+ if (!output_data->timer) goto create_fail;
+
+ LIST_INITHEAD(&output_data->timer_event_list);
+
+ /* The TDM virtual backend output support only one layer. */
+ layer_data = calloc(1, sizeof(tdm_virtual_layer_data));
+ if (!layer_data) {
+ TDM_ERR("alloc failed");
+ ret = TDM_ERROR_OUT_OF_MEMORY;
+ goto create_fail;
+ }
+
+ layer_data->virtual_data = virtual_data;
+ layer_data->output_data = output_data;
+ layer_data->zpos = 0;
+
+ layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY | TDM_LAYER_CAPABILITY_GRAPHIC;
+ output_data->primary_layer = layer_data;
+
+ LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
+
+ ret = tdm_backend_register_output(virtual_data->dpy, output_data);
+ GOTO_IF_FAIL(ret == TDM_ERROR_NONE, create_fail);
+
+ *error = TDM_ERROR_NONE;
+
+ return output_data;
+
+create_fail:
+ if (layer_data) free(layer_data);
+ if (output_data->output_mode) free(output_data->output_mode);
+ free(output_data);
+
+ *error = ret;
+
+ return NULL;
+}
+
+tdm_error
+virtual_display_output_destroy(tdm_backend_data *bdata, tdm_output *output)
+{
+ tdm_virtual_data *virtual_data = bdata;
+ tdm_virtual_output_data *o, *output_data = output;
+ int find = 0;
+
+ RETURN_VAL_IF_FAIL(virtual_data, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+
+ LIST_FOR_EACH_ENTRY(o, &virtual_data->output_list, link) {
+ if (o == output_data) {
+ find = 1;
+ break;
+ }
+ }
+
+ if (find)
+ tdm_backend_unregister_output(virtual_data->dpy, output);
+ else
+ return TDM_ERROR_INVALID_PARAMETER;
+
+ return TDM_ERROR_NONE;
+}
+