return ret;
}
+EXTERN tdm_error
+tdm_output_add_mode_change_request_handler(tdm_output *output,
+ tdm_output_mode_change_request_handler func,
+ void *user_data)
+{
+ tdm_private_display *private_display;
+ tdm_private_output *private_output;
+ tdm_private_output_mode_change_handler *mode_change_handler = NULL;
+
+ TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ private_output = (tdm_private_output*)output;
+ private_display = private_output->private_display;
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ LIST_FOR_EACH_ENTRY(mode_change_handler, &private_output->mode_change_request_handler_list, link) {
+ if (mode_change_handler->func == func && mode_change_handler->user_data == user_data) {
+ TDM_ERR("can't add twice");
+ _pthread_mutex_unlock(&private_display->lock);
+ return TDM_ERROR_BAD_REQUEST;
+ }
+ }
+
+ mode_change_handler = calloc(1, sizeof(tdm_private_output_change_handler));
+ if (!mode_change_handler) {
+ /* LCOV_EXCL_START */
+ TDM_ERR("failed: alloc memory");
+ _pthread_mutex_unlock(&private_display->lock);
+ return TDM_ERROR_OUT_OF_MEMORY;
+ /* LCOV_EXCL_STOP */
+ }
+
+ mode_change_handler->private_output = private_output;
+ mode_change_handler->func = func;
+ mode_change_handler->user_data = user_data;
+
+ LIST_ADDTAIL(&mode_change_handler->link, &private_output->mode_change_request_handler_list);
+
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return TDM_ERROR_NONE;
+}
+
+EXTERN tdm_error
+tdm_output_remove_mode_change_request_handler(tdm_output *output,
+ tdm_output_mode_change_request_handler func,
+ void *user_data)
+{
+ tdm_private_display *private_display;
+ tdm_private_output *private_output;
+ tdm_private_output_mode_change_handler *mode_change_handler = NULL, *hh = NULL;
+
+ TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ private_output = (tdm_private_output*)output;
+ private_display = private_output->private_display;
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ LIST_FOR_EACH_ENTRY_SAFE(mode_change_handler, hh, &private_output->mode_change_request_handler_list, link) {
+ if (mode_change_handler->func != func || mode_change_handler->user_data != user_data)
+ continue;
+
+ LIST_DEL(&mode_change_handler->link);
+ free(mode_change_handler);
+
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return TDM_ERROR_NONE;
+ }
+
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return TDM_ERROR_INVALID_PARAMETER;
+}
+
EXTERN void
tdm_output_remove_change_handler(tdm_output *output,
tdm_output_change_handler func,
return ret;
}
+INTERN void
+tdm_output_request_mode_set(tdm_output *output, unsigned int index)
+{
+ tdm_private_output *private_output = (tdm_private_output*)output;
+ tdm_private_output_mode_change_handler *mode_change_handler = NULL;
+
+ TDM_RETURN_IF_FAIL(private_output != NULL);
+
+ if (LIST_IS_EMPTY(&private_output->mode_change_request_handler_list))
+ return;
+
+ LIST_FOR_EACH_ENTRY(mode_change_handler, &private_output->mode_change_request_handler_list, link) {
+ mode_change_handler->func(mode_change_handler->private_output, index, mode_change_handler->user_data);
+ }
+}
+
INTERN tdm_error
tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data)
{
return ret;
}
+
+INTERN tdm_error
+tdm_voutput_set_available_mode(tdm_voutput *voutput, const tdm_output_mode *modes, int count)
+{
+ tdm_private_display *private_display;
+ tdm_private_module *private_module = NULL;
+ tdm_private_voutput *private_voutput;
+ tdm_func_voutput *func_voutput = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
+
+ TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(count != 0, TDM_ERROR_INVALID_PARAMETER);
+
+ private_voutput = (tdm_private_voutput*)voutput;
+ private_display = private_voutput->private_display;
+ private_module = private_voutput->private_module;
+ TDM_RETURN_VAL_IF_FAIL(private_module == private_display->virtual_module, TDM_ERROR_BAD_MODULE);
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ func_voutput = &private_module->func_voutput;
+ if (func_voutput->voutput_set_available_mode)
+ ret = func_voutput->voutput_set_available_mode(private_voutput->voutput_backend, modes, count);
+ else
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}
+
+INTERN tdm_error
+tdm_voutput_set_physical_size(tdm_voutput *voutput, unsigned int mmwidth, unsigned int mmheight)
+{
+ tdm_private_display *private_display;
+ tdm_private_module *private_module = NULL;
+ tdm_private_voutput *private_voutput;
+ tdm_func_voutput *func_voutput = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
+
+ TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(mmwidth != 0, TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(mmheight != 0, TDM_ERROR_INVALID_PARAMETER);
+
+ private_voutput = (tdm_private_voutput*)voutput;
+ private_display = private_voutput->private_display;
+ private_module = private_voutput->private_module;
+ TDM_RETURN_VAL_IF_FAIL(private_module == private_display->virtual_module, TDM_ERROR_BAD_MODULE);
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ func_voutput = &private_module->func_voutput;
+ if (func_voutput->voutput_set_physical_size)
+ ret = func_voutput->voutput_set_physical_size(private_voutput->voutput_backend, mmwidth, mmheight);
+ else
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}
+
+INTERN tdm_error
+tdm_voutput_connect(tdm_voutput *voutput)
+{
+ tdm_private_display *private_display;
+ tdm_private_module *private_module = NULL;
+ tdm_private_voutput *private_voutput;
+ tdm_func_voutput *func_voutput = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
+
+ TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ private_voutput = (tdm_private_voutput*)voutput;
+ private_display = private_voutput->private_display;
+ private_module = private_voutput->private_module;
+ TDM_RETURN_VAL_IF_FAIL(private_module == private_display->virtual_module, TDM_ERROR_BAD_MODULE);
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ func_voutput = &private_module->func_voutput;
+ if (func_voutput->voutput_connect)
+ ret = func_voutput->voutput_connect(private_voutput->voutput_backend);
+ else
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}
+
+INTERN tdm_error
+tdm_voutput_disconnect(tdm_voutput *voutput)
+{
+ tdm_private_display *private_display;
+ tdm_private_module *private_module = NULL;
+ tdm_private_voutput *private_voutput;
+ tdm_func_voutput *func_voutput = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
+
+ TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ private_voutput = (tdm_private_voutput*)voutput;
+ private_display = private_voutput->private_display;
+ private_module = private_voutput->private_module;
+ TDM_RETURN_VAL_IF_FAIL(private_module == private_display->virtual_module, TDM_ERROR_BAD_MODULE);
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ func_voutput = &private_module->func_voutput;
+ if (func_voutput->voutput_disconnect)
+ ret = func_voutput->voutput_disconnect(private_voutput->voutput_backend);
+ else
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}
tdm_server_output_info *output_info = user_data;
struct wl_client *client;
pid_t pid = 0;
+ tdm_output_conn_status status;
+ tdm_error ret = TDM_ERROR_NONE;
TDM_RETURN_IF_FAIL(output_info != NULL);
return;
}
- TDM_DBG("send the output changes: %d", (unsigned int)pid);
+ TDM_DBG("send the output changes: %d, type:%d, value:%d", (unsigned int)pid, type, value.u32);
switch (type) {
case TDM_OUTPUT_CHANGE_DPMS:
wl_tdm_output_send_dpms(output_info->resource, value.u32, TDM_ERROR_NONE);
break;
case TDM_OUTPUT_CHANGE_CONNECTION:
+ status = value.u32;
+ if (status == TDM_OUTPUT_CONN_STATUS_MODE_SETTED) {
+ const tdm_output_mode *mode = NULL;
+ unsigned int hdisplay, vdisplay, vrefresh;
+
+ ret = tdm_output_get_mode(output_info->output, &mode);
+ if (ret == TDM_ERROR_NONE) {
+ hdisplay = (mode) ? mode->hdisplay : 0;
+ vdisplay = (mode) ? mode->vdisplay : 0;
+ vrefresh = (mode) ? mode->vrefresh : 0;
+
+ wl_tdm_output_send_mode(output_info->resource, hdisplay, vdisplay, vrefresh, ret);
+ } else {
+ wl_tdm_output_send_mode(output_info->resource, 0, 0, 0, ret);
+ }
+ }
wl_tdm_output_send_connection(output_info->resource, value.u32, TDM_ERROR_NONE);
break;
default:
struct wl_resource *resource,
struct wl_array *modes)
{
- /* TODO */
+ tdm_server_voutput_info *voutput_info;
+ tdm_output_mode *mode;
+ int size, count = 0, i = 0;
+
+ voutput_info = wl_resource_get_user_data(resource);
+
+ voutput_info->available_modes.count = 0;
+ if (voutput_info->available_modes.modes)
+ free(voutput_info->available_modes.modes);
+
+ wl_array_for_each(mode, modes)
+ count++;
+ size = sizeof(tdm_output_mode);
+
+ voutput_info->available_modes.modes = malloc(count * size);
+ voutput_info->available_modes.count = count;
+
+ wl_array_for_each(mode, modes)
+ memcpy(&voutput_info->available_modes.modes[i++], mode, size);
}
static void
_tdm_voutput_cb_set_physical_size(struct wl_client *client, struct wl_resource *resource,
unsigned int mmwidth, unsigned int mmheight)
{
- /* TODO */
+ tdm_server_voutput_info *voutput_info;
+
+ voutput_info = wl_resource_get_user_data(resource);
+
+ voutput_info->mmwidth = mmwidth;
+ voutput_info->mmheight = mmheight;
}
static void
_tdm_voutput_cb_set_mode(struct wl_client *client, struct wl_resource *resource, unsigned int index)
{
- /* TODO */
+ tdm_server_voutput_info *voutput_info = NULL;
+ tdm_output *output = NULL;
+ tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+ const tdm_output_mode *modes, *mode;
+
+ int count = 0;
+ tdm_error ret;
+
+ voutput_info = wl_resource_get_user_data(resource);
+ TDM_RETURN_IF_FAIL(voutput_info != NULL);
+ output = voutput_info->output;
+
+ ret = tdm_output_get_conn_status(output, &status);
+ TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
+ TDM_RETURN_IF_FAIL(status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED);
+
+ ret = tdm_output_get_available_modes(output, &modes, &count);
+ TDM_RETURN_IF_FAIL(index < count);
+
+ mode = &modes[index];
+ TDM_DBG("mode set request to index:%d (%dx%d, %d)", index, mode->hdisplay, mode->vdisplay, mode->vrefresh);
+
+ ret = tdm_output_set_mode(output, mode);
+ TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
+
+ tdm_output_request_mode_set(voutput_info->output, index);
}
static void
_tdm_voutput_cb_connect(struct wl_client *client, struct wl_resource *resource)
{
- /* TODO */
+ tdm_server_voutput_info *voutput_info;
+
+ voutput_info = wl_resource_get_user_data(resource);
+ voutput_info->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
+
+ tdm_voutput_set_physical_size(voutput_info->voutput, voutput_info->mmwidth, voutput_info->mmheight);
+ tdm_voutput_set_available_mode(voutput_info->voutput, voutput_info->available_modes.modes, voutput_info->available_modes.count);
+ tdm_voutput_connect(voutput_info->voutput);
}
static void
_tdm_voutput_cb_disconnect(struct wl_client *client, struct wl_resource *resource)
{
- /* TODO */
+ tdm_server_voutput_info *voutput_info;
+
+ voutput_info = wl_resource_get_user_data(resource);
+ voutput_info->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+
+ /* Do free resources when it's being disconnected */
+ free(voutput_info->available_modes.modes);
+ voutput_info->available_modes.modes = NULL;
+ voutput_info->available_modes.count = 0;
+ voutput_info->mmwidth = 0;
+ voutput_info->mmheight = 0;
+
+ tdm_voutput_disconnect(voutput_info->voutput);
}
static void