} sound_behavior_e;
/**
+ * @brief Definition for the value indicating that the preferred device for a stream information was not set."
+ * @since_tizen 5.5
+ * @see sound_manager_get_stream_preferred_device()
+ */
+#define SOUND_MANAGER_STREAM_NO_PREFERRED_DEVICE 0
+
+/**
* @}
*/
int sound_manager_apply_stream_routing(sound_stream_info_h stream_info);
/**
+ * @brief Sets the preferred built-in device for the stream routing.
+ * @since_tizen 5.5
+ *
+ * @remarks This function is to set a specific built-in device when the system has multiple devices of the same built-in device type.
+ * When there's only one device for a built-in device type in the system, nothing will happen even if this function succeeds in operation.
+ * If @a device is not supported by @a stream_info, #SOUND_MANAGER_ERROR_POLICY will be returned.
+ * After this function is called, @a device is not needed for the function's work. It's okay to destroy it by destroying the list from which it was obtained.
+ *
+ * @param[in] stream_info The handle of stream information
+ * @param[in] io_direction The IO direction of the device
+ * @param[in] device The preferred device (this can be NULL to unset)
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #SOUND_MANAGER_ERROR_NONE Success
+ * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SOUND_MANAGER_ERROR_POLICY Noncompliance with the sound system policy
+ * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
+ * @pre Call sound_manager_create_stream_information() before calling this function.
+ * @pre Get a device by calling sound_manager_get_device_list() and sound_manager_get_next_device().
+ * @post You can get preferred devices by calling sound_manager_get_stream_preferred_device().
+ * @post Call sound_manager_free_device_list() to free the devices.
+ * @see sound_manager_get_stream_preferred_device()
+ * @see sound_manager_create_stream_information()
+ * @see sound_manager_destroy_stream_information()
+ * @see sound_manager_get_device_list()
+ * @see sound_manager_get_next_device()
+ * @see sound_manager_free_device_list()
+ */
+int sound_manager_set_stream_preferred_device(sound_stream_info_h stream_info, sound_device_io_direction_e io_direction, sound_device_h device);
+
+/**
+ * @brief Gets the preferred device id of the stream info handle.
+ * @since_tizen 5.5
+ *
+ * @remarks This function is to return the preferred device id per each direction if it has been set.
+ * If there is no preferred device for a given direction, the corresponding output value will be set to
+ * #SOUND_MANAGER_STREAM_NO_PREFERRED_DEVICE.
+ * You can get a device handle of the id value by using sound_manager_get_device_list(),
+ * sound_manager_get_next_device() and sound_manager_get_device_id().
+ *
+ * @param[in] stream_info The handle of stream information
+ * @param[out] in_device_id The preferred input device id
+ * @param[out] out_device_id The preferred output device id
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #SOUND_MANAGER_ERROR_NONE Success
+ * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see sound_manager_set_stream_preferred_device()
+ * @see sound_manager_get_device_list()
+ * @see sound_manager_get_next_device()
+ * @see sound_manager_get_device_id()
+ * @see sound_manager_free_device_list()
+ */
+int sound_manager_get_stream_preferred_device(sound_stream_info_h stream_info, int *in_device_id, int *out_device_id);
+
+/**
* @brief Acquires the stream focus.
* @since_tizen 3.0
*
_CHECK_CONDITION(handle != NULL, SOUND_MANAGER_ERROR_INVALID_PARAMETER, "SOUND_MANAGER_ERROR_INVALID_PARAMETER")
#define SM_NULL_ARG_CHECK(arg) \
-_CHECK_CONDITION(arg != NULL, SOUND_MANAGER_ERROR_INVALID_PARAMETER, "SOUND_MANAGER_ERROR_INVALID_PARAMETER")
+_CHECK_CONDITION(!!(arg) != false, SOUND_MANAGER_ERROR_INVALID_PARAMETER, "SOUND_MANAGER_ERROR_INVALID_PARAMETER")
#define SM_STATE_CHECK(handle, expected_state) \
_CHECK_CONDITION(handle->state == expected_state, SOUND_MANAGER_ERROR_INVALID_STATE, "SOUND_MANAGER_ERROR_INVALID_STATE")
_CHECK_CONDITION(handle != NULL, MM_ERROR_INVALID_ARGUMENT, "MM_ERROR_INVALID_ARGUMENT")
#define SM_NULL_ARG_CHECK_FOR_PRIV(arg) \
-_CHECK_CONDITION(arg != NULL, MM_ERROR_INVALID_ARGUMENT, "MM_ERROR_INVALID_ARGUMENT")
+_CHECK_CONDITION(!!(arg) != false, MM_ERROR_INVALID_ARGUMENT, "MM_ERROR_INVALID_ARGUMENT")
#define SM_STATE_CHECK_FOR_PRIV(handle, expected_state) \
_CHECK_CONDITION(handle->state == expected_state, MM_ERROR_SOUND_INVALID_STATE, "MM_ERROR_SOUND_INVALID_STATE")
unsigned int index;
} sound_pa_info_s;
+typedef struct _preferred_device_info_s {
+ int in;
+ int out;
+} preferred_device_info_s;
+
typedef struct _sound_stream_info_s {
int focus_id;
char *stream_type;
sound_stream_focus_state_changed_cb user_cb;
void *user_data;
manual_route_info_s manual_route_info;
+ preferred_device_info_s preferred_device_info;
pthread_mutex_t focus_state_mutex;
pthread_mutex_t focus_cb_mutex;
} sound_stream_info_s;
int _get_ducking_state(uint32_t stream_index, bool *is_ducked);
+int _set_preferred_device(sound_stream_info_s *stream_info, sound_device_io_direction_e direction, sound_device_h device);
+
+int _get_preferred_device(sound_stream_info_s *stream_info, int *in_device_id, int *out_device_id);
+
#ifdef __cplusplus
}
#endif
Name: capi-media-sound-manager
Summary: Sound Manager library
-Version: 0.5.31
+Version: 0.5.32
Release: 0
Group: Multimedia/API
License: Apache-2.0
return _convert_sound_manager_error_code(__func__, ret);
}
+int sound_manager_set_stream_preferred_device(sound_stream_info_h stream_info, sound_device_io_direction_e io_direction, sound_device_h device)
+{
+ int ret = MM_ERROR_NONE;
+ sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
+
+ SM_NULL_ARG_CHECK(stream_h);
+
+ ret = _set_preferred_device(stream_h, io_direction, device);
+
+ return _convert_sound_manager_error_code(__func__, ret);
+}
+
+int sound_manager_get_stream_preferred_device(sound_stream_info_h stream_info, int *in_device_id, int *out_device_id)
+{
+ int ret = MM_ERROR_NONE;
+ sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
+
+ SM_NULL_ARG_CHECK(stream_h);
+ SM_NULL_ARG_CHECK(in_device_id || out_device_id);
+
+ ret = _get_preferred_device(stream_h, in_device_id, out_device_id);
+
+ return _convert_sound_manager_error_code(__func__, ret);
+}
+
int sound_manager_set_focus_reacquisition(sound_stream_info_h stream_info, bool enable)
{
int ret = MM_ERROR_NONE;
#define PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_INFO "GetStreamInfo"
#define PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_DEVICES "SetStreamRouteDevices"
#define PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_OPTION "SetStreamRouteOption"
+#define PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREFERRED_DEVICE "SetStreamPreferredDevice"
#define PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MAX_LEVEL "GetVolumeMaxLevel"
#define PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL "GetVolumeLevel"
#define PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL "SetVolumeLevel"
return MM_ERROR_NONE;
}
+static int __check_auto_route_type(sound_stream_info_s *stream_info)
+{
+ SM_INSTANCE_CHECK_FOR_PRIV(stream_info);
+
+ if (stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_AUTO &&
+ stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) {
+ LOGE("route type is not auto or auto-last-connected");
+ return MM_ERROR_POLICY_INTERNAL;
+ }
+
+ return MM_ERROR_NONE;
+}
+
static int __add_device_to_stream_info(sound_stream_info_s *stream_info, int device_id, mm_sound_device_io_direction_e device_direction, char *device_type_str)
{
int i, j;
return MM_ERROR_NONE;
}
+static int __is_available_device(sound_stream_info_s *stream_info, sound_device_h device, bool *available)
+{
+ int ret = MM_ERROR_NONE;
+ int i = 0;
+ mm_sound_device_type_e mm_sound_device_type;
+ sound_device_type_e device_type;
+ char *device_type_str = NULL;
+ char *avail_device_item = NULL;
+ mm_sound_device_io_direction_e device_direction;
+ bool found = false;
+
+ SM_INSTANCE_CHECK_FOR_PRIV(stream_info);
+ SM_INSTANCE_CHECK_FOR_PRIV(device);
+
+ if ((ret = mm_sound_get_device_type(device, &mm_sound_device_type)))
+ return ret;
+ if ((ret = _convert_device_type(mm_sound_device_type, &device_type)))
+ return ret;
+ if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)))
+ return ret;
+ if ((ret = mm_sound_get_device_io_direction(device, &device_direction)))
+ return ret;
+
+ if (device_direction & MM_SOUND_DEVICE_IO_DIRECTION_OUT) {
+ for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
+ if (!(avail_device_item = stream_info->stream_conf_info.avail_out_devices[i]))
+ break;
+ if (!strncmp(avail_device_item, device_type_str, strlen(device_type_str)))
+ found = true;
+ }
+ if (!found) {
+ LOGE("[OUT] this device(%s) is not available for this stream_info(%s)", device_type_str, stream_info->stream_type);
+ *available = false;
+ return MM_ERROR_NONE;
+ }
+ }
+
+ if (device_direction & MM_SOUND_DEVICE_IO_DIRECTION_IN) {
+ found = false;
+ for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
+ if (!(avail_device_item = stream_info->stream_conf_info.avail_in_devices[i]))
+ break;
+ if (!strncmp(avail_device_item, device_type_str, strlen(device_type_str)))
+ found = true;
+ }
+ if (!found) {
+ LOGE("[IN] this device(%s) is not available for this stream_info(%s)", device_type_str, stream_info->stream_type);
+ *available = false;
+ return MM_ERROR_NONE;
+ }
+ }
+
+ *available = true;
+
+ return MM_ERROR_NONE;
+}
+
int _add_device_for_stream_routing(sound_stream_info_s *stream_info, sound_device_h device)
{
int ret = MM_ERROR_NONE;
return ret;
}
-//LCOV_EXCL_STOP
int _activate_ducking(uint32_t stream_index, bool enable, const char *target_stream, uint32_t duration, double ratio)
{
return ret;
}
+
+
+int _set_preferred_device(sound_stream_info_s *stream_info, sound_device_io_direction_e direction, sound_device_h device)
+{
+ int ret = MM_ERROR_NONE;
+ GVariant *result = NULL;
+ GDBusConnection *conn = NULL;
+ GError *err = NULL;
+ const gchar *dbus_ret = NULL;
+ const gchar *direction_str;
+ bool available = false;
+ int device_id = 0;
+ mm_sound_device_io_direction_e io_direction;
+ int i;
+
+ SM_INSTANCE_CHECK_FOR_PRIV(stream_info);
+
+ /* allow only auto route type */
+ if ((ret = __check_auto_route_type(stream_info)))
+ return ret;
+
+ /* check if this device belongs to available devices of the stream info */
+ /* In case device is null, it's for unsetting preferred device, device_id will be 0. */
+ if (device) {
+ if ((ret = __is_available_device(stream_info, device, &available)))
+ return ret;
+ if (!available)
+ return MM_ERROR_POLICY_INTERNAL;
+ if ((ret = mm_sound_get_device_id(device, &device_id)))
+ return ret;
+ if ((ret = mm_sound_get_device_io_direction(device, &io_direction)))
+ return ret;
+ if (!(io_direction & (direction + 1)) || ((int)io_direction < (int)(direction + 1))) {
+ LOGE("device direction(0x%x), request direction(0x%x)", io_direction, (direction + 1));
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+ }
+
+ if ((ret = __get_dbus_connection(&conn)))
+ return ret;
+
+ for (i = SOUND_DEVICE_IO_DIRECTION_IN; i < SOUND_DEVICE_IO_DIRECTION_BOTH; i++) {
+ if (device) {
+ if (!(io_direction & (i + 1)))
+ continue;
+ } else {
+ if (!((direction + 1) & (i + 1)))
+ continue;
+ }
+ direction_str = (i == SOUND_DEVICE_IO_DIRECTION_IN) ? "in" : "out";
+
+ result = g_dbus_connection_call_sync(conn,
+ PA_BUS_NAME,
+ PA_STREAM_MANAGER_OBJECT_PATH,
+ PA_STREAM_MANAGER_INTERFACE,
+ PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREFERRED_DEVICE,
+ g_variant_new("(usu)", stream_info->pa_info.index, direction_str, (unsigned int)device_id),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ 2000,
+ NULL,
+ &err);
+ if (!result || err) {
+ LOGE("g_dbus_connection_call_sync() for SET PREFERRED DEVICE error (%s)", err ? err->message : NULL);
+ ret = _convert_dbus_error(err ? err->message : NULL);
+ if (err)
+ g_error_free(err);
+ if (result)
+ g_variant_unref(result);
+ goto LEAVE;
+ }
+
+ LOGI("Preferred device(id:%d, direction:%s) is set to PA context(%u)", device_id, direction_str, stream_info->pa_info.index);
+
+ g_variant_get(result, "(&s)", &dbus_ret);
+ LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
+ if (!strncmp("STREAM_MANAGER_RETURN_ERROR_DEVICE_NOT_FOUND", dbus_ret, strlen(dbus_ret)))
+ ret = MM_ERROR_INVALID_ARGUMENT;
+ else if (!strncmp("STREAM_MANAGER_RETURN_POLICY", dbus_ret, strlen(dbus_ret)))
+ ret = MM_ERROR_POLICY_INTERNAL;
+ else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
+ ret = MM_ERROR_SOUND_INTERNAL;
+
+ g_variant_unref(result);
+ if (ret)
+ goto LEAVE;
+
+ if (i == SOUND_DEVICE_IO_DIRECTION_IN)
+ stream_info->preferred_device_info.in = device_id;
+ else
+ stream_info->preferred_device_info.out = device_id;
+ }
+
+LEAVE:
+ g_object_unref(conn);
+
+ return ret;
+}
+
+int _get_preferred_device(sound_stream_info_s *stream_info, int *in_device_id, int *out_device_id)
+{
+ SM_INSTANCE_CHECK_FOR_PRIV(stream_info);
+
+ if (in_device_id) {
+ *in_device_id = stream_info->preferred_device_info.in;
+ LOGI("preferred device id[in:%d]", *in_device_id);
+ }
+ if (out_device_id) {
+ *out_device_id = stream_info->preferred_device_info.out;
+ LOGI("preferred device id[out:%d]", *out_device_id);
+ }
+
+ return MM_ERROR_NONE;
+}
+//LCOV_EXCL_STOP
\ No newline at end of file
CURRENT_STATUS_ADD_DEVICE_ID_FOR_STREAM_ROUTING,
CURRENT_STATUS_REMOVE_DEVICE_ID_FOR_STREAM_ROUTING,
CURRENT_STATUS_APPLY_STREAM_ROUTING,
+ CURRENT_STATUS_SET_STREAM_PREFERRED_DEVICE,
+ CURRENT_STATUS_GET_STREAM_PREFERRED_DEVICE,
CURRENT_STATUS_SET_STREAM_ROUTING_OPTION,
CURRENT_STATUS_ACQUIRE_FOCUS,
CURRENT_STATUS_RELEASE_FOCUS,
static const char *g_device_direction_str[] = {"IN", "OUT", "BOTH"};
static const char *g_device_state_str[] = {"De-Activated", "Activated"};
+static const char *g_device_type_str[] = {"builtin-speaker", "builtin-receiver", "builtin-mic",
+ "audio-jack", "bt-media", "hdmi",
+ "forwarding", "usb-audio", "bt-voice",
+ "network"};
void focus_callback(sound_stream_info_h stream_info,
sound_stream_focus_mask_e focus_mask,
g_menu_state = CURRENT_STATUS_APPLY_STREAM_ROUTING;
else if (strncmp(cmd, "sso", MAX_CMD_LEN) == 0)
g_menu_state = CURRENT_STATUS_SET_STREAM_ROUTING_OPTION;
+ else if (strncmp(cmd, "spd", MAX_CMD_LEN) == 0)
+ g_menu_state = CURRENT_STATUS_SET_STREAM_PREFERRED_DEVICE;
+ else if (strncmp(cmd, "gpd", MAX_CMD_LEN) == 0)
+ g_menu_state = CURRENT_STATUS_GET_STREAM_PREFERRED_DEVICE;
else if (strncmp(cmd, "afc", MAX_CMD_LEN) == 0)
g_menu_state = CURRENT_STATUS_ACQUIRE_FOCUS;
else if (strncmp(cmd, "rfc", MAX_CMD_LEN) == 0)
g_print("rdi. *Remove Device ID for Stream Routing\n");
g_print("aps. Apply devices for Stream Routing\t");
g_print("rad. Remove all devices for Stream Routing\n");
+ g_print("spd. Set preferred device\t");
+ g_print("gpd. Get preferred device\n");
g_print("afc. Acquire Focus\t");
g_print("rfc. Release Focus\t");
g_print("gfs. Get Focus State\n");
g_print("*** input device type to remove (0:built-in mic, 1:built-in spk, 2:built-in rcv, 3:audio-jack, 4:bt-a2dp, 5:bt-sco 6:usb)\n");
else if (g_menu_state == CURRENT_STATUS_APPLY_STREAM_ROUTING)
g_print("*** press enter to apply devices for stream routing\n");
+ else if (g_menu_state == CURRENT_STATUS_SET_STREAM_PREFERRED_DEVICE)
+ g_print("*** input direction to set preferred device (0:out, 1:in, 2:both)\n");
+ else if (g_menu_state == CURRENT_STATUS_GET_STREAM_PREFERRED_DEVICE)
+ g_print("*** press enter to get preferred device\n");
else if (g_menu_state == CURRENT_STATUS_SET_STREAM_ROUTING_OPTION)
g_print("*** input option(name/value) for routing (0:option_1/0, 1:option_1/1, 2:option_2/0, 3:option_2:1)\n");
else if (g_menu_state == CURRENT_STATUS_ACQUIRE_FOCUS)
type, io_direction, id, name, is_running ? "Running" : "Not running");
} else {
g_print("failed to get next device, ret[0x%x]\n", ret);
+ g_device = NULL;
}
reset_menu_state();
break;
default:
g_print("invalid argument, device_type(%d) is not valid for this feature\n", device_type);
reset_menu_state();
- break;
+ goto end;
}
if (!(ret = sound_manager_get_device_list(SOUND_DEVICE_ALL_MASK, &g_device_list))) {
g_print("success to get current device list\n");
default:
g_print("invalid argument, device_type(%d) is not valid for this feature\n", device_type);
reset_menu_state();
- break;
+ goto end;
}
if (!(ret = sound_manager_get_device_list(SOUND_DEVICE_ALL_MASK, &g_device_list))) {
g_print("success to get current device list\n");
default:
g_print("invalid argument, device_type(%d) is not valid for this feature\n", device_type);
reset_menu_state();
- break;
+ goto end;
}
if (!(ret = sound_manager_get_device_list(SOUND_DEVICE_ALL_MASK, &g_device_list))) {
g_print("success to get current device list\n");
default:
g_print("invalid argument, device_type(%d) is not valid for this feature\n", device_type);
reset_menu_state();
- break;
+ goto end;
}
if (!(ret = sound_manager_get_device_list(SOUND_DEVICE_ALL_MASK, &g_device_list))) {
g_print("success to get current device list\n");
default:
g_print("invalid argument, try again..\n");
reset_menu_state();
- break;
+ goto end;
}
ret = sound_manager_set_stream_routing_option(g_stream_info_h, name, value);
if (ret)
reset_menu_state();
break;
}
+ case CURRENT_STATUS_SET_STREAM_PREFERRED_DEVICE: {
+ int ret = SOUND_MANAGER_ERROR_NONE;
+ int selection = 0;
+ sound_device_io_direction_e direction;
+
+ selection = atoi(cmd);
+ switch (selection) {
+ case 0:
+ direction = SOUND_DEVICE_IO_DIRECTION_OUT;
+ break;
+ case 1:
+ direction = SOUND_DEVICE_IO_DIRECTION_IN;
+ break;
+ case 2:
+ direction = SOUND_DEVICE_IO_DIRECTION_BOTH;
+ break;
+ default:
+ g_print("invalid argument, try again..\n");
+ reset_menu_state();
+ goto end;
+ }
+
+ ret = sound_manager_set_stream_preferred_device(g_stream_info_h, direction, g_device);
+ if (ret)
+ g_print("failed to sound_manager_set_stream_preferred_device(), ret(0x%x)\n", ret);
+
+ reset_menu_state();
+ break;
+ }
+ case CURRENT_STATUS_GET_STREAM_PREFERRED_DEVICE: {
+ int ret = SOUND_MANAGER_ERROR_NONE;
+ int in_device_id = 0;
+ int out_device_id = 0;
+
+ ret = sound_manager_get_stream_preferred_device(g_stream_info_h, &in_device_id, &out_device_id);
+ if (ret) {
+ g_print("failed to sound_manager_get_stream_preferred_device(), ret(0x%x)\n", ret);
+ } else {
+ sound_device_list_h device_list;
+ sound_device_h device;
+ sound_device_type_e type;
+ int id;
+
+ if (in_device_id == SOUND_MANAGER_STREAM_NO_PREFERRED_DEVICE)
+ g_print("preferred [ IN] device was not set\n");
+ if (out_device_id == SOUND_MANAGER_STREAM_NO_PREFERRED_DEVICE)
+ g_print("preferred [OUT] device was not set\n");
+ if ((in_device_id == SOUND_MANAGER_STREAM_NO_PREFERRED_DEVICE) &&
+ (out_device_id == SOUND_MANAGER_STREAM_NO_PREFERRED_DEVICE)) {
+ reset_menu_state();
+ break;
+ }
+
+ sound_manager_get_device_list(SOUND_DEVICE_TYPE_INTERNAL_MASK, &device_list);
+ while (!sound_manager_get_next_device(device_list, &device)) {
+ if (!sound_manager_get_device_id(device, &id)) {
+ if (in_device_id && id == in_device_id) {
+ sound_manager_get_device_type(device, &type);
+ g_print("preferred [ IN] device type[%s], id[%d]\n", g_device_type_str[type], in_device_id);
+ }
+ if (out_device_id && id == out_device_id) {
+ sound_manager_get_device_type(device, &type);
+ g_print("preferred [OUT] device type[%s], id[%d]\n", g_device_type_str[type], out_device_id);
+ }
+ }
+ }
+ sound_manager_free_device_list(device_list);
+ }
+ reset_menu_state();
+ break;
+ }
case CURRENT_STATUS_ACQUIRE_FOCUS: {
int ret = SOUND_MANAGER_ERROR_NONE;
int focus_type = 0;
break;
}
}
+end:
g_timeout_add(100, timeout_menu_display, 0);
}