efl/src/lib/ecore_x/xcb/ecore_xcb_render.c

226 lines
6.2 KiB
C

#include "ecore_xcb_private.h"
#include <ctype.h> // for isupper/tolower
#ifdef ECORE_XCB_RENDER
# include <xcb/render.h>
# include <xcb/xcb_renderutil.h>
#endif
/* local function prototypes */
static Eina_Bool _ecore_xcb_render_parse_boolean(char *v);
/* local variables */
static Eina_Bool _render_avail = EINA_FALSE;
static Eina_Bool _render_argb = EINA_FALSE;
static Eina_Bool _render_anim = EINA_FALSE;
void
_ecore_xcb_render_init(void)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
#ifdef ECORE_XCB_RENDER
xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_render_id);
#endif
}
void
_ecore_xcb_render_finalize(void)
{
#ifdef ECORE_XCB_RENDER
const xcb_query_extension_reply_t *ext_reply;
#endif
LOGFN(__FILE__, __LINE__, __FUNCTION__);
#ifdef ECORE_XCB_RENDER
ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_render_id);
if ((ext_reply) && (ext_reply->present))
{
xcb_render_query_version_cookie_t cookie;
xcb_render_query_version_reply_t *reply;
cookie =
xcb_render_query_version_unchecked(_ecore_xcb_conn,
XCB_RENDER_MAJOR_VERSION,
XCB_RENDER_MINOR_VERSION);
reply = xcb_render_query_version_reply(_ecore_xcb_conn, cookie, NULL);
if (reply)
{
// if ((reply->major_version >= XCB_RENDER_MAJOR_VERSION) &&
if (reply->minor_version >= XCB_RENDER_MINOR_VERSION)
{
char *v = NULL;
_render_avail = EINA_TRUE;
_ecore_xcb_xdefaults_init();
if ((reply->major_version > 0) || (reply->minor_version >= 5))
{
_render_argb = EINA_TRUE;
v = getenv("XCURSOR_CORE");
if (!v)
v = _ecore_xcb_xdefaults_string_get("Xcursor", "core");
if ((v) && (_ecore_xcb_render_parse_boolean(v)))
_render_argb = EINA_FALSE;
}
if ((_render_argb) &&
((reply->major_version > 0) || (reply->minor_version >= 8)))
{
_render_anim = EINA_TRUE;
v = getenv("XCURSOR_ANIM");
if (!v)
v = _ecore_xcb_xdefaults_string_get("Xcursor", "anim");
if ((v) && (_ecore_xcb_render_parse_boolean(v)))
_render_anim = EINA_FALSE;
}
_ecore_xcb_xdefaults_shutdown();
}
}
free(reply);
}
#endif
}
Eina_Bool
_ecore_xcb_render_avail_get(void)
{
return _render_avail;
}
Eina_Bool
_ecore_xcb_render_argb_get(void)
{
return _render_argb;
}
Eina_Bool
_ecore_xcb_render_anim_get(void)
{
return _render_anim;
}
Eina_Bool
_ecore_xcb_render_visual_supports_alpha(Ecore_X_Visual visual)
{
Eina_Bool ret = EINA_FALSE;
#ifdef ECORE_XCB_RENDER
const xcb_render_query_pict_formats_reply_t *reply;
xcb_render_pictvisual_t *vis;
#endif
LOGFN(__FILE__, __LINE__, __FUNCTION__);
CHECK_XCB_CONN;
if (!visual) return EINA_FALSE;
if (!_render_avail) return EINA_FALSE;
#ifdef ECORE_XCB_RENDER
reply = xcb_render_util_query_formats(_ecore_xcb_conn);
if (!reply) return EINA_FALSE;
vis =
xcb_render_util_find_visual_format(reply,
((xcb_visualtype_t *)visual)->visual_id);
if (vis)
{
xcb_render_pictforminfo_t temp;
xcb_render_pictforminfo_t *format;
temp.id = vis->format;
format =
xcb_render_util_find_format(reply, XCB_PICT_FORMAT_ID, &temp, 0);
if ((format->type == XCB_RENDER_PICT_TYPE_DIRECT) &&
(format->direct.alpha_mask))
ret = EINA_TRUE;
}
#endif
return ret;
}
uint32_t
_ecore_xcb_render_find_visual_id(int type,
Eina_Bool check_alpha)
{
#ifdef ECORE_XCB_RENDER
const xcb_render_query_pict_formats_reply_t *reply;
xcb_render_pictvisual_t *visual = NULL;
xcb_render_pictscreen_iterator_t screens;
xcb_render_pictdepth_iterator_t depths;
xcb_render_pictvisual_iterator_t visuals;
#endif
LOGFN(__FILE__, __LINE__, __FUNCTION__);
CHECK_XCB_CONN;
if (!_render_avail) return 0;
#ifdef ECORE_XCB_RENDER
reply = xcb_render_util_query_formats(_ecore_xcb_conn);
if (!reply) return 0;
for (screens = xcb_render_query_pict_formats_screens_iterator(reply);
screens.rem; xcb_render_pictscreen_next(&screens))
{
for (depths = xcb_render_pictscreen_depths_iterator(screens.data);
depths.rem; xcb_render_pictdepth_next(&depths))
{
for (visuals = xcb_render_pictdepth_visuals_iterator(depths.data);
visuals.rem; xcb_render_pictvisual_next(&visuals))
{
xcb_render_pictforminfo_t temp;
xcb_render_pictforminfo_t *format;
visual = visuals.data;
temp.id = visual->format;
format =
xcb_render_util_find_format(reply, XCB_PICT_FORMAT_ID,
&temp, 0);
if (!format) continue;
if (format->type == type)
{
if (check_alpha)
{
if (format->direct.alpha_mask)
return visual->visual;
}
else
return visual->visual;
}
}
}
}
#endif
return 0;
}
/* local function prototypes */
static Eina_Bool
_ecore_xcb_render_parse_boolean(char *v)
{
char c;
c = *v;
if (isupper((int)c))
c = tolower(c);
if ((c == 't') || (c == 'y') || (c == '1'))
return EINA_TRUE;
if ((c == 'f') || (c == 'n') || (c == '0'))
return EINA_FALSE;
if (c == 'o')
{
char d;
d = v[1];
if (isupper((int)d))
d = tolower(d);
if (d == 'n') return EINA_TRUE;
if (d == 'f') return EINA_FALSE;
}
return EINA_FALSE;
}