virtual: implementations for virtual output
[platform/core/uifw/libtdm.git] / src / tdm_output.c
index 4a96e16..9454647 100644 (file)
@@ -500,6 +500,85 @@ tdm_output_add_change_handler(tdm_output *output,
        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,
@@ -1206,6 +1285,22 @@ tdm_output_remove_commit_handler(tdm_output *output, tdm_output_commit_handler f
        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)
 {
@@ -1856,3 +1951,123 @@ tdm_voutput_destroy(tdm_voutput *voutput)
 
        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;
+}