forked from enlightenment/efl
Add infrastructure to handle message between ecore and parent ecore in Ecore_Evas
I add new example related with this. (ecore_evas_extn_socket & plug example) ecore extn use this infrasturcture, server app and client app can communicate each other later, this can be used to contorl access message SVN revision: 83942
This commit is contained in:
parent
9885466787
commit
c5a8a6b5ff
|
@ -1,3 +1,7 @@
|
|||
2013-02-15 Jiyoun Park (jypark)
|
||||
|
||||
* Add infrastructure to handle message between ecore and parent ecore in Ecore_Evas.
|
||||
|
||||
2013-02-14 Cedric Bail
|
||||
|
||||
* Reduce memory consumption of Edje program handler.
|
||||
|
|
1
NEWS
1
NEWS
|
@ -63,6 +63,7 @@ Additions:
|
|||
* added eet_data_descriptor_name_get()
|
||||
* Add eio_eet_sync symbols.
|
||||
* Add infrastructure to handle buggy touchscreen in Ecore_Input_Evas.
|
||||
* Add infrastructure to handle message between ecore and parent ecore in Ecore_Evas.
|
||||
|
||||
Deprecations:
|
||||
* ecore_x:
|
||||
|
|
|
@ -43,6 +43,8 @@ ecore_con_url_headers_example \
|
|||
ecore_evas_basics_example \
|
||||
ecore_evas_buffer_example_01 \
|
||||
ecore_evas_buffer_example_02 \
|
||||
ecore_evas_extn_socket_example \
|
||||
ecore_evas_extn_plug_example \
|
||||
ecore_evas_callbacks \
|
||||
ecore_evas_ews_example \
|
||||
ecore_evas_object_example \
|
||||
|
@ -141,6 +143,12 @@ ecore_evas_buffer_example_01_LDADD = $(ECORE_EVAS_COMMON_LDADD)
|
|||
ecore_evas_buffer_example_02_SOURCES = ecore_evas_buffer_example_02.c
|
||||
ecore_evas_buffer_example_02_LDADD = $(ECORE_EVAS_COMMON_LDADD)
|
||||
|
||||
ecore_evas_extn_socket_example_SOURCES = ecore_evas_extn_socket_example.c
|
||||
ecore_evas_extn_socket_example_LDADD = $(ECORE_EVAS_COMMON_LDADD)
|
||||
|
||||
ecore_evas_extn_plug_example_SOURCES = ecore_evas_extn_plug_example.c
|
||||
ecore_evas_extn_plug_example_LDADD = $(ECORE_EVAS_COMMON_LDADD)
|
||||
|
||||
ecore_evas_callbacks_SOURCES = ecore_evas_callbacks.c
|
||||
ecore_evas_callbacks_LDADD = $(ECORE_EVAS_COMMON_LDADD)
|
||||
|
||||
|
@ -233,6 +241,8 @@ ecore_con_url_headers_example.c \
|
|||
ecore_evas_basics_example.c \
|
||||
ecore_evas_buffer_example_01.c \
|
||||
ecore_evas_buffer_example_02.c \
|
||||
ecore_evas_extn_socket_example.c \
|
||||
ecore_evas_extn_plug_example.c \
|
||||
ecore_evas_callbacks.c \
|
||||
ecore_evas_ews_example.c \
|
||||
ecore_evas_object_example.c \
|
||||
|
|
|
@ -682,6 +682,73 @@ EAPI void ecore_evas_window_available_profiles_set(Ecore_Evas *ee, const
|
|||
* @since 1.8.0
|
||||
*/
|
||||
EAPI Eina_Bool ecore_evas_window_available_profiles_get(Ecore_Evas *ee, char ***profiles, unsigned int *count);
|
||||
/**
|
||||
* @brief Send message to parent ecore
|
||||
*
|
||||
* @param ee The Ecore_Evas to set
|
||||
* @param msg_domain The domain of message
|
||||
* @param msg_id The id of message
|
||||
* @param data The data of message
|
||||
* @param size The size of message data
|
||||
*
|
||||
* @warning Support for this depends on the underlying windowing system.
|
||||
* @since 1.8.0
|
||||
*
|
||||
* @see ecore_evas_msg_send()
|
||||
* @see ecore_evas_callback_msg_parent_handle_set()
|
||||
* @see eecore_evas_callback_msg_handle_set()
|
||||
*
|
||||
* This is a list of examples of these functions:
|
||||
* @li @ref ecore_evas_extn_socket_example
|
||||
* @li @ref ecore_evas_extn_plug_example
|
||||
*/
|
||||
EAPI void ecore_evas_msg_parent_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size);
|
||||
/**
|
||||
* @brief Send message to child ecore
|
||||
*
|
||||
* @param ee The Ecore_Evas to set
|
||||
* @param msg_domain The domain of message
|
||||
* @param msg_id The id of message
|
||||
* @param data The data of message
|
||||
* @param size The size of message data
|
||||
*
|
||||
* @warning Support for this depends on the underlying windowing system.
|
||||
* @since 1.8.0
|
||||
*
|
||||
* @see ecore_evas_msg_parent_send()
|
||||
* @see ecore_evas_callback_msg_parent_handle_set()
|
||||
* @see eecore_evas_callback_msg_handle_set()
|
||||
*/
|
||||
EAPI void ecore_evas_msg_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size);
|
||||
/**
|
||||
* Set a callback for parent Ecore_Evas message.
|
||||
*
|
||||
* @param ee The Ecore_Evas to set callbacks on
|
||||
* @param func_parent_handle The handle to be called when message arive.
|
||||
*
|
||||
* @warning Support for this depends on the underlying windowing system.
|
||||
* @since 1.8.0
|
||||
*
|
||||
* @see ecore_evas_msg_parent_send()
|
||||
* @see ecore_evas_msg_send()
|
||||
* @see eecore_evas_callback_msg_handle_set()
|
||||
*/
|
||||
EAPI void ecore_evas_callback_msg_parent_handle_set(Ecore_Evas *ee, void (*func_parent_handle)(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size));
|
||||
/**
|
||||
* Set a callback for child Ecore_Evas message.
|
||||
*
|
||||
* @param ee The Ecore_Evas to set callbacks on
|
||||
* @param func_handle The handle to be called when message arive
|
||||
*
|
||||
* @warning Support for this depends on the underlying windowing system.
|
||||
* @since 1.8.0
|
||||
*
|
||||
* @see ecore_evas_msg_parent_send()
|
||||
* @see ecore_evas_msg_send()
|
||||
* @see ecore_evas_callback_msg_parent_handle_set()
|
||||
*/
|
||||
EAPI void ecore_evas_callback_msg_handle_set(Ecore_Evas *ee, void (*func_handle)(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size));
|
||||
|
||||
/**
|
||||
* @brief Move an Ecore_Evas.
|
||||
*
|
||||
|
|
|
@ -2191,6 +2191,61 @@ ecore_evas_manual_render(Ecore_Evas *ee)
|
|||
ee->engine.func->fn_render(ee);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_evas_msg_parent_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
|
||||
"ecore_evas_msg_parent_send");
|
||||
return;
|
||||
}
|
||||
DBG("Msg(to parent): ee=%p msg_domain=%d msg_id=%d size=%d", ee, msg_domain, msg_id, size);
|
||||
IFC(ee, fn_msg_parent_send) (ee, msg_domain, msg_id, data, size);
|
||||
IFE;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_evas_msg_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
|
||||
"ecore_evas_msg_send");
|
||||
return;
|
||||
}
|
||||
DBG("Msg: ee=%p msg_domain=%d msg_id=%d size=%d", ee, msg_domain, msg_id, size);
|
||||
IFC(ee, fn_msg_send) (ee, msg_domain, msg_id, data, size);
|
||||
IFE;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_evas_callback_msg_parent_handle_set(Ecore_Evas *ee, void (*func_parent_handle)(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size))
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
|
||||
"ecore_evas_msg_parent_handle");
|
||||
return;
|
||||
}
|
||||
DBG("Msg Parent handle: ee=%p", ee);
|
||||
ee->func.fn_msg_parent_handle = func_parent_handle;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_evas_callback_msg_handle_set(Ecore_Evas *ee, void (*func_handle)(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size))
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
|
||||
"ecore_evas_msg_handle");
|
||||
return;
|
||||
}
|
||||
DBG("Msg handle: ee=%p", ee);
|
||||
ee->func.fn_msg_handle = func_handle;
|
||||
}
|
||||
|
||||
|
||||
EAPI void
|
||||
ecore_evas_comp_sync_set(Ecore_Evas *ee, Eina_Bool do_sync)
|
||||
{
|
||||
|
|
|
@ -474,6 +474,42 @@ _ecore_evas_buffer_profile_set(Ecore_Evas *ee, const char *profile)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_evas_buffer_msg_parent_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)
|
||||
{
|
||||
Ecore_Evas *parent_ee = NULL;
|
||||
parent_ee = ecore_evas_data_get(ee, "parent");
|
||||
|
||||
if (parent_ee)
|
||||
{
|
||||
if (parent_ee->func.fn_msg_parent_handle)
|
||||
parent_ee ->func.fn_msg_parent_handle(parent_ee, msg_domain, msg_id, data, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ee->func.fn_msg_parent_handle)
|
||||
ee ->func.fn_msg_parent_handle(ee, msg_domain, msg_id, data, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_evas_buffer_msg_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)
|
||||
{
|
||||
Ecore_Evas *child_ee = NULL;
|
||||
child_ee = ecore_evas_data_get(ee, "child");
|
||||
|
||||
if (!child_ee)
|
||||
{
|
||||
if (child_ee->func.fn_msg_handle)
|
||||
child_ee->func.fn_msg_handle(child_ee, msg_domain, msg_id, data, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ee->func.fn_msg_handle)
|
||||
ee->func.fn_msg_handle(ee, msg_domain, msg_id, data, size);
|
||||
}
|
||||
}
|
||||
|
||||
static Ecore_Evas_Engine_Func _ecore_buffer_engine_func =
|
||||
{
|
||||
_ecore_evas_buffer_free,
|
||||
|
@ -534,7 +570,9 @@ static Ecore_Evas_Engine_Func _ecore_buffer_engine_func =
|
|||
|
||||
_ecore_evas_buffer_render,
|
||||
NULL, // screen_geometry_get
|
||||
NULL // screen_dpi_get
|
||||
NULL, // screen_dpi_get
|
||||
_ecore_evas_buffer_msg_parent_send,
|
||||
_ecore_evas_buffer_msg_send
|
||||
};
|
||||
|
||||
static void *
|
||||
|
|
|
@ -697,7 +697,9 @@ static const Ecore_Evas_Engine_Func _ecore_ews_engine_func =
|
|||
|
||||
_ecore_evas_ews_render,
|
||||
_ecore_evas_ews_screen_geometry_get,
|
||||
NULL // screen_dpi_get
|
||||
NULL, // screen_dpi_get
|
||||
NULL,
|
||||
NULL // msg_send
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -122,6 +122,8 @@ struct _Ecore_Evas_Engine_Func
|
|||
int (*fn_render) (Ecore_Evas *ee);
|
||||
void (*fn_screen_geometry_get) (const Ecore_Evas *ee, int *x, int *y, int *w, int *h);
|
||||
void (*fn_screen_dpi_get) (const Ecore_Evas *ee, int *xdpi, int *ydpi);
|
||||
void (*fn_msg_parent_send) (Ecore_Evas *ee, int maj, int min, void *data, int size);
|
||||
void (*fn_msg_send) (Ecore_Evas *ee, int maj, int min, void *data, int size);
|
||||
};
|
||||
|
||||
struct _Ecore_Evas_Interface
|
||||
|
@ -295,6 +297,8 @@ struct _Ecore_Evas
|
|||
void (*fn_post_render) (Ecore_Evas *ee);
|
||||
void (*fn_pre_free) (Ecore_Evas *ee);
|
||||
void (*fn_state_change) (Ecore_Evas *ee);
|
||||
void (*fn_msg_parent_handle) (Ecore_Evas *ee, int maj, int min, void *data, int size);
|
||||
void (*fn_msg_handle) (Ecore_Evas *ee, int maj, int min, void *data, int size);
|
||||
} func;
|
||||
|
||||
Ecore_Evas_Engine engine;
|
||||
|
|
|
@ -471,7 +471,9 @@ static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func =
|
|||
|
||||
NULL, // render
|
||||
NULL,
|
||||
NULL // screen_dpi_get
|
||||
NULL, // screen_dpi_get
|
||||
NULL,
|
||||
NULL // msg_send
|
||||
};
|
||||
|
||||
EAPI Ecore_Evas *
|
||||
|
|
|
@ -216,7 +216,9 @@ enum // opcodes
|
|||
OP_EV_KEY_UP,
|
||||
OP_EV_KEY_DOWN,
|
||||
OP_EV_HOLD,
|
||||
OP_LOCK_FILE2
|
||||
OP_LOCK_FILE2,
|
||||
OP_MSG_PARENT,
|
||||
OP_MSG
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -607,6 +609,7 @@ _ecore_evas_extn_free(Ecore_Evas *ee)
|
|||
Extn *extn;
|
||||
Ecore_Ipc_Client *client;
|
||||
Ecore_Evas_Engine_Buffer_Data *bdata = ee->engine.data;
|
||||
if (!bdata) return;
|
||||
|
||||
extn = bdata->data;
|
||||
if (extn)
|
||||
|
@ -675,14 +678,16 @@ _ecore_evas_extn_free(Ecore_Evas *ee)
|
|||
EVAS_CALLBACK_RENDER_POST,
|
||||
_ecore_evas_extn_plug_targer_render_post,
|
||||
ee);
|
||||
evas_object_del(bdata->image);
|
||||
ee2 = evas_object_data_get(bdata->image, "Ecore_Evas_Parent");
|
||||
if (ee2)
|
||||
{
|
||||
ee2->sub_ecore_evas = eina_list_remove(ee2->sub_ecore_evas, ee);
|
||||
}
|
||||
evas_object_del(bdata->image);
|
||||
bdata->image = NULL;
|
||||
}
|
||||
free(bdata);
|
||||
ee->engine.data = NULL;
|
||||
extn_ee_list = eina_list_remove(extn_ee_list, ee);
|
||||
}
|
||||
|
||||
|
@ -1282,6 +1287,21 @@ _ecore_evas_extn_plug_profile_set(Ecore_Evas *ee, const char *profile)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_evas_extn_plug_msg_parent_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)
|
||||
{
|
||||
Ecore_Evas_Engine_Buffer_Data *bdata = ee->engine.data;
|
||||
Extn *extn;
|
||||
|
||||
extn = bdata->data;
|
||||
if (!extn) return;
|
||||
if (!extn->ipc.server) return;
|
||||
|
||||
//ref = msg_domain
|
||||
//ref_to = msg_id
|
||||
ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_MSG, msg_domain, msg_id, 0, data, size);
|
||||
}
|
||||
|
||||
static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func =
|
||||
{
|
||||
_ecore_evas_extn_free,
|
||||
|
@ -1341,7 +1361,9 @@ static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func =
|
|||
|
||||
NULL, // render
|
||||
NULL, // screen_geometry_get
|
||||
NULL // screen_dpi_get
|
||||
NULL, // screen_dpi_get
|
||||
_ecore_evas_extn_plug_msg_parent_send,
|
||||
NULL // msg_send
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
|
@ -1529,6 +1551,18 @@ _ipc_server_data(void *data, int type EINA_UNUSED, void *event)
|
|||
/* profile change finished being sent - done now. */
|
||||
/* do something here */
|
||||
break;
|
||||
case OP_MSG_PARENT:
|
||||
if ((e->data) && (e->size > 0))
|
||||
{
|
||||
//ref = msg_domain
|
||||
//ref_to = msg_id
|
||||
if (ee->func.fn_msg_handle)
|
||||
{
|
||||
INF("Message handle: ref=%d to=%d size=%d", e->ref, e->ref_to, e->size);
|
||||
ee->func.fn_msg_handle(ee, e->ref, e->ref_to, e->data, e->size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2207,6 +2241,18 @@ _ipc_client_data(void *data, int type EINA_UNUSED, void *event)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case OP_MSG:
|
||||
if ((e->data) && (e->size > 0))
|
||||
{
|
||||
//ref = msg_domain
|
||||
//ref_to = msg_id
|
||||
if (ee->func.fn_msg_parent_handle)
|
||||
{
|
||||
INF("Message parent handle: ref=%d to=%d size=%d", e->ref, e->ref_to, e->size);
|
||||
ee->func.fn_msg_parent_handle(ee, e->ref, e->ref_to, e->data, e->size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2284,6 +2330,25 @@ _ecore_evas_extn_socket_available_profiles_set(Ecore_Evas *ee, const char **plis
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_evas_extn_socket_msg_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)
|
||||
{
|
||||
Ecore_Evas_Engine_Buffer_Data *bdata = ee->engine.data;
|
||||
Extn *extn;
|
||||
Eina_List *l;
|
||||
Ecore_Ipc_Client *client;
|
||||
|
||||
extn = bdata->data;
|
||||
if (extn)
|
||||
{
|
||||
EINA_LIST_FOREACH(extn->ipc.clients, l, client)
|
||||
ecore_ipc_client_send(client, MAJOR, OP_MSG_PARENT,
|
||||
msg_domain, msg_id, 0,
|
||||
data,
|
||||
size);
|
||||
}
|
||||
}
|
||||
|
||||
static const Ecore_Evas_Engine_Func _ecore_extn_socket_engine_func =
|
||||
{
|
||||
_ecore_evas_extn_free,
|
||||
|
@ -2345,6 +2410,8 @@ static const Ecore_Evas_Engine_Func _ecore_extn_socket_engine_func =
|
|||
_ecore_evas_extn_socket_render, // render
|
||||
NULL, // screen_geometry_get
|
||||
NULL, // screen_dpi_get
|
||||
NULL,
|
||||
_ecore_evas_extn_socket_msg_send
|
||||
};
|
||||
|
||||
EAPI Ecore_Evas *
|
||||
|
|
|
@ -559,7 +559,9 @@ static Ecore_Evas_Engine_Func _ecore_fb_engine_func =
|
|||
|
||||
NULL, // render
|
||||
NULL, // screen_geometry_get
|
||||
NULL // screen_dpi_get
|
||||
NULL, // screen_dpi_get
|
||||
NULL,
|
||||
NULL // msg_send
|
||||
};
|
||||
|
||||
EAPI Ecore_Evas *
|
||||
|
|
|
@ -404,7 +404,9 @@ static Ecore_Evas_Engine_Func _ecore_psl1ght_engine_func =
|
|||
|
||||
NULL, // render
|
||||
_ecore_evas_screen_geometry_get, // screen_geometry_get
|
||||
NULL // screen_dpi_get
|
||||
NULL, // screen_dpi_get
|
||||
NULL,
|
||||
NULL //msg_send
|
||||
};
|
||||
|
||||
EAPI Ecore_Evas *
|
||||
|
|
|
@ -445,7 +445,9 @@ static Ecore_Evas_Engine_Func _ecore_sdl_engine_func =
|
|||
|
||||
NULL, // render
|
||||
NULL, // screen_geometry_get
|
||||
NULL // screen_dpi_get
|
||||
NULL, // screen_dpi_get
|
||||
NULL,
|
||||
NULL // msg_send
|
||||
};
|
||||
|
||||
static Ecore_Evas*
|
||||
|
|
|
@ -74,7 +74,9 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
|
|||
NULL, // focus skip set
|
||||
_ecore_evas_wl_common_render,
|
||||
_ecore_evas_wl_common_screen_geometry_get,
|
||||
_ecore_evas_wl_common_screen_dpi_get
|
||||
_ecore_evas_wl_common_screen_dpi_get,
|
||||
NULL,
|
||||
NULL // msg_send
|
||||
};
|
||||
|
||||
/* external variables */
|
||||
|
|
|
@ -1152,7 +1152,9 @@ static Ecore_Evas_Engine_Func _ecore_win32_engine_func =
|
|||
|
||||
NULL, // render
|
||||
NULL, // screen_geometry_get
|
||||
_ecore_evas_win32_screen_dpi_get
|
||||
_ecore_evas_win32_screen_dpi_get,
|
||||
NULL,
|
||||
NULL // msg_send
|
||||
};
|
||||
|
||||
#endif /* BUILD_ECORE_EVAS_WIN32 */
|
||||
|
|
|
@ -991,6 +991,12 @@ _ecore_evas_x_event_client_message(void *data EINA_UNUSED, int type EINA_UNUSED,
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (e->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL)
|
||||
{
|
||||
///TODO after access structure determined
|
||||
// if (ee->func.fn_msg_handle)
|
||||
// ee->func.fn_msg_handle(ee, msg_domain, msg_id, data, size);
|
||||
}
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
|
@ -3050,7 +3056,9 @@ static Ecore_Evas_Engine_Func _ecore_x_engine_func =
|
|||
|
||||
NULL, // render
|
||||
_ecore_evas_x_screen_geometry_get,
|
||||
_ecore_evas_x_screen_dpi_get
|
||||
_ecore_evas_x_screen_dpi_get,
|
||||
NULL,
|
||||
NULL //fn_msg_send
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue