tdm_client_output_set_mode(tdm_client_output *output, int index)
{
tdm_private_client_output *private_output;
+ tdm_private_client *private_client;
TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
- TDM_RETURN_VAL_IF_FAIL(index < 0, TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(index >= 0, TDM_ERROR_INVALID_PARAMETER);
private_output = (tdm_private_client_output*)output;
+ private_client = private_output->private_client;
+
+ pthread_mutex_lock(&private_client->lock);
if (private_output->available_modes.count - 1 < index)
return TDM_ERROR_INVALID_PARAMETER;
wl_tdm_output_set_mode(private_output->output, index);
+ pthread_mutex_unlock(&private_client->lock);
+
return TDM_ERROR_NONE;
}
ASSERT_EQ(tdm_client_output_get_available_modes(output, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
}
+TEST_P(TDMClient, ClientOutputSetMode)
+{
+ tdm_client_output_mode *modes;
+ int count = 0;
+
+ ASSERT_EQ(PrepareClient(), true);
+ ASSERT_EQ(PrepareOutput(), true);
+
+ ASSERT_EQ(tdm_client_output_get_available_modes(output, &modes, &count), TDM_ERROR_NONE);
+
+ printf("count:%d\n", count);
+
+ ASSERT_EQ(tdm_client_output_set_mode(output, count - 1), TDM_ERROR_NONE);
+}
+
+TEST_P(TDMClient, ClientOutputSetModeiNullObject)
+{
+ ASSERT_EQ(PrepareClient(), true);
+ ASSERT_EQ(PrepareOutput(), true);
+
+ ASSERT_EQ(tdm_client_output_set_mode(NULL, 0), TDM_ERROR_INVALID_PARAMETER);
+}
+
+TEST_P(TDMClient, ClientOutputSetModeInvalidIndex)
+{
+ ASSERT_EQ(PrepareClient(), true);
+ ASSERT_EQ(PrepareOutput(), true);
+
+ ASSERT_EQ(tdm_client_output_set_mode(output, -1), TDM_ERROR_INVALID_PARAMETER);
+}
+
/* tdm_client_output_create_vblank */
TEST_P(TDMClient, ClientOutputCreateVblank)
{
tdm_output_change_handler func,
void *user_data);
+tdm_error
+tdm_output_add_mode_change_request_handler(tdm_output *output,
+ tdm_output_mode_change_request_handler func,
+ void *user_data);
+
+tdm_error
+tdm_output_remove_mode_change_request_handler(tdm_output *output,
+ tdm_output_mode_change_request_handler func,
+ void *user_data);
+
/**
* @brief Get the connection type of a output object.
* @param[in] output A output object
void *user_data);
/**
+ * @brief The output mode change request handler
+ */
+typedef void (*tdm_output_mode_change_request_handler)(tdm_output *output,
+ unsigned int index, void *user_data);
+
+/**
* @brief The layer commit handler
*/
typedef void (*tdm_layer_commit_handler)(tdm_layer *layer, unsigned int sequence,
LIST_INITHEAD(&private_output->pending_commit_handler_list);
LIST_INITHEAD(&private_output->destroy_handler_list);
LIST_INITHEAD(&private_output->change_handler_list);
+ LIST_INITHEAD(&private_output->mode_change_request_handler_list);
if (func_output->output_set_status_handler) {
func_output->output_set_status_handler(private_output->output_backend,
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,
*count = 0;
LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
- (*count)++;
+ (*count)++;
if (*count == 0) {
_pthread_mutex_unlock(&private_display->lock);
return TDM_ERROR_NONE;
return ret;
}
+INTERN void
+tdm_output_call_mode_set_request(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);
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
+
+ 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);
+ }
+}
+
tdm_error
_tdm_output_commit_virtual(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data)
{
tdm_output_remove_vblank_handler_internal(tdm_output *output, tdm_output_vblank_handler func, void *user_data);
void
tdm_output_remove_commit_handler_internal(tdm_output *output, tdm_output_commit_handler func, void *user_data);
+
+void
+tdm_output_call_mode_set_request(tdm_output *output, unsigned int index);
+
void
tdm_layer_remove_commit_handler_internal(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data);
typedef struct _tdm_private_output_change_handler tdm_private_output_change_handler;
typedef struct _tdm_private_output_commit_handler tdm_private_output_commit_handler;
typedef struct _tdm_private_output_vblank_handler tdm_private_output_vblank_handler;
+typedef struct _tdm_private_output_mode_change_handler tdm_private_output_mode_change_handler;
typedef struct _tdm_private_layer_commit_handler tdm_private_layer_commit_handler;
typedef struct _tdm_private_hwc_commit_handler tdm_private_hwc_commit_handler;
/* virtual */
char name[TDM_NAME_LEN];
+ struct list_head mode_change_request_handler_list;
};
struct _tdm_private_layer {
pid_t owner_tid;
};
+struct _tdm_private_output_mode_change_handler {
+ struct list_head link;
+
+ tdm_private_output *private_output;
+ tdm_output_mode_change_request_handler func;
+ void *user_data;
+};
+
struct _tdm_private_hwc_commit_handler {
struct list_head link;
tdm_error ret;
ret = tdm_output_get_available_modes(output_info->output, &modes, &count);
-
if ((ret != TDM_ERROR_NONE) || (count == 0)) {
wl_tdm_output_send_available_modes(output_info->resource, NULL, ret);
return;
{
tdm_server_output_info *output_info = wl_resource_get_user_data(resource);
tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+ const tdm_output_mode *modes;
+ int count = 0;
tdm_error ret;
TDM_RETURN_IF_FAIL(output_info != NULL);
TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
TDM_RETURN_IF_FAIL(status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED);
- //To do
+ ret = tdm_output_get_available_modes(output_info->output, &modes, &count);
+ TDM_RETURN_IF_FAIL(index < count);
+
+ tdm_output_call_mode_set_request(output_info->output, index);
return;
}