#include "e.h"
-#ifdef HAVE_WAYLAND_CLIENTS
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
# include "e_comp_wl.h"
#endif
#ifndef HAVE_WAYLAND_ONLY
struct _E_Pixmap
{
unsigned int refcount;
+ unsigned int failures;
+
+ E_Client *client;
E_Pixmap_Type type;
+
uint64_t win;
- void *visual;
- void *image;
- Eina_List *images_cache;
- unsigned int cmap;
- int ibpp, ibpl;
Ecore_Window parent;
-#ifdef HAVE_WAYLAND_CLIENTS
- struct wl_resource *resource;
-#endif
+
+ int w, h;
+
#ifndef HAVE_WAYLAND_ONLY
+ void *image;
+ void *visual;
+ int ibpp, ibpl;
+ unsigned int cmap;
uint32_t pixmap;
+ Eina_List *images_cache;
#endif
- int w, h;
- E_Client *client;
- unsigned int failures;
+
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ struct wl_resource *resource;
+#endif
+
Eina_Bool usable : 1;
Eina_Bool dirty : 1;
Eina_Bool image_argb : 1;
-#ifdef HAVE_WAYLAND_CLIENTS
- Eina_Bool copy_image : 1;
-#endif
};
static void
cp->image_argb = EINA_FALSE;
switch (cp->type)
{
-#ifndef HAVE_WAYLAND_ONLY
case E_PIXMAP_TYPE_X:
+#ifndef HAVE_WAYLAND_ONLY
if (cp->pixmap)
{
ecore_x_pixmap_free(cp->pixmap);
ecore_x_e_comp_pixmap_set(cp->parent ?: cp->win, 0);
e_pixmap_image_clear(cp, cache);
}
- break;
#endif
-#ifdef HAVE_WAYLAND_CLIENTS
+ break;
case E_PIXMAP_TYPE_WL:
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
e_pixmap_image_clear(cp, cache);
- break;
#endif
+ break;
default: break;
}
}
#endif
break;
case E_PIXMAP_TYPE_WL:
-#ifdef HAVE_WAYLAND_CLIENTS
- if (!cp->copy_image) break;
- /* maybe delay image free here... */
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ /* NB: No-Op. Nothing to free. image data no longer memcpy'd */
#endif
break;
default:
#ifndef HAVE_WAYLAND_ONLY
Ecore_X_Window xwin;
#endif
-#ifdef HAVE_WAYLAND_CLIENTS
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
uint64_t id;
#endif
if (!pixmaps[type]) return NULL;
switch (type)
{
-#ifndef HAVE_WAYLAND_ONLY
case E_PIXMAP_TYPE_X:
+#ifndef HAVE_WAYLAND_ONLY
xwin = va_arg(*l, uint32_t);
return eina_hash_find(pixmaps[type], &xwin);
#endif
-#ifdef HAVE_WAYLAND_CLIENTS
+ break;
case E_PIXMAP_TYPE_WL:
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
id = va_arg(*l, uint64_t);
return eina_hash_find(pixmaps[type], &id);
#endif
+ break;
default: break;
}
return NULL;
}
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+static void
+_e_pixmap_update_wl(E_Pixmap *cp)
+{
+ if (!cp) return;
+ cp->w = cp->h = 0;
+ if (cp->resource)
+ {
+ struct wl_shm_buffer *buffer;
+ uint32_t format;
+
+ if (!(buffer = wl_shm_buffer_get(cp->resource))) return;
+
+ format = wl_shm_buffer_get_format(buffer);
+ switch (format)
+ {
+ /* TOOD: add more cases */
+ case WL_SHM_FORMAT_ARGB8888:
+ case WL_SHM_FORMAT_ARGB4444:
+ case WL_SHM_FORMAT_ABGR4444:
+ case WL_SHM_FORMAT_RGBA4444:
+ case WL_SHM_FORMAT_BGRA4444:
+ case WL_SHM_FORMAT_ARGB1555:
+ case WL_SHM_FORMAT_ABGR1555:
+ case WL_SHM_FORMAT_RGBA5551:
+ case WL_SHM_FORMAT_BGRA5551:
+ case WL_SHM_FORMAT_ABGR8888:
+ case WL_SHM_FORMAT_RGBA8888:
+ case WL_SHM_FORMAT_BGRA8888:
+ case WL_SHM_FORMAT_ARGB2101010:
+ case WL_SHM_FORMAT_ABGR2101010:
+ case WL_SHM_FORMAT_RGBA1010102:
+ case WL_SHM_FORMAT_BGRA1010102:
+ case WL_SHM_FORMAT_AYUV:
+ cp->image_argb = EINA_TRUE;
+ break;
+ default:
+ cp->image_argb = EINA_FALSE;
+ break;
+ }
+ cp->w = wl_shm_buffer_get_width(buffer);
+ cp->h = wl_shm_buffer_get_height(buffer);
+ }
+}
+#endif
+
EAPI int
e_pixmap_free(E_Pixmap *cp)
{
if (!cp) return 0;
if (--cp->refcount) return cp->refcount;
- e_pixmap_image_clear(cp, 0);
- switch (cp->type)
- {
- case E_PIXMAP_TYPE_X:
-#ifndef HAVE_WAYLAND_ONLY
- if (cp->parent) eina_hash_set(pixmaps[cp->type], &cp->parent, NULL);
-#endif
- break;
- case E_PIXMAP_TYPE_WL:
-#ifdef HAVE_WAYLAND_CLIENTS
- if (cp->parent) eina_hash_set(pixmaps[cp->type], &cp->parent, NULL);
-#endif
- break;
- }
+ e_pixmap_image_clear(cp, EINA_FALSE);
+ if (cp->parent) eina_hash_set(pixmaps[cp->type], &cp->parent, NULL);
eina_hash_del_by_key(pixmaps[cp->type], &cp->win);
return 0;
}
#ifndef HAVE_WAYLAND_ONLY
Ecore_X_Window xwin;
#endif
-#ifdef HAVE_WAYLAND_CLIENTS
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
uint64_t id;
#endif
#endif
break;
case E_PIXMAP_TYPE_WL:
-#ifdef HAVE_WAYLAND_CLIENTS
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
id = va_arg(l, uint64_t);
if (pixmaps[type])
{
{
EINA_SAFETY_ON_NULL_RETURN(cp);
if (cp->parent == win) return;
+
e_pixmap_usable_set(cp, 0);
e_pixmap_clear(cp);
+
if (cp->parent)
eina_hash_set(pixmaps[cp->type], &cp->parent, NULL);
cp->parent = win;
e_pixmap_visual_cmap_set(E_Pixmap *cp, void *visual, unsigned int cmap)
{
EINA_SAFETY_ON_NULL_RETURN(cp);
+ if (cp->type != E_PIXMAP_TYPE_X) return;
+#ifndef HAVE_WAYLAND_ONLY
cp->visual = visual;
cp->cmap = cmap;
+#endif
}
EAPI void *
e_pixmap_visual_get(const E_Pixmap *cp)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(cp, NULL);
+ if (cp->type != E_PIXMAP_TYPE_X) return NULL;
+#ifndef HAVE_WAYLAND_ONLY
return cp->visual;
+#endif
+ return NULL;
}
EAPI void
{
EINA_SAFETY_ON_NULL_RETURN(cp);
_e_pixmap_clear(cp, 0);
- e_pixmap_dirty(cp);
+ cp->dirty = EINA_TRUE;
}
+
EAPI void
e_pixmap_dirty(E_Pixmap *cp)
{
#endif
break;
case E_PIXMAP_TYPE_WL:
-#ifdef HAVE_WAYLAND_CLIENTS
- {
- E_Wayland_Surface *ews;
- E_Wayland_Buffer *buff;
- struct wl_shm_buffer *shm_buffer;
-
- ews = (E_Wayland_Surface*)cp->parent;
- buff = ews->buffer_reference.buffer;
-
- cp->resource = buff->wl.resource;
- shm_buffer = wl_shm_buffer_get(cp->resource);
- cp->w = wl_shm_buffer_get_width(shm_buffer);
- cp->h = wl_shm_buffer_get_height(shm_buffer);
- success = (cp->w > 0) && (cp->h > 0);
- }
-#endif
- break;
- default: break;
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ _e_pixmap_update_wl(cp);
+ success = ((cp->w > 0) && (cp->h > 0));
+#endif
+ break;
+ default:
+ break;
}
+
if (success)
{
cp->dirty = 0;
EAPI unsigned int
e_pixmap_failures_get(const E_Pixmap *cp)
{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(cp, 0);
return cp->failures;
}
EAPI void
e_pixmap_client_set(E_Pixmap *cp, E_Client *ec)
{
+ EINA_SAFETY_ON_NULL_RETURN(cp);
cp->client = ec;
}
+EAPI E_Client *
+e_pixmap_client_get(E_Pixmap *cp)
+{
+ if (!cp) return NULL;
+ return cp->client;
+}
+
EAPI E_Pixmap *
e_pixmap_find(E_Pixmap_Type type, ...)
{
EAPI void *
e_pixmap_resource_get(E_Pixmap *cp)
{
- EINA_SAFETY_ON_NULL_RETURN_VAL(cp, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(cp, NULL);
if (cp->type != E_PIXMAP_TYPE_WL)
- CRI("ACK!");
-#ifdef HAVE_WAYLAND_CLIENTS
+ {
+ CRI("ACK");
+ return NULL;
+ }
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
return cp->resource;
-#else
+#endif
return NULL;
+}
+
+EAPI void
+e_pixmap_resource_set(E_Pixmap *cp, void *resource)
+{
+ if ((!cp) || (cp->type != E_PIXMAP_TYPE_WL)) return;
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ cp->resource = resource;
#endif
}
EAPI Eina_Bool
e_pixmap_native_surface_init(E_Pixmap *cp, Evas_Native_Surface *ns)
{
+ Eina_Bool ret = EINA_FALSE;
+
EINA_SAFETY_ON_NULL_RETURN_VAL(cp, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(ns, EINA_FALSE);
ns->type = EVAS_NATIVE_SURFACE_X11;
ns->data.x11.visual = cp->visual;
ns->data.x11.pixmap = cp->pixmap;
+ ret = EINA_TRUE;
#endif
break;
case E_PIXMAP_TYPE_WL:
- return EINA_FALSE;
-#ifdef HAVE_WAYLAND_CLIENTS
-#warning FIXME WL NATIVE SURFACES!
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
ns->type = EVAS_NATIVE_SURFACE_OPENGL;
ns->version = EVAS_NATIVE_SURFACE_VERSION;
ns->data.opengl.texture_id = 0;
default:
break;
}
- return EINA_TRUE;
+
+ return ret;
}
EAPI void
{
EINA_SAFETY_ON_NULL_RETURN(cp);
- if ((!cache) && (!cp->image)) return;
+ if (!cache)
+ {
+#ifndef HAVE_WAYLAND_ONLY
+ if (!cp->image) return;
+#endif
+ }
+
cp->failures = 0;
switch (cp->type)
{
}
#endif
break;
- case E_PIXMAP_TYPE_WL: //lel wayland
-#ifdef HAVE_WAYLAND_CLIENTS
- if (cache)
- {
- if (cp->copy_image)
- {
- //INF("IMG FREE");
- E_FREE(cp->image);
- }
- else
- cp->image = NULL;
- cp->copy_image = 0;
- }
- else if (!cp->copy_image)
- {
- void *copy;
- size_t size;
-
- size = cp->w * cp->h * sizeof(int);
- copy = malloc(size);
- memcpy(copy, cp->image, size);
- cp->image = copy;
- cp->copy_image = 1;
- }
-#endif
+ case E_PIXMAP_TYPE_WL:
+ /* NB: Nothing to do here. No-Op */
break;
default:
break;
{
EINA_SAFETY_ON_NULL_RETURN_VAL(cp, EINA_FALSE);
+#ifndef HAVE_WAYLAND_ONLY
if (cp->image) return EINA_TRUE;
+#endif
if (cp->dirty)
{
CRI("BUG! PIXMAP %p IS DIRTY!", cp);
return EINA_FALSE;
}
+
switch (cp->type)
{
case E_PIXMAP_TYPE_X:
#endif
break;
case E_PIXMAP_TYPE_WL:
-#ifdef HAVE_WAYLAND_CLIENTS
- {
- struct wl_shm_buffer *shm_buffer;
-
- cp->image_argb = EINA_TRUE; //for now...
- //size = cp->w * cp->h * sizeof(int);
- shm_buffer = wl_shm_buffer_get(cp->resource);
- if (cp->w != wl_shm_buffer_get_width(shm_buffer))
- CRI("ACK!");
- if (cp->h != wl_shm_buffer_get_height(shm_buffer))
- CRI("ACK!");
- cp->image = wl_shm_buffer_get_data(shm_buffer);
- }
-#endif
- break;
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ _e_pixmap_update_wl(cp);
+ return ((cp->w > 0) && (cp->h > 0));
+#endif
+ break;
default:
break;
}
e_pixmap_image_exists(const E_Pixmap *cp)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(cp, EINA_FALSE);
+
+#ifndef HAVE_WAYLAND_ONLY
return !!cp->image;
+#endif
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ return (cp->resource != NULL);
+#endif
+
+ return EINA_FALSE;
}
EAPI Eina_Bool
e_pixmap_image_is_argb(const E_Pixmap *cp)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(cp, EINA_FALSE);
- return cp->image && cp->image_argb;
+
+ switch (cp->type)
+ {
+ case E_PIXMAP_TYPE_X:
+#ifndef HAVE_WAYLAND_ONLY
+ return cp->image && cp->image_argb;
+#endif
+ case E_PIXMAP_TYPE_WL:
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ return ((cp->resource != NULL) && (cp->image_argb));
+#endif
+ default: break;
+ }
+ return EINA_FALSE;
}
EAPI void *
e_pixmap_image_data_get(E_Pixmap *cp)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(cp, NULL);
- if (!cp->image) return NULL;
+
switch (cp->type)
{
case E_PIXMAP_TYPE_X:
#ifndef HAVE_WAYLAND_ONLY
- return ecore_x_image_data_get(cp->image, &cp->ibpl, NULL, &cp->ibpp);
+ if (cp->image)
+ return ecore_x_image_data_get(cp->image, &cp->ibpl, NULL, &cp->ibpp);
#endif
break;
case E_PIXMAP_TYPE_WL:
-#ifdef HAVE_WAYLAND_CLIENTS
- cp->copy_image = 0;
- return cp->image;
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ if (cp->resource)
+ {
+ struct wl_shm_buffer *buffer;
+ void *data = NULL;
+
+ if (!(buffer = wl_shm_buffer_get(cp->resource)))
+ return NULL;
+
+ wl_shm_buffer_begin_access(buffer);
+ data = wl_shm_buffer_get_data(buffer);
+ wl_shm_buffer_end_access(buffer);
+
+ return data;
+ }
#endif
break;
default:
e_pixmap_image_data_argb_convert(E_Pixmap *cp, void *pix, void *ipix, Eina_Rectangle *r, int stride)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(cp, EINA_FALSE);
- if (!cp->image) return EINA_FALSE;
+
switch (cp->type)
{
case E_PIXMAP_TYPE_X:
+ if (cp->image_argb) return EINA_TRUE;
#ifndef HAVE_WAYLAND_ONLY
- if (cp->image_argb) return EINA_FALSE;
return ecore_x_image_to_argb_convert(ipix, cp->ibpp, cp->ibpl,
cp->cmap, cp->visual,
r->x, r->y, r->w, r->h,
pix, stride, r->x, r->y);
#endif
+ break;
case E_PIXMAP_TYPE_WL:
- return EINA_TRUE; //already guaranteed to be argb
+ if (cp->image_argb) return EINA_TRUE;
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ WRN("FIXME: Convert wayland non-argb image");
+#endif
+ break;
default:
break;
}
e_pixmap_image_draw(E_Pixmap *cp, const Eina_Rectangle *r)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(cp, EINA_FALSE);
- if (!cp->image) return EINA_FALSE;
+
switch (cp->type)
{
case E_PIXMAP_TYPE_X:
#ifndef HAVE_WAYLAND_ONLY
- if (!cp->pixmap) return EINA_FALSE;
+ if ((!cp->image) || (!cp->pixmap)) return EINA_FALSE;
return ecore_x_image_get(cp->image, cp->pixmap, r->x, r->y, r->x, r->y, r->w, r->h);
#endif
+ break;
case E_PIXMAP_TYPE_WL:
return EINA_TRUE; //this call is a NOP
default: