+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;
+}
+