forked from enlightenment/efl
ecore-wl2: Add caching of server displays and fix issue of client
connecting to same server pid Signed-off-by: Chris Michael <cp.michael@samsung.com>
This commit is contained in:
parent
ad5f93b521
commit
8196913b15
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "ecore_wl2_private.h"
|
#include "ecore_wl2_private.h"
|
||||||
|
|
||||||
|
static Eina_Hash *_server_displays = NULL;
|
||||||
static Eina_Hash *_client_displays = NULL;
|
static Eina_Hash *_client_displays = NULL;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -138,7 +139,7 @@ _cb_global_remove(void *data, struct wl_registry *registry EINA_UNUSED, unsigned
|
||||||
_cb_global_event_free, NULL);
|
_cb_global_event_free, NULL);
|
||||||
|
|
||||||
/* delete this global from our hash */
|
/* delete this global from our hash */
|
||||||
eina_hash_del_by_key(ewd->globals, &id);
|
if (ewd->globals) eina_hash_del_by_key(ewd->globals, &id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_registry_listener _registry_listener =
|
static const struct wl_registry_listener _registry_listener =
|
||||||
|
@ -318,7 +319,7 @@ _ecore_wl2_display_cleanup(Ecore_Wl2_Display *ewd)
|
||||||
if (ewd->name) free(ewd->name);
|
if (ewd->name) free(ewd->name);
|
||||||
|
|
||||||
/* remove this client display from hash */
|
/* remove this client display from hash */
|
||||||
eina_hash_del(_client_displays, ewd->name, ewd);
|
if (_client_displays) eina_hash_del(_client_displays, ewd->name, ewd);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ecore_Wl2_Window *
|
Ecore_Wl2_Window *
|
||||||
|
@ -343,11 +344,42 @@ ecore_wl2_display_create(const char *name)
|
||||||
{
|
{
|
||||||
Ecore_Wl2_Display *ewd;
|
Ecore_Wl2_Display *ewd;
|
||||||
struct wl_event_loop *loop;
|
struct wl_event_loop *loop;
|
||||||
|
const char *n;
|
||||||
|
|
||||||
|
if (!_server_displays)
|
||||||
|
_server_displays = eina_hash_string_superfast_new(NULL);
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
{
|
||||||
|
/* someone wants to create a new server */
|
||||||
|
n = getenv("WAYLAND_DISPLAY");
|
||||||
|
if (n)
|
||||||
|
{
|
||||||
|
/* we have a default wayland display */
|
||||||
|
|
||||||
|
/* check hash of cached server displays for this name */
|
||||||
|
ewd = eina_hash_find(_server_displays, n);
|
||||||
|
if (ewd) goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* someone wants to create a server with a specific display */
|
||||||
|
|
||||||
|
/* check hash of cached server displays for this name */
|
||||||
|
ewd = eina_hash_find(_server_displays, name);
|
||||||
|
if (ewd) goto found;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* allocate space for display structure */
|
/* allocate space for display structure */
|
||||||
ewd = calloc(1, sizeof(Ecore_Wl2_Display));
|
ewd = calloc(1, sizeof(Ecore_Wl2_Display));
|
||||||
if (!ewd) return NULL;
|
if (!ewd) return NULL;
|
||||||
|
|
||||||
|
ewd->refs++;
|
||||||
|
ewd->pid = getpid();
|
||||||
|
|
||||||
/* try to create new wayland display */
|
/* try to create new wayland display */
|
||||||
ewd->wl.display = wl_display_create();
|
ewd->wl.display = wl_display_create();
|
||||||
if (!ewd->wl.display)
|
if (!ewd->wl.display)
|
||||||
|
@ -391,6 +423,10 @@ ecore_wl2_display_create(const char *name)
|
||||||
|
|
||||||
ecore_main_fd_handler_prepare_callback_set(ewd->fd_hdl,
|
ecore_main_fd_handler_prepare_callback_set(ewd->fd_hdl,
|
||||||
_cb_create_prepare, ewd);
|
_cb_create_prepare, ewd);
|
||||||
|
|
||||||
|
/* add this new server display to hash */
|
||||||
|
eina_hash_add(_server_displays, ewd->name, ewd);
|
||||||
|
|
||||||
return ewd;
|
return ewd;
|
||||||
|
|
||||||
socket_err:
|
socket_err:
|
||||||
|
@ -399,12 +435,42 @@ socket_err:
|
||||||
create_err:
|
create_err:
|
||||||
free(ewd);
|
free(ewd);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
found:
|
||||||
|
ewd->refs++;
|
||||||
|
return ewd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_ecore_wl2_display_sync_get(void)
|
||||||
|
{
|
||||||
|
Ecore_Wl2_Display *sewd;
|
||||||
|
Eina_Iterator *itr;
|
||||||
|
Eina_Bool ret = EINA_TRUE;
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
if (eina_hash_population(_server_displays) < 1) return ret;
|
||||||
|
|
||||||
|
itr = eina_hash_iterator_data_new(_server_displays);
|
||||||
|
while (eina_iterator_next(itr, &data))
|
||||||
|
{
|
||||||
|
sewd = (Ecore_Wl2_Display *)data;
|
||||||
|
if (sewd->pid == getpid())
|
||||||
|
{
|
||||||
|
ret = EINA_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eina_iterator_free(itr);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI Ecore_Wl2_Display *
|
EAPI Ecore_Wl2_Display *
|
||||||
ecore_wl2_display_connect(const char *name)
|
ecore_wl2_display_connect(const char *name)
|
||||||
{
|
{
|
||||||
Ecore_Wl2_Display *ewd;
|
Ecore_Wl2_Display *ewd;
|
||||||
|
Eina_Bool sync = EINA_TRUE;
|
||||||
struct wl_callback *cb;
|
struct wl_callback *cb;
|
||||||
const char *n;
|
const char *n;
|
||||||
|
|
||||||
|
@ -466,6 +532,7 @@ ecore_wl2_display_connect(const char *name)
|
||||||
_cb_connect_data, ewd, NULL, NULL);
|
_cb_connect_data, ewd, NULL, NULL);
|
||||||
|
|
||||||
ewd->idle_enterer = ecore_idle_enterer_add(_cb_connect_idle, ewd);
|
ewd->idle_enterer = ecore_idle_enterer_add(_cb_connect_idle, ewd);
|
||||||
|
|
||||||
ewd->wl.registry = wl_display_get_registry(ewd->wl.display);
|
ewd->wl.registry = wl_display_get_registry(ewd->wl.display);
|
||||||
wl_registry_add_listener(ewd->wl.registry, &_registry_listener, ewd);
|
wl_registry_add_listener(ewd->wl.registry, &_registry_listener, ewd);
|
||||||
|
|
||||||
|
@ -475,15 +542,39 @@ ecore_wl2_display_connect(const char *name)
|
||||||
/* add this new client display to hash */
|
/* add this new client display to hash */
|
||||||
eina_hash_add(_client_displays, ewd->name, ewd);
|
eina_hash_add(_client_displays, ewd->name, ewd);
|
||||||
|
|
||||||
/* NB: If we are connecting (as a client), then we will need to setup
|
/* check server display hash and match on pid. If match, skip sync */
|
||||||
* a callback for display_sync and wait for it to complete. There is no
|
sync = _ecore_wl2_display_sync_get();
|
||||||
* other option here as we need the compositor, shell, etc, to be setup
|
|
||||||
* before we can allow a user to make use of the API functions we provide */
|
|
||||||
cb = wl_display_sync(ewd->wl.display);
|
cb = wl_display_sync(ewd->wl.display);
|
||||||
wl_callback_add_listener(cb, &_sync_listener, ewd);
|
wl_callback_add_listener(cb, &_sync_listener, ewd);
|
||||||
|
|
||||||
while (!ewd->sync_done)
|
if (sync)
|
||||||
wl_display_dispatch(ewd->wl.display);
|
{
|
||||||
|
/* NB: If we are connecting (as a client), then we will need to setup
|
||||||
|
* a callback for display_sync and wait for it to complete. There is no
|
||||||
|
* other option here as we need the compositor, shell, etc, to be setup
|
||||||
|
* before we can allow a user to make use of the API functions */
|
||||||
|
while (!ewd->sync_done)
|
||||||
|
wl_display_dispatch(ewd->wl.display);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* this client is on same pid as server so we need to iterate
|
||||||
|
* main loop until the "server" advertises it's globals
|
||||||
|
*
|
||||||
|
* NB: DO NOT REMOVE THIS !!
|
||||||
|
*
|
||||||
|
* This is NEEDED for E's internal dialogs to function because the
|
||||||
|
* "server" and "client" are on the same PID
|
||||||
|
* and thus the "server" never advertises out it's globals
|
||||||
|
* (wl_compositor, wl_shm, etc) unless we sit here and iterate the
|
||||||
|
* main loop until it's done.
|
||||||
|
*
|
||||||
|
* If we remove this, E will never show an internal dialog as it
|
||||||
|
* just sits and waits for the globals */
|
||||||
|
while (!ewd->sync_done)
|
||||||
|
ecore_main_loop_iterate();
|
||||||
|
}
|
||||||
|
|
||||||
return ewd;
|
return ewd;
|
||||||
|
|
||||||
|
@ -524,8 +615,11 @@ ecore_wl2_display_destroy(Ecore_Wl2_Display *display)
|
||||||
{
|
{
|
||||||
EINA_SAFETY_ON_NULL_RETURN(display);
|
EINA_SAFETY_ON_NULL_RETURN(display);
|
||||||
_ecore_wl2_display_cleanup(display);
|
_ecore_wl2_display_cleanup(display);
|
||||||
wl_display_destroy(display->wl.display);
|
if (display->refs <= 0)
|
||||||
free(display);
|
{
|
||||||
|
wl_display_destroy(display->wl.display);
|
||||||
|
free(display);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef _ECORE_WL2_PRIVATE_H
|
#ifndef _ECORE_WL2_PRIVATE_H
|
||||||
# define _ECORE_WL2_PRIVATE_H
|
# define _ECORE_WL2_PRIVATE_H
|
||||||
|
|
||||||
|
# include <unistd.h>
|
||||||
# include "Ecore_Wl2.h"
|
# include "Ecore_Wl2.h"
|
||||||
# include "Ecore_Input.h"
|
# include "Ecore_Input.h"
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ struct _Ecore_Wl2_Display
|
||||||
{
|
{
|
||||||
int refs;
|
int refs;
|
||||||
char *name;
|
char *name;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue