forked from enlightenment/efl
parent
6e63a2d07b
commit
1f3549a60b
|
@ -1,5 +1,7 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS = data src proj
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \
|
||||
|
@ -29,6 +31,6 @@ EXTRA_DIST = AUTHORS COPYING COPYING-PLAIN evas.c.in gendoc \
|
|||
debian/libevas0-dev.files \
|
||||
debian/libevas0.files \
|
||||
debian/rules
|
||||
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = evas.pc
|
||||
|
|
|
@ -5,6 +5,7 @@ AC_INIT(configure.in)
|
|||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
AC_ISC_POSIX
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_INIT_AUTOMAKE(evas, 0.9.9.023)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
|
@ -169,7 +170,6 @@ if test "x$have_evas_software_x11" = "xyes"; then
|
|||
AC_PATH_XTRA
|
||||
AC_CHECK_HEADER(X11/X.h,
|
||||
[
|
||||
AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_X11, true)
|
||||
AC_DEFINE(BUILD_ENGINE_SOFTWARE_X11, 1, [Software X11 Rendering Backend])
|
||||
x_dir=${x_dir:-/usr/X11R6}
|
||||
x_cflags=${x_cflags:--I${x_includes:-$x_dir/include}}
|
||||
|
@ -177,14 +177,12 @@ if test "x$have_evas_software_x11" = "xyes"; then
|
|||
ENGINE_SOFTWARE_X11_PRG="evas_software_x11_test evas_software_x11_perf_test evas_software_x11_perf_load"
|
||||
],
|
||||
[
|
||||
AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_X11, false)
|
||||
AC_MSG_RESULT(disabling software X11 engine)
|
||||
have_evas_software_x11="no"
|
||||
]
|
||||
)
|
||||
else
|
||||
AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_X11, false)
|
||||
fi
|
||||
AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_X11, test "x$have_evas_software_x11" = "yes")
|
||||
|
||||
#######################################
|
||||
## Check if we should build the software_xcb engine
|
||||
|
@ -223,17 +221,14 @@ if test "x$have_evas_software_xcb" = "xyes"; then
|
|||
PKG_CHECK_MODULES(
|
||||
XCB,
|
||||
xcb xcb-image xcb-icccm,
|
||||
[AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_XCB, true)
|
||||
AC_DEFINE(BUILD_ENGINE_SOFTWARE_XCB, 1, [Software XCB Rendering Backend])
|
||||
[AC_DEFINE(BUILD_ENGINE_SOFTWARE_XCB, 1, [Software XCB Rendering Backend])
|
||||
xcb_cflags=$XCB_CFLAGS
|
||||
xcb_libs=$XCB_LIBS
|
||||
ENGINE_SOFTWARE_XCB_PRG="evas_software_xcb_test evas_software_xcb_perf_test evas_software_xcb_perf_load"],
|
||||
[AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_XCB, false)
|
||||
AC_MSG_RESULT(disabling software XCB engine)
|
||||
[AC_MSG_RESULT(disabling software XCB engine)
|
||||
have_evas_software_xcb="no"])
|
||||
else
|
||||
AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_XCB, false)
|
||||
fi
|
||||
AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_XCB, test "x$have_evas_software_xcb" = "xyes")
|
||||
|
||||
#######################################
|
||||
## Check if we should build the directfb engine
|
||||
|
@ -263,18 +258,15 @@ AC_ARG_ENABLE(directfb, [ --enable-directfb enable the DirectFB r
|
|||
if test "x$have_evas_directfb" = "xyes"; then
|
||||
PKG_CHECK_MODULES(DIRECTFB, directfb >= 0.9.16,
|
||||
[
|
||||
AM_CONDITIONAL(BUILD_ENGINE_DIRECTFB, true)
|
||||
AC_DEFINE(BUILD_ENGINE_DIRECTFB, 1, [DirectFB Rendering Backend])
|
||||
ENGINE_DIRECTFB_PRG="evas_directfb_test evas_directfb_window"
|
||||
], [
|
||||
AM_CONDITIONAL(BUILD_ENGINE_DIRECTFB, false)
|
||||
AC_MSG_RESULT(disabling directfb engine)
|
||||
have_evas_directfb="no"
|
||||
]
|
||||
)
|
||||
else
|
||||
AM_CONDITIONAL(BUILD_ENGINE_DIRECTFB, false)
|
||||
fi
|
||||
AM_CONDITIONAL(BUILD_ENGINE_DIRECTFB, test "x$have_evas_directfb" = "xyes")
|
||||
|
||||
#######################################
|
||||
## Check if we should build the fb engine
|
||||
|
@ -552,7 +544,6 @@ if test "x$have_evas_xrender_x11" = "xyes"; then
|
|||
[
|
||||
AC_CHECK_HEADER(X11/extensions/Xrender.h,
|
||||
[
|
||||
AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, true)
|
||||
AC_DEFINE(BUILD_ENGINE_XRENDER_X11, 1, [XRender X11 Rendering Backend])
|
||||
x_dir=${x_dir:-/usr/X11R6}
|
||||
x_cflags=${x_cflags:--I${x_includes:-$x_dir/include}}
|
||||
|
@ -560,21 +551,64 @@ if test "x$have_evas_xrender_x11" = "xyes"; then
|
|||
ENGINE_XRENDER_X11_PRG="evas_xrender_x11_test"
|
||||
],
|
||||
[
|
||||
AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, false)
|
||||
AC_MSG_RESULT(disabling xrender X11 engine)
|
||||
have_evas_xrender_x11="no"
|
||||
]
|
||||
)
|
||||
],
|
||||
[
|
||||
AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, false)
|
||||
AC_MSG_RESULT(disabling xrender X11 engine)
|
||||
have_evas_xrender_x11="no"
|
||||
]
|
||||
)
|
||||
else
|
||||
AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, false)
|
||||
fi
|
||||
AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, test "x$have_evas_xrender_x11" = "xyes")
|
||||
|
||||
#######################################
|
||||
## Check if we should build the xrender_xcb engine
|
||||
have_evas_xrender_xcb="no";
|
||||
ENGINE_XRENDER_XCB_PRG="";
|
||||
|
||||
## Automatic check...
|
||||
PKG_CHECK_MODULES(
|
||||
XCB,
|
||||
xcb xcb-image xcb-icccm,
|
||||
[AC_CHECK_HEADER(
|
||||
X11/X.h,
|
||||
[have_evas_xrender_xcb="yes"],
|
||||
[have_evas_xrender_xcb="no"])],
|
||||
[ have_evas_xrender_xcb="no" ])
|
||||
|
||||
## manually disable xcb engine by default - not auto detected.
|
||||
have_evas_xrender_xcb="no"
|
||||
## Manual override
|
||||
AC_MSG_CHECKING(whether xrender xcb backend is to be built)
|
||||
AC_ARG_ENABLE(xrender-xcb, [ --enable-xrender-xcb enable the Xrender XCB rendering backend], [
|
||||
if test x"$enableval" = x"yes" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
have_evas_xrender_xcb="yes"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
have_evas_xrender_xcb="no"
|
||||
fi
|
||||
], [
|
||||
AC_MSG_RESULT($have_evas_xrender_xcb)
|
||||
]
|
||||
)
|
||||
if test "x$have_evas_xrender_xcb" = "xyes"; then
|
||||
AC_PATH_XTRA
|
||||
|
||||
PKG_CHECK_MODULES(
|
||||
XCB,
|
||||
xcb xcb-image xcb-icccm,
|
||||
[AC_DEFINE(BUILD_ENGINE_XRENDER_XCB, 1, [Xrender XCB Rendering Backend])
|
||||
xcb_cflags=$XCB_CFLAGS
|
||||
xcb_libs=$XCB_LIBS
|
||||
ENGINE_XRENDER_XCB_PRG="evas_xrender_xcb_test"],
|
||||
[AC_MSG_RESULT(disabling xrender XCB engine)
|
||||
have_evas_xrender_xcb="no"])
|
||||
fi
|
||||
AM_CONDITIONAL(BUILD_ENGINE_XRENDER_XCB, test "x$have_evas_xrender_xcb" = "xyes")
|
||||
|
||||
|
||||
#####################################################################
|
||||
|
@ -1616,6 +1650,7 @@ AC_SUBST(ENGINE_SOFTWARE_QTOPIA_PRG)
|
|||
AC_SUBST(ENGINE_GL_X11_PRG)
|
||||
AC_SUBST(ENGINE_CAIRO_X11_PRG)
|
||||
AC_SUBST(ENGINE_XRENDER_X11_PRG)
|
||||
AC_SUBST(ENGINE_XRENDER_XCB_PRG)
|
||||
|
||||
AC_SUBST(altivec_cflags)
|
||||
|
||||
|
@ -1651,6 +1686,7 @@ src/modules/engines/gl_x11/Makefile
|
|||
src/modules/engines/cairo_common/Makefile
|
||||
src/modules/engines/cairo_x11/Makefile
|
||||
src/modules/engines/xrender_x11/Makefile
|
||||
src/modules/engines/xrender_xcb/Makefile
|
||||
src/modules/loaders/Makefile
|
||||
src/modules/loaders/edb/Makefile
|
||||
src/modules/loaders/eet/Makefile
|
||||
|
@ -1698,6 +1734,7 @@ echo " DirectFB................: $have_evas_directfb"
|
|||
echo " OpenGL X11..............: $have_evas_gl_x11"
|
||||
echo " Cairo X11...............: $have_evas_cairo_x11"
|
||||
echo " XRender X11.............: $have_evas_xrender_x11"
|
||||
echo " XRender Xcb.............: $have_evas_xrender_xcb"
|
||||
# FIXME: opengl engine needs to be fixed and tested lots for all drivers
|
||||
# FIXME: xrender engine to be written
|
||||
echo
|
||||
|
|
|
@ -23,7 +23,8 @@ bin_PROGRAMS = \
|
|||
@ENGINE_SOFTWARE_QTOPIA_PRG@ \
|
||||
@ENGINE_GL_X11_PRG@ \
|
||||
@ENGINE_CAIRO_X11_PRG@ \
|
||||
@ENGINE_XRENDER_X11_PRG@
|
||||
@ENGINE_XRENDER_X11_PRG@ \
|
||||
@ENGINE_XRENDER_XCB_PRG@
|
||||
|
||||
EXTRA_PROGRAMS = \
|
||||
evas_software_x11_test \
|
||||
|
@ -39,7 +40,8 @@ evas_buffer_test \
|
|||
evas_software_qtopia_test \
|
||||
evas_gl_x11_test \
|
||||
evas_cairo_x11_test \
|
||||
evas_xrender_x11_test
|
||||
evas_xrender_x11_test \
|
||||
evas_xrender_xcb_test
|
||||
|
||||
SUBDIRS = evas_software_win32
|
||||
|
||||
|
@ -119,6 +121,11 @@ evas_xrender_x11_test_LDADD = $(top_builddir)/src/lib/libevas.la -lm @x_libs@
|
|||
evas_xrender_x11_test_CFLAGS = $(CFLAGS) @x_cflags@
|
||||
evas_xrender_x11_test_DEPENDENCIES = $(top_builddir)/src/lib/libevas.la
|
||||
|
||||
evas_xrender_xcb_test_SOURCES = evas_test_main.h evas_test_main.c evas_xrender_xcb_main.c
|
||||
evas_xrender_xcb_test_LDADD = $(top_builddir)/src/lib/libevas.la -lm @XCB_LIBS@
|
||||
evas_xrender_xcb_test_CFLAGS = $(CFLAGS) @XCB_CFLAGS@
|
||||
evas_xrender_xcb_test_DEPENDENCIES = $(top_builddir)/src/lib/libevas.la
|
||||
|
||||
EXTRA_DIST = evas_software_qtopia_main.h evas_software_qtopia_main.cpp
|
||||
# moc_evas_software_qtopia_main.cpp
|
||||
|
||||
|
|
|
@ -69,8 +69,8 @@ main(int argc, char **argv)
|
|||
{
|
||||
int pause_me = 0;
|
||||
XCBConnection *conn;
|
||||
XCBDRAWABLE win;
|
||||
XCBSCREEN *screen;
|
||||
XCBDRAWABLE win;
|
||||
XCBGenericEvent *e;
|
||||
CARD32 mask;
|
||||
CARD32 value[6];
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
#include "evas_test_main.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <X11/XCB/xcb.h>
|
||||
|
||||
#include "Evas.h"
|
||||
#include "Evas_Engine_XRender_Xcb.h"
|
||||
|
||||
|
||||
XCBSCREEN *
|
||||
get_screen (XCBConnection *c,
|
||||
int screen)
|
||||
{
|
||||
XCBSCREENIter iter;
|
||||
|
||||
iter = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c));
|
||||
for (; iter.rem; --screen, XCBSCREENNext (&iter))
|
||||
if (screen == 0)
|
||||
return iter.data;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
get_depth(XCBConnection *conn,
|
||||
XCBSCREEN *root)
|
||||
{
|
||||
XCBDRAWABLE drawable;
|
||||
XCBGetGeometryRep *geom;
|
||||
int depth;
|
||||
|
||||
drawable.window = root->root;
|
||||
geom = XCBGetGeometryReply (conn, XCBGetGeometry(conn, drawable), 0);
|
||||
|
||||
if(!geom)
|
||||
{
|
||||
perror ("GetGeometry(root) failed");
|
||||
exit (0);
|
||||
}
|
||||
|
||||
depth = geom->depth;
|
||||
free (geom);
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
static void title_set (XCBConnection *conn, XCBWINDOW window, const char *title)
|
||||
{
|
||||
XCBInternAtomRep *rep;
|
||||
XCBATOM encoding;
|
||||
char *atom_name;
|
||||
|
||||
/* encoding */
|
||||
atom_name = "UTF8_STRING";
|
||||
rep = XCBInternAtomReply (conn,
|
||||
XCBInternAtom (conn,
|
||||
0,
|
||||
strlen (atom_name),
|
||||
atom_name),
|
||||
NULL);
|
||||
encoding = rep->atom;
|
||||
free (rep);
|
||||
|
||||
/* ICCCM */
|
||||
/* SetWMName (f->xcb.c, f->xcb.draw.window, encoding, strlen (title), title); */
|
||||
|
||||
/* NETWM */
|
||||
atom_name = "_NET_WM_NAME";
|
||||
rep = XCBInternAtomReply (conn,
|
||||
XCBInternAtom (conn,
|
||||
0,
|
||||
strlen (atom_name),
|
||||
atom_name),
|
||||
NULL);
|
||||
XCBChangeProperty(conn, PropModeReplace,
|
||||
window,
|
||||
rep->atom, encoding, 8, strlen (title), title);
|
||||
free (rep);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int pause_me = 0;
|
||||
XCBConnection *conn;
|
||||
XCBSCREEN *screen;
|
||||
XCBDRAWABLE win;
|
||||
XCBGenericEvent *e;
|
||||
CARD32 mask;
|
||||
CARD32 value[6];
|
||||
int screen_nbr;
|
||||
|
||||
conn = XCBConnect (NULL, &screen_nbr);
|
||||
if (!conn)
|
||||
{
|
||||
printf("Error: cannot open a connection.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
screen = get_screen (conn, screen_nbr);
|
||||
|
||||
mask =
|
||||
XCBCWBackingStore | XCBCWColormap |
|
||||
XCBCWBackPixmap | XCBCWBorderPixel |
|
||||
XCBCWBitGravity | XCBCWEventMask;
|
||||
|
||||
value[0] = None;
|
||||
value[1] = 0;
|
||||
value[2] = ForgetGravity;
|
||||
value[3] = NotUseful;
|
||||
value[4] = ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask;
|
||||
value[5] = screen->default_colormap.xid;
|
||||
|
||||
win.window = XCBWINDOWNew(conn);
|
||||
XCBCreateWindow (conn,
|
||||
get_depth(conn, screen),
|
||||
win.window, screen->root,
|
||||
0, 0,
|
||||
win_w, win_h,
|
||||
0,
|
||||
InputOutput,
|
||||
screen->root_visual,
|
||||
mask, value);
|
||||
title_set (conn, win.window, "Evas XRender Xcb Test");
|
||||
#if 0
|
||||
szhints.flags = PMinSize | PMaxSize | PSize | USSize;
|
||||
szhints.min_width = szhints.max_width = win_w;
|
||||
szhints.min_height = szhints.max_height = win_h;
|
||||
XSetWMNormalHints(disp, win, &szhints);
|
||||
#endif
|
||||
XCBMapWindow (conn, win.window);
|
||||
XCBSync(conn, 0);
|
||||
|
||||
/* test evas_free.... :) */
|
||||
evas_init();
|
||||
evas = evas_new();
|
||||
evas_output_method_set(evas, evas_render_method_lookup("xrender_xcb"));
|
||||
evas_output_size_set(evas, win_w, win_h);
|
||||
evas_output_viewport_set(evas, 0, 0, win_w, win_h);
|
||||
{
|
||||
Evas_Engine_Info_XRender_Xcb *einfo;
|
||||
|
||||
einfo = (Evas_Engine_Info_XRender_Xcb *) evas_engine_info_get(evas);
|
||||
|
||||
/* the following is specific to the engine */
|
||||
einfo->info.conn = conn;
|
||||
einfo->info.visual = screen->root_visual;
|
||||
einfo->info.drawable = win;
|
||||
evas_engine_info_set(evas, (Evas_Engine_Info *) einfo);
|
||||
}
|
||||
setup();
|
||||
|
||||
orig_start_time = start_time = get_time();
|
||||
while (1)
|
||||
{
|
||||
e = XCBPollForEvent(conn, NULL);
|
||||
|
||||
if (e) {
|
||||
switch (e->response_type)
|
||||
{
|
||||
case XCBButtonPress: {
|
||||
XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e;
|
||||
|
||||
if (ev->detail.id == 3)
|
||||
{
|
||||
setdown();
|
||||
evas_free(evas);
|
||||
free(e);
|
||||
XCBDisconnect(conn);
|
||||
evas_shutdown();
|
||||
exit(0);
|
||||
|
||||
}
|
||||
#if 0
|
||||
if (!pause_me)
|
||||
pause_me = 1;
|
||||
else if (pause_me == 1)
|
||||
pause_me = 2;
|
||||
else
|
||||
pause_me = 1;
|
||||
#endif
|
||||
evas_event_feed_mouse_move(evas, ev->event_x, ev->event_y, 0, NULL);
|
||||
evas_event_feed_mouse_down(evas, ev->state, EVAS_BUTTON_NONE, 0, NULL);
|
||||
break;
|
||||
}
|
||||
case XCBButtonRelease: {
|
||||
XCBButtonReleaseEvent *ev = (XCBButtonReleaseEvent *)e;
|
||||
|
||||
evas_event_feed_mouse_move(evas, ev->event_x, ev->event_y, 0, NULL);
|
||||
evas_event_feed_mouse_up(evas, ev->state, EVAS_BUTTON_NONE, 0, NULL);
|
||||
break;
|
||||
}
|
||||
case XCBMotionNotify: {
|
||||
XCBMotionNotifyEvent *ev = (XCBMotionNotifyEvent *)e;
|
||||
|
||||
evas_event_feed_mouse_move(evas, ev->event_x, ev->event_y, 0, NULL);
|
||||
break;
|
||||
}
|
||||
case Expose: {
|
||||
XCBExposeEvent *ev = (XCBExposeEvent *)e;
|
||||
|
||||
evas_damage_rectangle_add(evas,
|
||||
ev->x,
|
||||
ev->y,
|
||||
ev->width,
|
||||
ev->height);
|
||||
break;
|
||||
}
|
||||
case ConfigureNotify: {
|
||||
XCBConfigureNotifyEvent *ev = (XCBConfigureNotifyEvent *)e;
|
||||
|
||||
evas_output_size_set(evas,
|
||||
ev->width,
|
||||
ev->height);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
free (e);
|
||||
}
|
||||
if (!(pause_me == 1))
|
||||
{
|
||||
loop();
|
||||
evas_render(evas);
|
||||
XCBFlush(conn);
|
||||
}
|
||||
if (pause_me == 2)
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
setdown();
|
||||
evas_free(evas);
|
||||
XCBDisconnect(conn);
|
||||
evas_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -690,6 +690,9 @@ evas_render_method_list(void)
|
|||
#ifdef BUILD_ENGINE_SOFTWARE_XCB
|
||||
methods = evas_list_append(methods, strdup("software_xcb"));
|
||||
#endif
|
||||
#ifdef BUILD_ENGINE_XRENDER_XCB
|
||||
methods = evas_list_append(methods, strdup("xrender_xcb"));
|
||||
#endif
|
||||
#ifdef BUILD_ENGINE_GL_X11
|
||||
methods = evas_list_append(methods, strdup("gl_x11"));
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,7 @@ evas_engine_api_software_win32_gdi.h \
|
|||
evas_engine_api_software_x11.h \
|
||||
evas_engine_api_software_xcb.h \
|
||||
evas_engine_api_xrender_x11.h \
|
||||
evas_engine_api_xrender_xcb.h \
|
||||
evas_gl_common.h \
|
||||
evas_macros.h \
|
||||
evas_mmx.h \
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef EVAS_ENGINE_XRENDER_XCB_H
|
||||
#define EVAS_ENGINE_XRENDER_XCB_H
|
||||
#include <X11/XCB/xcb.h>
|
||||
|
||||
extern Evas_Func evas_engine_xrender_xcb_func;
|
||||
|
||||
#endif
|
|
@ -13,7 +13,8 @@ software_qtopia \
|
|||
software_win32_gdi \
|
||||
software_x11 \
|
||||
software_xcb \
|
||||
xrender_x11
|
||||
xrender_x11 \
|
||||
xrender_xcb
|
||||
|
||||
# FIXME: these should go into engine subdirs so engines are much more fully
|
||||
# self-contained.
|
||||
|
@ -41,7 +42,17 @@ else
|
|||
ENGINE_CAIRO_X11_INC =
|
||||
endif
|
||||
|
||||
if BUILD_ENGINE_XRENDER_XCB
|
||||
ENGINE_XRENDER_XCB = engines/xrender_xcb/libevas_engine_xrender_xcb.la
|
||||
ENGINE_XRENDER_XCB_INC = Evas_Engine_XRender_Xcb.h
|
||||
else
|
||||
ENGINE_XRENDER_XCB =
|
||||
ENGINE_XRENDER_XCB_INC =
|
||||
endif
|
||||
|
||||
|
||||
include_HEADERS = \
|
||||
$(ENGINE_DIRECTFB_INC) \
|
||||
$(ENGINE_GL_X11_INC) \
|
||||
$(ENGINE_XRENDER_XCB_INC)
|
||||
$(ENGINE_CAIRO_X11_INC)
|
||||
|
|
|
@ -83,7 +83,7 @@ X_Output_Buffer *
|
|||
evas_software_x11_x_output_buffer_new(Display *d, Visual *v, int depth, int w, int h, int try_shm, void *data)
|
||||
{
|
||||
X_Output_Buffer *xob;
|
||||
|
||||
char *tmp = (char *)malloc (2);
|
||||
xob = calloc(1, sizeof(X_Output_Buffer));
|
||||
if (!xob) return NULL;
|
||||
|
||||
|
|
|
@ -766,7 +766,7 @@ Evas_Module_Api evas_modapi =
|
|||
{
|
||||
EVAS_MODULE_API_VERSION,
|
||||
EVAS_MODULE_TYPE_ENGINE,
|
||||
"xrender",
|
||||
"xrender_x11",
|
||||
"none"
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.4 foreign
|
||||
|
||||
# A list of all the files in the current directory which can be regenerated
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
INCLUDES = -I. \
|
||||
-I$(top_srcdir)/src/lib \
|
||||
-I$(top_srcdir)/src/lib/include \
|
||||
-I$(top_srcdir)/src/modules/engines \
|
||||
@FREETYPE_CFLAGS@ @XCB_CFLAGS@
|
||||
|
||||
if BUILD_ENGINE_XRENDER_XCB
|
||||
|
||||
pkgdir = $(libdir)/evas/modules/engines/xrender_xcb/$(MODULE_ARCH)
|
||||
|
||||
pkg_LTLIBRARIES = module.la
|
||||
|
||||
module_la_SOURCES = \
|
||||
evas_engine.h \
|
||||
evas_engine.c \
|
||||
evas_engine_xrender.c \
|
||||
evas_engine_image.c \
|
||||
evas_engine_font.c \
|
||||
evas_engine_gradient.c \
|
||||
evas_engine_ximage.c
|
||||
|
||||
module_la_LIBADD = $(top_builddir)/src/lib/libevas.la @XCB_LIBS@
|
||||
module_la_LDFLAGS = -module -avoid-version \
|
||||
-L$(top_builddir)/src/lib -L$(top_builddir)/src/lib/.libs
|
||||
|
||||
module_la_DEPENDENCIES = \
|
||||
$(top_builddir)/config.h
|
||||
|
||||
endif
|
||||
|
||||
EXTRA_DIST = \
|
||||
evas_engine.h \
|
||||
evas_engine.c \
|
||||
evas_engine_ximage.c \
|
||||
evas_engine_xrender.c \
|
||||
evas_engine_image.c \
|
||||
evas_engine_font.c \
|
||||
evas_engine_gradient.c
|
|
@ -0,0 +1,779 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_private.h"
|
||||
#include "evas_engine.h"
|
||||
#include "Evas_Engine_XRender_Xcb.h"
|
||||
|
||||
/* function tables - filled in later (func and parent func) */
|
||||
static Evas_Func func, pfunc;
|
||||
|
||||
/* engine struct data */
|
||||
typedef struct _Render_Engine Render_Engine;
|
||||
typedef struct _Render_Engine_Update Render_Engine_Update;
|
||||
|
||||
struct _Render_Engine_Update
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
XCBrender_Surface *surface;
|
||||
};
|
||||
|
||||
struct _Render_Engine
|
||||
{
|
||||
XCBConnection *conn;
|
||||
XCBVISUALID vis;
|
||||
XCBDRAWABLE win;
|
||||
XCBPIXMAP mask;
|
||||
unsigned char destination_alpha : 1;
|
||||
|
||||
XCBimage_Info *xcbinf;
|
||||
XCBrender_Surface *output;
|
||||
XCBrender_Surface *mask_output;
|
||||
|
||||
Tilebuf *tb;
|
||||
Tilebuf_Rect *rects;
|
||||
Evas_Object_List *cur_rect;
|
||||
int end : 1;
|
||||
|
||||
Evas_List *updates;
|
||||
};
|
||||
|
||||
/* prototypes we will use here */
|
||||
static void *eng_info(Evas *e);
|
||||
static void eng_info_free(Evas *e, void *info);
|
||||
static void eng_setup(Evas *e, void *info);
|
||||
static void eng_output_free(void *data);
|
||||
static void eng_output_resize(void *data, int w, int h);
|
||||
static void eng_output_tile_size_set(void *data, int w, int h);
|
||||
static void eng_output_redraws_rect_add(void *data, int x, int y, int w, int h);
|
||||
static void eng_output_redraws_rect_del(void *data, int x, int y, int w, int h);
|
||||
static void eng_output_redraws_clear(void *data);
|
||||
static void *eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch);
|
||||
static void eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h);
|
||||
static void eng_output_flush(void *data);
|
||||
static void eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h);
|
||||
static void eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2);
|
||||
static void eng_polygon_draw(void *data, void *context, void *surface, void *polygon);
|
||||
static void *eng_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance);
|
||||
static void *eng_gradient_colors_clear(void *data, void *context, void *gradient);
|
||||
static void eng_gradient_free(void *data, void *gradient);
|
||||
static void eng_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h);
|
||||
static void eng_gradient_type_set(void *data, void *gradient, char *name);
|
||||
static void eng_gradient_type_params_set(void *data, void *gradient, char *params);
|
||||
static void *eng_gradient_geometry_init(void *data, void *gradient, int spread);
|
||||
static int eng_gradient_alpha_get(void *data, void *gradient, int spread);
|
||||
static void eng_gradient_map(void *data, void *context, void *gradient, int spread);
|
||||
static void eng_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread);
|
||||
static void *eng_image_load(void *data, char *file, char *key, int *error);
|
||||
static void *eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data);
|
||||
static void *eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data);
|
||||
static void eng_image_free(void *data, void *image);
|
||||
static void eng_image_size_get(void *data, void *image, int *w, int *h);
|
||||
static void *eng_image_size_set(void *data, void *image, int w, int h);
|
||||
static void *eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h);
|
||||
static void *eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data);
|
||||
static void *eng_image_data_put(void *data, void *image, DATA32 *image_data);
|
||||
static void *eng_image_alpha_set(void *data, void *image, int has_alpha);
|
||||
static int eng_image_alpha_get(void *data, void *image);
|
||||
static void eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth);
|
||||
static char *eng_image_comment_get(void *data, void *image, char *key);
|
||||
static char *eng_image_format_get(void *data, void *image);
|
||||
static void eng_image_cache_flush(void *data);
|
||||
static void eng_image_cache_set(void *data, int bytes);
|
||||
static int eng_image_cache_get(void *data);
|
||||
static void eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, char *text);
|
||||
|
||||
/* internal engine routines */
|
||||
|
||||
/* engine api this module provides */
|
||||
|
||||
static void *
|
||||
eng_info(Evas *e)
|
||||
{
|
||||
Evas_Engine_Info_XRender_Xcb *info;
|
||||
|
||||
info = calloc(1, sizeof(Evas_Engine_Info_XRender_Xcb));
|
||||
if (!info) return NULL;
|
||||
info->magic.magic = rand();
|
||||
return info;
|
||||
e = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
eng_info_free(Evas *e, void *info)
|
||||
{
|
||||
Evas_Engine_Info_XRender_Xcb *in;
|
||||
|
||||
in = (Evas_Engine_Info_XRender_Xcb *)info;
|
||||
free(in);
|
||||
}
|
||||
static void
|
||||
eng_setup(Evas *e, void *in)
|
||||
{
|
||||
Render_Engine *re;
|
||||
Evas_Engine_Info_XRender_Xcb *info;
|
||||
|
||||
info = (Evas_Engine_Info_XRender_Xcb *)in;
|
||||
if (!e->engine.data.output)
|
||||
{
|
||||
re = calloc(1, sizeof(Render_Engine));
|
||||
evas_common_cpu_init();
|
||||
evas_common_blend_init();
|
||||
evas_common_image_init();
|
||||
evas_common_convert_init();
|
||||
evas_common_scale_init();
|
||||
evas_common_rectangle_init();
|
||||
evas_common_gradient_init();
|
||||
evas_common_polygon_init();
|
||||
evas_common_line_init();
|
||||
evas_common_font_init();
|
||||
evas_common_draw_init();
|
||||
evas_common_tilebuf_init();
|
||||
re->tb = evas_common_tilebuf_new(e->output.w, e->output.h);
|
||||
if (re->tb)
|
||||
evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
|
||||
e->engine.data.output = re;
|
||||
}
|
||||
re = e->engine.data.output;
|
||||
if (!re) return;
|
||||
|
||||
if (!e->engine.data.context) e->engine.data.context = e->engine.func->context_new(e->engine.data.output);
|
||||
|
||||
re->conn = info->info.conn;
|
||||
re->vis = info->info.visual;
|
||||
re->win = info->info.drawable;
|
||||
re->mask = info->info.mask;
|
||||
re->destination_alpha = info->info.destination_alpha;
|
||||
|
||||
if (re->xcbinf) _xr_image_info_free(re->xcbinf);
|
||||
re->xcbinf = _xr_image_info_get(re->conn, re->win, re->vis);
|
||||
|
||||
if (re->output) _xr_render_surface_free(re->output);
|
||||
re->output = _xr_render_surface_adopt(re->xcbinf, re->win, e->output.w, e->output.h, 0);
|
||||
if (re->mask.xid)
|
||||
{
|
||||
XCBDRAWABLE draw;
|
||||
|
||||
if (re->mask_output) _xr_render_surface_free(re->mask_output);
|
||||
draw.pixmap = re->mask;
|
||||
re->mask_output = _xr_render_surface_format_adopt(re->xcbinf, draw,
|
||||
e->output.w, e->output.h,
|
||||
re->xcbinf->fmt1, 1);
|
||||
}
|
||||
else
|
||||
re->mask_output = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
eng_output_free(void *data)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
evas_common_font_shutdown();
|
||||
evas_common_image_shutdown();
|
||||
while (re->updates)
|
||||
{
|
||||
Render_Engine_Update *reu;
|
||||
|
||||
reu = re->updates->data;
|
||||
re->updates = evas_list_remove_list(re->updates, re->updates);
|
||||
_xr_render_surface_free(reu->surface);
|
||||
free(reu);
|
||||
}
|
||||
if (re->tb) evas_common_tilebuf_free(re->tb);
|
||||
if (re->output) _xr_render_surface_free(re->output);
|
||||
if (re->mask_output) _xr_render_surface_free(re->mask_output);
|
||||
if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
|
||||
if (re->xcbinf) _xr_image_info_free(re->xcbinf);
|
||||
free(re);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_output_resize(void *data, int w, int h)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
if (re->output)
|
||||
{
|
||||
if ((re->output->w == w) && (re->output->h ==h)) return;
|
||||
if (re->output) _xr_render_surface_free(re->output);
|
||||
}
|
||||
re->output = _xr_render_surface_adopt(re->xcbinf, re->win, w, h, 0);
|
||||
if (re->mask_output)
|
||||
{
|
||||
XCBDRAWABLE draw;
|
||||
|
||||
if (re->mask_output) _xr_render_surface_free(re->mask_output);
|
||||
draw.pixmap = re->mask;
|
||||
re->mask_output = _xr_render_surface_format_adopt(re->xcbinf, draw,
|
||||
w, h,
|
||||
re->xcbinf->fmt1, 1);
|
||||
}
|
||||
evas_common_tilebuf_free(re->tb);
|
||||
re->tb = evas_common_tilebuf_new(w, h);
|
||||
if (re->tb) evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_output_tile_size_set(void *data, int w, int h)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
evas_common_tilebuf_set_tile_size(re->tb, w, h);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_output_redraws_clear(void *data)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
evas_common_tilebuf_clear(re->tb);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
|
||||
{
|
||||
Render_Engine *re;
|
||||
Tilebuf_Rect *rect;
|
||||
int ux, uy, uw, uh;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
if (re->end)
|
||||
{
|
||||
re->end = 0;
|
||||
return NULL;
|
||||
}
|
||||
if (!re->rects)
|
||||
{
|
||||
re->rects = evas_common_tilebuf_get_render_rects(re->tb);
|
||||
re->cur_rect = (Evas_Object_List *)re->rects;
|
||||
}
|
||||
if (!re->cur_rect) return NULL;
|
||||
rect = (Tilebuf_Rect *)re->cur_rect;
|
||||
ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h;
|
||||
re->cur_rect = re->cur_rect->next;
|
||||
if (!re->cur_rect)
|
||||
{
|
||||
evas_common_tilebuf_free_render_rects(re->rects);
|
||||
re->rects = NULL;
|
||||
re->end = 1;
|
||||
}
|
||||
|
||||
*x = ux; *y = uy; *w = uw; *h = uh;
|
||||
*cx = 0; *cy = 0; *cw = uw; *ch = uh;
|
||||
if ((re->destination_alpha) || (re->mask.xid))
|
||||
{
|
||||
XCBrender_Surface *surface;
|
||||
|
||||
surface = _xr_render_surface_new(re->xcbinf, uw, uh, re->xcbinf->fmt32, 1);
|
||||
_xr_render_surface_solid_rectangle_set(surface, 0, 0, 0, 0, 0, 0, uw, uh);
|
||||
return surface;
|
||||
}
|
||||
return _xr_render_surface_new(re->xcbinf, uw, uh, re->xcbinf->fmt24, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
|
||||
{
|
||||
Render_Engine *re;
|
||||
Render_Engine_Update *reu;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
reu = malloc(sizeof(Render_Engine_Update));
|
||||
if (!reu) return;
|
||||
reu->x = x;
|
||||
reu->y = y;
|
||||
reu->w = w;
|
||||
reu->h = h;
|
||||
reu->surface = (XCBrender_Surface *)surface;
|
||||
re->updates = evas_list_append(re->updates, reu);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_output_flush(void *data)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
while (re->updates)
|
||||
{
|
||||
Render_Engine_Update *reu;
|
||||
|
||||
reu = re->updates->data;
|
||||
re->updates = evas_list_remove_list(re->updates, re->updates);
|
||||
if (re->mask_output)
|
||||
{
|
||||
XCBrender_Surface *tsurf;
|
||||
|
||||
_xr_render_surface_copy(reu->surface, re->output, 0, 0,
|
||||
reu->x, reu->y, reu->w, reu->h);
|
||||
tsurf = _xr_render_surface_new(re->xcbinf, reu->w, reu->h, re->xcbinf->fmt1, 1);
|
||||
if (tsurf)
|
||||
{
|
||||
_xr_render_surface_copy(reu->surface, tsurf, 0, 0,
|
||||
0, 0, reu->w, reu->h);
|
||||
_xr_render_surface_copy(tsurf, re->mask_output, 0, 0,
|
||||
reu->x, reu->y, reu->w, reu->h);
|
||||
_xr_render_surface_free(tsurf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_xr_render_surface_copy(reu->surface, re->output, 0, 0,
|
||||
reu->x, reu->y, reu->w, reu->h);
|
||||
}
|
||||
_xr_render_surface_free(reu->surface);
|
||||
free(reu);
|
||||
}
|
||||
XCBSync(re->conn, 0);
|
||||
_xr_image_info_pool_flush(re->xcbinf, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h)
|
||||
{
|
||||
_xr_render_surface_rectangle_draw((XCBrender_Surface *)surface,
|
||||
(RGBA_Draw_Context *)context,
|
||||
x, y, w, h);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
_xr_render_surface_line_draw((XCBrender_Surface *)surface, (RGBA_Draw_Context *)context, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_polygon_draw(void *data, void *context, void *surface, void *polygon)
|
||||
{
|
||||
_xre_poly_draw((XCBrender_Surface *)surface, (RGBA_Draw_Context *)context, (RGBA_Polygon_Point *)polygon);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
return _xre_gradient_color_add(re->xcbinf, (XR_Gradient *)gradient, r, g, b, a, distance);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_gradient_colors_clear(void *data, void *context, void *gradient)
|
||||
{
|
||||
return _xre_gradient_colors_clear((XR_Gradient *)gradient);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_gradient_free(void *data, void *gradient)
|
||||
{
|
||||
_xre_gradient_free((XR_Gradient *)gradient);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h)
|
||||
{
|
||||
_xre_gradient_fill_set((XR_Gradient *)gradient, x, y, w, h);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_gradient_type_set(void *data, void *gradient, char *name)
|
||||
{
|
||||
_xre_gradient_type_set((XR_Gradient *)gradient, name);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_gradient_type_params_set(void *data, void *gradient, char *params)
|
||||
{
|
||||
_xre_gradient_type_params_set((XR_Gradient *)gradient, params);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_gradient_geometry_init(void *data, void *gradient, int spread)
|
||||
{
|
||||
return _xre_gradient_geometry_init((XR_Gradient *)gradient, spread);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_gradient_alpha_get(void *data, void *gradient, int spread)
|
||||
{
|
||||
return _xre_gradient_alpha_get((XR_Gradient *)gradient, spread);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_gradient_map(void *data, void *context, void *gradient, int spread)
|
||||
{
|
||||
_xre_gradient_map((RGBA_Draw_Context *)context, (XR_Gradient *)gradient, spread);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread)
|
||||
{
|
||||
_xre_gradient_draw((XCBrender_Surface *)surface,
|
||||
(RGBA_Draw_Context *)context,
|
||||
(XR_Gradient *)gradient, x, y, w, h, angle, spread);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_image_load(void *data, char *file, char *key, int *error)
|
||||
{
|
||||
Render_Engine *re;
|
||||
XR_Image *im;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
*error = 0;
|
||||
im = _xre_image_load(re->xcbinf, file, key);
|
||||
return im;
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data)
|
||||
{
|
||||
Render_Engine *re;
|
||||
XR_Image *im;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
im = _xre_image_new_from_data(re->xcbinf, w, h, image_data);
|
||||
return im;
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data)
|
||||
{
|
||||
Render_Engine *re;
|
||||
XR_Image *im;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
im = _xre_image_new_from_copied_data(re->xcbinf, w, h, image_data);
|
||||
return im;
|
||||
}
|
||||
|
||||
static void
|
||||
eng_image_free(void *data, void *image)
|
||||
{
|
||||
if (!image) return;
|
||||
_xre_image_free((XR_Image *)image);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_image_size_get(void *data, void *image, int *w, int *h)
|
||||
{
|
||||
if (!image) return;
|
||||
if (w) *w = ((XR_Image *)image)->w;
|
||||
if (h) *h = ((XR_Image *)image)->h;
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_image_size_set(void *data, void *image, int w, int h)
|
||||
{
|
||||
if (!image) return image;
|
||||
if ((w <= 0) || (h <= 0))
|
||||
{
|
||||
_xre_image_free((XR_Image *)image);
|
||||
return NULL;
|
||||
}
|
||||
if (((XR_Image *)image)->references > 1)
|
||||
{
|
||||
XR_Image *old_image;
|
||||
|
||||
old_image = (XR_Image *)image;
|
||||
image = _xre_image_copy((XR_Image *)old_image);
|
||||
if (image)
|
||||
{
|
||||
((XR_Image *)image)->alpha = old_image->alpha;
|
||||
_xre_image_free(old_image);
|
||||
}
|
||||
else
|
||||
image = old_image;
|
||||
}
|
||||
else
|
||||
_xre_image_dirty((XR_Image *)image);
|
||||
_xre_image_resize((XR_Image *)image, w, h);
|
||||
return image;
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
|
||||
{
|
||||
if (!image) return image;
|
||||
_xre_image_dirty((XR_Image *)image);
|
||||
_xre_image_region_dirty((XR_Image *)image, x, y, w, h);
|
||||
return image;
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data)
|
||||
{
|
||||
if (!image) return image;
|
||||
if (to_write)
|
||||
{
|
||||
if (((XR_Image *)image)->references > 1)
|
||||
{
|
||||
XR_Image *old_image;
|
||||
|
||||
old_image = (XR_Image *)image;
|
||||
image = _xre_image_copy((XR_Image *)old_image);
|
||||
if (image)
|
||||
{
|
||||
((XR_Image *)image)->alpha = old_image->alpha;
|
||||
_xre_image_free(old_image);
|
||||
}
|
||||
else
|
||||
image = old_image;
|
||||
}
|
||||
else
|
||||
_xre_image_dirty((XR_Image *)image);
|
||||
}
|
||||
if (image_data) *image_data = _xre_image_data_get((XR_Image *)image);
|
||||
return image;
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_image_data_put(void *data, void *image, DATA32 *image_data)
|
||||
{
|
||||
if (!image) return image;
|
||||
if (_xre_image_data_get((XR_Image *)image) != image_data)
|
||||
{
|
||||
XR_Image *old_image;
|
||||
|
||||
old_image = (XR_Image *)image;
|
||||
image = _xre_image_data_find(image_data);
|
||||
if (image != old_image)
|
||||
{
|
||||
if (!image)
|
||||
{
|
||||
image = _xre_image_new_from_data(old_image->xcbinf, old_image->w, old_image->h, image_data);
|
||||
if (image)
|
||||
{
|
||||
((XR_Image *)image)->alpha = old_image->alpha;
|
||||
_xre_image_free(old_image);
|
||||
}
|
||||
else
|
||||
image = old_image;
|
||||
}
|
||||
else
|
||||
{
|
||||
_xre_image_free(old_image);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_xre_image_free(image);
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_image_alpha_set(void *data, void *image, int has_alpha)
|
||||
{
|
||||
if (!image) return image;
|
||||
if (((((XR_Image *)image)->alpha) && (has_alpha)) ||
|
||||
((!((XR_Image *)image)->alpha) && (!has_alpha)))
|
||||
return image;
|
||||
if (((XR_Image *)image)->references > 1)
|
||||
{
|
||||
XR_Image *old_image;
|
||||
|
||||
old_image = (XR_Image *)image;
|
||||
image = _xre_image_copy((XR_Image *)old_image);
|
||||
if (image)
|
||||
{
|
||||
((XR_Image *)image)->alpha = old_image->alpha;
|
||||
_xre_image_free(old_image);
|
||||
}
|
||||
else
|
||||
image = old_image;
|
||||
}
|
||||
else
|
||||
_xre_image_dirty((XR_Image *)image);
|
||||
_xre_image_alpha_set((XR_Image *)image, has_alpha);
|
||||
return image;
|
||||
}
|
||||
|
||||
static int
|
||||
eng_image_alpha_get(void *data, void *image)
|
||||
{
|
||||
if (!image) return 0;
|
||||
return _xre_image_alpha_get((XR_Image *)image);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
|
||||
{
|
||||
if ((!image) || (!surface)) return;
|
||||
_xre_image_surface_gen((XR_Image *)image);
|
||||
if (((XR_Image *)image)->surface)
|
||||
_xr_render_surface_composite(((XR_Image *)image)->surface,
|
||||
(XCBrender_Surface *)surface,
|
||||
(RGBA_Draw_Context *)context,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h,
|
||||
smooth);
|
||||
}
|
||||
|
||||
static char *
|
||||
eng_image_comment_get(void *data, void *image, char *key)
|
||||
{
|
||||
if (!image) return NULL;
|
||||
return ((XR_Image *)image)->comment;
|
||||
}
|
||||
|
||||
static char *
|
||||
eng_image_format_get(void *data, void *image)
|
||||
{
|
||||
if (!image) return NULL;
|
||||
return ((XR_Image *)image)->format;
|
||||
}
|
||||
|
||||
static void
|
||||
eng_image_cache_flush(void *data)
|
||||
{
|
||||
int tmp_size;
|
||||
|
||||
pfunc.image_cache_flush(data);
|
||||
_xre_image_cache_set(0);
|
||||
_xre_image_cache_set(tmp_size);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_image_cache_set(void *data, int bytes)
|
||||
{
|
||||
pfunc.image_cache_set(data, bytes);
|
||||
_xre_image_cache_set(bytes);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_image_cache_get(void *data)
|
||||
{
|
||||
return pfunc.image_cache_get(data);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, char *text)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
{
|
||||
static RGBA_Image *im = NULL;
|
||||
|
||||
if (!im)
|
||||
{
|
||||
im = evas_common_image_new();
|
||||
im->image = evas_common_image_surface_new(im);
|
||||
im->image->no_free = 1;
|
||||
}
|
||||
im->image->w = ((XCBrender_Surface *)surface)->w;
|
||||
im->image->h = ((XCBrender_Surface *)surface)->h;
|
||||
_xr_render_surface_clips_set((XCBrender_Surface *)surface, (RGBA_Draw_Context *)context, x, y, w, h);
|
||||
im->image->data = surface;
|
||||
evas_common_draw_context_font_ext_set(context,
|
||||
re->xcbinf,
|
||||
_xre_font_surface_new,
|
||||
_xre_font_surface_free,
|
||||
_xre_font_surface_draw);
|
||||
evas_common_font_draw(im, context, font, x, y, text);
|
||||
evas_common_draw_context_font_ext_set(context,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
evas_common_cpu_end_opt();
|
||||
}
|
||||
}
|
||||
|
||||
/* module advertising code */
|
||||
int
|
||||
module_open(Evas_Module *em)
|
||||
{
|
||||
if (!em) return 0;
|
||||
/* get whatever engine module we inherit from */
|
||||
if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
|
||||
/* store it for later use */
|
||||
func = pfunc;
|
||||
/* now to override methods */
|
||||
#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
|
||||
ORD(info);
|
||||
ORD(info_free);
|
||||
ORD(setup);
|
||||
ORD(output_free);
|
||||
ORD(output_resize);
|
||||
ORD(output_tile_size_set);
|
||||
ORD(output_redraws_rect_add);
|
||||
ORD(output_redraws_rect_del);
|
||||
ORD(output_redraws_clear);
|
||||
ORD(output_redraws_next_update_get);
|
||||
ORD(output_redraws_next_update_push);
|
||||
ORD(output_flush);
|
||||
ORD(rectangle_draw);
|
||||
ORD(line_draw);
|
||||
ORD(polygon_draw);
|
||||
ORD(gradient_color_add);
|
||||
ORD(gradient_colors_clear);
|
||||
ORD(gradient_free);
|
||||
ORD(gradient_fill_set);
|
||||
ORD(gradient_type_set);
|
||||
ORD(gradient_type_params_set);
|
||||
ORD(gradient_geometry_init);
|
||||
ORD(gradient_alpha_get);
|
||||
ORD(gradient_map);
|
||||
ORD(gradient_draw);
|
||||
ORD(image_load);
|
||||
ORD(image_new_from_data);
|
||||
ORD(image_new_from_copied_data);
|
||||
ORD(image_free);
|
||||
ORD(image_size_get);
|
||||
ORD(image_size_set);
|
||||
ORD(image_dirty_region);
|
||||
ORD(image_data_get);
|
||||
ORD(image_data_put);
|
||||
ORD(image_alpha_set);
|
||||
ORD(image_alpha_get);
|
||||
ORD(image_draw);
|
||||
ORD(image_comment_get);
|
||||
ORD(image_format_get);
|
||||
ORD(image_cache_flush);
|
||||
ORD(image_cache_set);
|
||||
ORD(image_cache_get);
|
||||
ORD(font_draw);
|
||||
/* now advertise out own api */
|
||||
em->functions = (void *)(&func);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
module_close(void)
|
||||
{
|
||||
}
|
||||
|
||||
Evas_Module_Api evas_modapi =
|
||||
{
|
||||
EVAS_MODULE_API_VERSION,
|
||||
EVAS_MODULE_TYPE_ENGINE,
|
||||
"xrender_xcb",
|
||||
"none"
|
||||
};
|
|
@ -0,0 +1,210 @@
|
|||
#ifndef EVAS_ENGINE_H
|
||||
#define EVAS_ENGINE_H
|
||||
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#include <X11/XCB/xcb.h>
|
||||
#include <X11/XCB/shm.h>
|
||||
#include <X11/XCB/render.h>
|
||||
#include <X11/XCB/xcb_image.h>
|
||||
|
||||
typedef struct _XCBimage_Info XCBimage_Info;
|
||||
typedef struct _XCBimage_Image XCBimage_Image;
|
||||
typedef struct _XCBrender_Surface XCBrender_Surface;
|
||||
|
||||
struct _XCBimage_Info
|
||||
{
|
||||
XCBConnection *conn;
|
||||
XCBDRAWABLE root;
|
||||
XCBDRAWABLE draw;
|
||||
int depth;
|
||||
XCBVISUALID vis;
|
||||
int pool_mem;
|
||||
Evas_List *pool;
|
||||
unsigned char can_do_shm;
|
||||
XCBRenderPICTFORMINFO *fmt32;
|
||||
XCBRenderPICTFORMINFO *fmt24;
|
||||
XCBRenderPICTFORMINFO *fmt8;
|
||||
XCBRenderPICTFORMINFO *fmt4;
|
||||
XCBRenderPICTFORMINFO *fmt1;
|
||||
unsigned char mul_r;
|
||||
unsigned char mul_g;
|
||||
unsigned char mul_b;
|
||||
unsigned char mul_a;
|
||||
XCBrender_Surface *mul;
|
||||
int references;
|
||||
};
|
||||
|
||||
struct _XCBimage_Image
|
||||
{
|
||||
XCBimage_Info *xcbinf;
|
||||
XCBImage *xcbim;
|
||||
XCBShmSegmentInfo *shm_info;
|
||||
int w;
|
||||
int h;
|
||||
int depth;
|
||||
int line_bytes;
|
||||
unsigned char *data;
|
||||
unsigned char available : 1;
|
||||
};
|
||||
|
||||
struct _XCBrender_Surface
|
||||
{
|
||||
XCBimage_Info *xcbinf;
|
||||
int w;
|
||||
int h;
|
||||
int depth;
|
||||
XCBRenderPICTFORMINFO *fmt;
|
||||
XCBDRAWABLE draw;
|
||||
XCBRenderPICTURE pic;
|
||||
unsigned char alpha : 1;
|
||||
unsigned char allocated : 1;
|
||||
};
|
||||
|
||||
/* ximage support calls (ximage vs xshmimage, cache etc.) */
|
||||
XCBimage_Info *_xr_image_info_get(XCBConnection *conn, XCBDRAWABLE draw, XCBVISUALID vis);
|
||||
void _xr_image_info_free(XCBimage_Info *xcbinf);
|
||||
void _xr_image_info_pool_flush(XCBimage_Info *xcbinf, int max_num, int max_mem);
|
||||
XCBimage_Image *_xr_image_new(XCBimage_Info *xcbinf, int w, int h, int depth);
|
||||
void _xr_image_free(XCBimage_Image *xim);
|
||||
void _xr_image_put(XCBimage_Image *xim, XCBDRAWABLE draw, int x, int y, int w, int h);
|
||||
|
||||
/* xrender support calls */
|
||||
XCBrender_Surface *_xr_render_surface_new(XCBimage_Info *xcbinf, int w, int h, XCBRenderPICTFORMINFO *fmt, int alpha);
|
||||
XCBrender_Surface *_xr_render_surface_adopt(XCBimage_Info *xcbinf, XCBDRAWABLE draw, int w, int h, int alpha);
|
||||
XCBrender_Surface *_xr_render_surface_format_adopt(XCBimage_Info *xcbinf, XCBDRAWABLE draw, int w, int h, XCBRenderPICTFORMINFO *fmt, int alpha);
|
||||
void _xr_render_surface_free(XCBrender_Surface *rs);
|
||||
void _xr_render_surface_repeat_set(XCBrender_Surface *rs, int repeat);
|
||||
void _xr_render_surface_solid_rectangle_set(XCBrender_Surface *rs, int r, int g, int b, int a, int x, int y, int w, int h);
|
||||
void _xr_render_surface_argb_pixels_fill(XCBrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h);
|
||||
void _xr_render_surface_rgb_pixels_fill(XCBrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h);
|
||||
void _xr_render_surface_clips_set(XCBrender_Surface *rs, RGBA_Draw_Context *dc, int rx, int ry, int rw, int rh);
|
||||
void _xr_render_surface_composite(XCBrender_Surface *srs, XCBrender_Surface *drs, RGBA_Draw_Context *dc, int sx, int sy, int sw, int sh, int x, int y, int w, int h, int smooth);
|
||||
void _xr_render_surface_copy(XCBrender_Surface *srs, XCBrender_Surface *drs, int sx, int sy, int x, int y, int w, int h);
|
||||
void _xr_render_surface_rectangle_draw(XCBrender_Surface *rs, RGBA_Draw_Context *dc, int x, int y, int w, int h);
|
||||
void _xr_render_surface_line_draw(XCBrender_Surface *rs, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2);
|
||||
void _xre_poly_draw(XCBrender_Surface *rs, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points);
|
||||
|
||||
|
||||
typedef struct _XR_Image XR_Image;
|
||||
|
||||
struct _XR_Image
|
||||
{
|
||||
XCBimage_Info *xcbinf;
|
||||
char *file;
|
||||
char *key;
|
||||
char *fkey;
|
||||
RGBA_Image *im;
|
||||
void *data;
|
||||
int w, h;
|
||||
XCBrender_Surface *surface;
|
||||
int references;
|
||||
char *format;
|
||||
char *comment;
|
||||
Tilebuf *updates;
|
||||
unsigned char alpha : 1;
|
||||
unsigned char dirty : 1;
|
||||
unsigned char free_data : 1;
|
||||
};
|
||||
|
||||
XR_Image *_xre_image_load(XCBimage_Info *xcbinf, char *file, char *key);
|
||||
XR_Image *_xre_image_new_from_data(XCBimage_Info *xcbinf, int w, int h, void *data);
|
||||
XR_Image *_xre_image_new_from_copied_data(XCBimage_Info *xcbinf, int w, int h, void *data);
|
||||
XR_Image *_xre_image_new(XCBimage_Info *xcbinf, int w, int h);
|
||||
void _xre_image_resize(XR_Image *im, int w, int h);
|
||||
void _xre_image_free(XR_Image *im);
|
||||
void _xre_image_region_dirty(XR_Image *im, int x, int y, int w, int h);
|
||||
void _xre_image_dirty(XR_Image *im);
|
||||
XR_Image *_xre_image_copy(XR_Image *im);
|
||||
void *_xre_image_data_get(XR_Image *im);
|
||||
XR_Image *_xre_image_data_find(void *data);
|
||||
void _xre_image_data_put(XR_Image *im, void *data);
|
||||
void _xre_image_alpha_set(XR_Image *im, int alpha);
|
||||
int _xre_image_alpha_get(XR_Image *im);
|
||||
void _xre_image_surface_gen(XR_Image *im);
|
||||
void _xre_image_cache_set(int size);
|
||||
int _xre_image_cache_get(void);
|
||||
|
||||
typedef struct _XR_Font_Surface XR_Font_Surface;
|
||||
|
||||
struct _XR_Font_Surface
|
||||
{
|
||||
XCBimage_Info *xcbinf;
|
||||
RGBA_Font_Glyph *fg;
|
||||
int w;
|
||||
int h;
|
||||
XCBDRAWABLE draw;
|
||||
XCBRenderPICTURE pic;
|
||||
};
|
||||
|
||||
XR_Font_Surface *_xre_font_surface_new (XCBimage_Info *xcbinf,
|
||||
RGBA_Font_Glyph *fg);
|
||||
|
||||
void _xre_font_surface_free (XR_Font_Surface *fs);
|
||||
|
||||
void _xre_font_surface_draw (XCBimage_Info *xcbinf,
|
||||
RGBA_Image *surface,
|
||||
RGBA_Draw_Context *dc,
|
||||
RGBA_Font_Glyph *fg,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
typedef struct _XR_Gradient XR_Gradient;
|
||||
|
||||
struct _XR_Gradient
|
||||
{
|
||||
XCBimage_Info *xcbinf;
|
||||
XCBrender_Surface *surface;
|
||||
RGBA_Gradient *grad;
|
||||
double angle;
|
||||
int spread;
|
||||
unsigned char changed;
|
||||
};
|
||||
|
||||
/* gradient */
|
||||
XR_Gradient *_xre_gradient_color_add (XCBimage_Info *xcbinf,
|
||||
XR_Gradient *gr,
|
||||
int r,
|
||||
int g,
|
||||
int b,
|
||||
int a,
|
||||
int distance);
|
||||
|
||||
XR_Gradient *_xre_gradient_colors_clear (XR_Gradient *gr);
|
||||
|
||||
void _xre_gradient_free (XR_Gradient *gr);
|
||||
|
||||
void _xre_gradient_fill_set (XR_Gradient *gr,
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
int h);
|
||||
|
||||
void _xre_gradient_type_set (XR_Gradient *gr,
|
||||
char *name);
|
||||
|
||||
void _xre_gradient_type_params_set (XR_Gradient *gr,
|
||||
char *params);
|
||||
|
||||
void *_xre_gradient_geometry_init (XR_Gradient *gr,
|
||||
int spread);
|
||||
|
||||
int _xre_gradient_alpha_get (XR_Gradient *gr,
|
||||
int spread);
|
||||
|
||||
void _xre_gradient_map (RGBA_Draw_Context *dc,
|
||||
XR_Gradient *gr,
|
||||
int spread);
|
||||
|
||||
void _xre_gradient_draw (XCBrender_Surface *rs,
|
||||
RGBA_Draw_Context *dc,
|
||||
XR_Gradient *gr,
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
int h,
|
||||
double angle,
|
||||
int spread);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,203 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_private.h"
|
||||
#include "evas_engine.h"
|
||||
#include "Evas_Engine_XRender_Xcb.h"
|
||||
|
||||
static Evas_Hash *_xr_fg_pool = NULL;
|
||||
|
||||
XR_Font_Surface *
|
||||
_xre_font_surface_new(XCBimage_Info *xcbinf, RGBA_Font_Glyph *fg)
|
||||
{
|
||||
char buf[256];
|
||||
char buf2[256];
|
||||
XR_Font_Surface *fs;
|
||||
DATA8 *data;
|
||||
int w, h, j;
|
||||
XCBimage_Image *xcim;
|
||||
Evas_Hash *pool;
|
||||
CARD32 mask;
|
||||
CARD32 values[3];
|
||||
|
||||
data = fg->glyph_out->bitmap.buffer;
|
||||
w = fg->glyph_out->bitmap.width;
|
||||
h = fg->glyph_out->bitmap.rows;
|
||||
j = fg->glyph_out->bitmap.pitch;
|
||||
if (j < w) j = w;
|
||||
if ((w <= 0) || (h <= 0)) return NULL;
|
||||
|
||||
if (fg->ext_dat)
|
||||
{
|
||||
fs = fg->ext_dat;
|
||||
if ((fs->xcbinf->conn == xcbinf->conn) &&
|
||||
(fs->xcbinf->root.window.xid == xcbinf->root.window.xid))
|
||||
return fs;
|
||||
snprintf(buf, sizeof(buf), "@%p@/@%lx@", fs->xcbinf->conn, fs->xcbinf->root.window.xid);
|
||||
pool = evas_hash_find(_xr_fg_pool, buf);
|
||||
if (pool)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%p", fg);
|
||||
fs = evas_hash_find(pool, buf);
|
||||
if (fs) return fs;
|
||||
}
|
||||
}
|
||||
|
||||
fs = calloc(1, sizeof(XR_Font_Surface));
|
||||
if (!fs) return NULL;
|
||||
|
||||
fs->xcbinf = xcbinf;
|
||||
fs->fg = fg;
|
||||
fs->xcbinf->references++;
|
||||
fs->w = w;
|
||||
fs->h = h;
|
||||
|
||||
snprintf(buf, sizeof(buf), "@%p@/@%lx@", fs->xcbinf->conn, fs->xcbinf->root.window.xid);
|
||||
pool = evas_hash_find(_xr_fg_pool, buf);
|
||||
snprintf(buf2, sizeof(buf2), "%p", fg);
|
||||
pool = evas_hash_add(pool, buf2, fs);
|
||||
_xr_fg_pool = evas_hash_add(_xr_fg_pool, buf, pool);
|
||||
|
||||
fs->draw.pixmap = XCBPIXMAPNew(xcbinf->conn);
|
||||
XCBCreatePixmap(xcbinf->conn, xcbinf->fmt8->depth, fs->draw.pixmap, xcbinf->root, w, h);
|
||||
|
||||
mask = XCBRenderCPRepeat | XCBRenderCPDither | XCBRenderCPComponentAlpha;
|
||||
values[0] = 0;
|
||||
values[1] = 0;
|
||||
values[2] = 0;
|
||||
fs->pic = XCBRenderPICTURENew(xcbinf->conn);
|
||||
XCBRenderCreatePicture(xcbinf->conn, fs->pic, fs->draw, xcbinf->fmt8->id, mask, values);
|
||||
|
||||
xcim = _xr_image_new(fs->xcbinf, w, h, xcbinf->fmt8->depth);
|
||||
if ((fg->glyph_out->bitmap.num_grays == 256) &&
|
||||
(fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
|
||||
{
|
||||
int x, y;
|
||||
DATA8 *p1, *p2;
|
||||
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
p1 = data + (j * y);
|
||||
p2 = ((DATA8 *)xcim->data) + (xcim->line_bytes * y);
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*p2 = *p1;
|
||||
p1++;
|
||||
p2++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
DATA8 *tmpbuf = NULL, *dp, *tp, bits;
|
||||
int bi, bj, end;
|
||||
const DATA8 bitrepl[2] = {0x0, 0xff};
|
||||
|
||||
tmpbuf = alloca(w);
|
||||
{
|
||||
int x, y;
|
||||
DATA8 *p1, *p2;
|
||||
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
p1 = tmpbuf;
|
||||
p2 = ((DATA8 *)xcim->data) + (xcim->line_bytes * y);
|
||||
tp = tmpbuf;
|
||||
dp = data + (y * fg->glyph_out->bitmap.pitch);
|
||||
for (bi = 0; bi < w; bi += 8)
|
||||
{
|
||||
bits = *dp;
|
||||
if ((w - bi) < 8) end = w - bi;
|
||||
else end = 8;
|
||||
for (bj = 0; bj < end; bj++)
|
||||
{
|
||||
*tp = bitrepl[(bits >> (7 - bj)) & 0x1];
|
||||
tp++;
|
||||
}
|
||||
dp++;
|
||||
}
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*p2 = *p1;
|
||||
p1++;
|
||||
p2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_xr_image_put(xcim, fs->draw, 0, 0, w, h);
|
||||
return fs;
|
||||
}
|
||||
|
||||
static Evas_Bool
|
||||
_xre_font_pool_cb(Evas_Hash *hash, const char *key, void *data, void *fdata)
|
||||
{
|
||||
Evas_Hash *pool;
|
||||
XR_Font_Surface *fs;
|
||||
char buf[256];
|
||||
|
||||
fs = fdata;
|
||||
pool = data;
|
||||
snprintf(buf, sizeof(buf), "@%p@/@%lx@", fs->xcbinf->conn, fs->xcbinf->root.window.xid);
|
||||
pool = evas_hash_del(pool, buf, fs);
|
||||
hash = evas_hash_modify(hash, key, pool);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
_xre_font_surface_free(XR_Font_Surface *fs)
|
||||
{
|
||||
if (!fs) return;
|
||||
evas_hash_foreach(_xr_fg_pool, _xre_font_pool_cb, fs);
|
||||
XCBFreePixmap(fs->xcbinf->conn, fs->draw.pixmap);
|
||||
XCBRenderFreePicture(fs->xcbinf->conn, fs->pic);
|
||||
_xr_image_info_free(fs->xcbinf);
|
||||
free(fs);
|
||||
}
|
||||
|
||||
void
|
||||
_xre_font_surface_draw(XCBimage_Info *xcbinf, RGBA_Image *surface, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y)
|
||||
{
|
||||
XR_Font_Surface *fs;
|
||||
XCBrender_Surface *target_surface;
|
||||
XCBRECTANGLE rect;
|
||||
int r;
|
||||
int g;
|
||||
int b;
|
||||
int a;
|
||||
|
||||
fs = fg->ext_dat;
|
||||
if (!fs) return;
|
||||
target_surface = (XCBrender_Surface *)(surface->image->data);
|
||||
a = (dc->col.col >> 24) & 0xff;
|
||||
r = (dc->col.col >> 16) & 0xff;
|
||||
g = (dc->col.col >> 8 ) & 0xff;
|
||||
b = (dc->col.col ) & 0xff;
|
||||
if ((fs->xcbinf->mul_r != r) || (fs->xcbinf->mul_g != g) ||
|
||||
(fs->xcbinf->mul_b != b) || (fs->xcbinf->mul_a != a))
|
||||
{
|
||||
fs->xcbinf->mul_r = r;
|
||||
fs->xcbinf->mul_g = g;
|
||||
fs->xcbinf->mul_b = b;
|
||||
fs->xcbinf->mul_a = a;
|
||||
_xr_render_surface_solid_rectangle_set(fs->xcbinf->mul, r, g, b, a, 0, 0, 1, 1);
|
||||
}
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = fs->w;
|
||||
rect.height = fs->h;
|
||||
if ((dc) && (dc->clip.use))
|
||||
{
|
||||
RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.width, rect.height,
|
||||
dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
|
||||
}
|
||||
XCBRenderSetPictureClipRectangles(target_surface->xcbinf->conn,
|
||||
target_surface->pic, 0, 0, 1, &rect);
|
||||
XCBRenderComposite(fs->xcbinf->conn, XCBRenderPictOpOver,
|
||||
fs->xcbinf->mul->pic,
|
||||
fs->pic,
|
||||
target_surface->pic,
|
||||
0, 0,
|
||||
0, 0,
|
||||
x, y,
|
||||
fs->w, fs->h);
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_private.h"
|
||||
#include "evas_engine.h"
|
||||
#include "Evas_Engine_XRender_Xcb.h"
|
||||
#include <math.h>
|
||||
|
||||
XR_Gradient *
|
||||
_xre_gradient_color_add(XCBimage_Info *xcbinf, XR_Gradient *gr, int r, int g, int b, int a, int distance)
|
||||
{
|
||||
if (!gr)
|
||||
{
|
||||
gr = calloc(1, sizeof(XR_Gradient));
|
||||
if (!gr) return NULL;
|
||||
gr->xcbinf = xcbinf;
|
||||
gr->xcbinf->references++;
|
||||
gr->grad = evas_common_gradient_new();
|
||||
if (!gr->grad)
|
||||
{
|
||||
gr->xcbinf->references--;
|
||||
free(gr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
evas_common_gradient_color_add(gr->grad, r, g, b, a, distance);
|
||||
if (gr->surface)
|
||||
{
|
||||
_xr_render_surface_free(gr->surface);
|
||||
gr->surface = NULL;
|
||||
}
|
||||
gr->changed = 1;
|
||||
return gr;
|
||||
}
|
||||
|
||||
XR_Gradient *
|
||||
_xre_gradient_colors_clear(XR_Gradient *gr)
|
||||
{
|
||||
if (!gr) return NULL;
|
||||
evas_common_gradient_colors_clear(gr->grad);
|
||||
if (gr->surface)
|
||||
{
|
||||
_xr_render_surface_free(gr->surface);
|
||||
gr->surface = NULL;
|
||||
}
|
||||
gr->changed = 1;
|
||||
return gr;
|
||||
}
|
||||
|
||||
void
|
||||
_xre_gradient_free(XR_Gradient *gr)
|
||||
{
|
||||
if (!gr) return;
|
||||
if (gr->grad)
|
||||
{
|
||||
evas_common_gradient_free(gr->grad);
|
||||
gr->grad = NULL;
|
||||
}
|
||||
if (gr->surface)
|
||||
{
|
||||
_xr_render_surface_free(gr->surface);
|
||||
gr->surface = NULL;
|
||||
}
|
||||
_xr_image_info_free(gr->xcbinf);
|
||||
free(gr);
|
||||
}
|
||||
|
||||
void
|
||||
_xre_gradient_fill_set(XR_Gradient *gr, int x, int y, int w, int h)
|
||||
{
|
||||
if (!gr) return;
|
||||
evas_common_gradient_fill_set(gr->grad, x, y, w, h);
|
||||
gr->changed = 1;
|
||||
}
|
||||
|
||||
void
|
||||
_xre_gradient_type_set(XR_Gradient *gr, char *name)
|
||||
{
|
||||
if (!gr) return;
|
||||
evas_common_gradient_type_set(gr->grad, name);
|
||||
gr->changed = 1;
|
||||
}
|
||||
|
||||
void
|
||||
_xre_gradient_type_params_set(XR_Gradient *gr, char *params)
|
||||
{
|
||||
if (!gr) return;
|
||||
evas_common_gradient_type_params_set(gr->grad, params);
|
||||
gr->changed = 1;
|
||||
}
|
||||
|
||||
void *
|
||||
_xre_gradient_geometry_init(XR_Gradient *gr, int spread)
|
||||
{
|
||||
if (!gr) return NULL;
|
||||
gr->grad = evas_common_gradient_geometry_init(gr->grad, spread);
|
||||
return gr;
|
||||
}
|
||||
|
||||
int
|
||||
_xre_gradient_alpha_get(XR_Gradient *gr, int spread)
|
||||
{
|
||||
if (!gr) return 0;
|
||||
return evas_common_gradient_has_alpha(gr->grad, spread);
|
||||
}
|
||||
|
||||
void
|
||||
_xre_gradient_map(RGBA_Draw_Context *dc, XR_Gradient *gr, int spread)
|
||||
{
|
||||
if (!gr) return;
|
||||
evas_common_gradient_map(dc, gr->grad, spread);
|
||||
evas_common_cpu_end_opt();
|
||||
gr->changed = 1;
|
||||
}
|
||||
|
||||
void
|
||||
_xre_gradient_draw(XCBrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h, double angle, int spread)
|
||||
{
|
||||
RGBA_Image *im;
|
||||
|
||||
if ((w <= 0) || (h <= 0)) return;
|
||||
|
||||
if ((angle != gr->angle) || (spread != gr->spread) || (gr->changed))
|
||||
{
|
||||
if (gr->surface)
|
||||
{
|
||||
_xr_render_surface_free(gr->surface);
|
||||
gr->surface = NULL;
|
||||
}
|
||||
}
|
||||
if (!gr->surface)
|
||||
{
|
||||
im = evas_common_image_create(w, h);
|
||||
if (im)
|
||||
{
|
||||
RGBA_Draw_Context *dc2;
|
||||
|
||||
dc2 = evas_common_draw_context_new();
|
||||
if (dc2)
|
||||
{
|
||||
im->flags |= RGBA_IMAGE_HAS_ALPHA;
|
||||
memset(im->image->data, 0, im->image->w * im->image->h * sizeof(DATA32));
|
||||
dc2->anti_alias = dc->anti_alias;
|
||||
dc2->interpolation.color_space = dc->interpolation.color_space;
|
||||
evas_common_gradient_draw(im, dc2, 0, 0, w, h, gr->grad, angle, spread);
|
||||
gr->surface = _xr_render_surface_new(gr->xcbinf, w, h, gr->xcbinf->fmt32, 1);
|
||||
if (gr->surface)
|
||||
_xr_render_surface_argb_pixels_fill(gr->surface, w, h, im->image->data, 0, 0, w, h);
|
||||
evas_common_draw_context_free(dc2);
|
||||
gr->angle = angle;
|
||||
gr->spread = spread;
|
||||
}
|
||||
evas_common_image_free(im);
|
||||
}
|
||||
}
|
||||
if (gr->surface)
|
||||
_xr_render_surface_composite(gr->surface, rs, dc, 0, 0, gr->surface->w, gr->surface->h, x, y, w, h, 1);
|
||||
gr->changed = 0;
|
||||
}
|
|
@ -0,0 +1,560 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_private.h"
|
||||
#include "evas_engine.h"
|
||||
#include "Evas_Engine_XRender_Xcb.h"
|
||||
|
||||
static Evas_Hash *_xr_image_hash = NULL;
|
||||
static int _xr_image_cache_size = 0;
|
||||
static int _xr_image_cache_usage = 0;
|
||||
static Evas_List *_xr_image_cache = NULL;
|
||||
static Evas_Hash *_xr_image_dirty_hash = NULL;
|
||||
|
||||
static void
|
||||
__xre_image_dirty_hash_add(XR_Image *im)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
if (!im->data) return;
|
||||
snprintf(buf, sizeof(buf), "%p", im->data);
|
||||
_xr_image_dirty_hash = evas_hash_add(_xr_image_dirty_hash, buf, im);
|
||||
}
|
||||
|
||||
static void
|
||||
__xre_image_dirty_hash_del(XR_Image *im)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
if (!im->data) return;
|
||||
snprintf(buf, sizeof(buf), "%p", im->data);
|
||||
_xr_image_dirty_hash = evas_hash_del(_xr_image_dirty_hash, buf, im);
|
||||
}
|
||||
|
||||
static XR_Image *
|
||||
__xre_image_dirty_hash_find(void *data)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%p", data);
|
||||
return evas_hash_find(_xr_image_dirty_hash, buf);
|
||||
}
|
||||
|
||||
static XR_Image *
|
||||
__xre_image_find(char *fkey)
|
||||
{
|
||||
XR_Image *im;
|
||||
|
||||
im = evas_hash_find(_xr_image_hash, fkey);
|
||||
if (!im)
|
||||
{
|
||||
Evas_List *l;
|
||||
|
||||
for (l = _xr_image_cache; l; l = l->next)
|
||||
{
|
||||
im = l->data;
|
||||
if (!strcmp(im->fkey, fkey))
|
||||
{
|
||||
_xr_image_cache = evas_list_remove_list(_xr_image_cache, l);
|
||||
_xr_image_hash = evas_hash_add(_xr_image_hash, im->fkey, im);
|
||||
_xr_image_cache_usage -= (im->w * im->h * 4);
|
||||
break;
|
||||
}
|
||||
im = NULL;
|
||||
}
|
||||
}
|
||||
if (im) im->references++;
|
||||
return im;
|
||||
}
|
||||
|
||||
XR_Image *
|
||||
_xre_image_load(XCBimage_Info *xcbinf, char *file, char *key)
|
||||
{
|
||||
XR_Image *im;
|
||||
char buf[4096];
|
||||
|
||||
if (!file) return NULL;
|
||||
if (key)
|
||||
snprintf(buf, sizeof(buf), "/@%p@%lx@/%s//://%s", xcbinf->conn, xcbinf->root.window.xid, file, key);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "/@%p@%lx@/%s", xcbinf->conn, xcbinf->root.window.xid, file);
|
||||
im = __xre_image_find(buf);
|
||||
if (im)
|
||||
{
|
||||
return im;
|
||||
}
|
||||
|
||||
im = calloc(1, sizeof(XR_Image));
|
||||
if (!im) return NULL;
|
||||
im->im = evas_common_load_image_from_file(file, key);
|
||||
if (!im->im)
|
||||
{
|
||||
free(im);
|
||||
return NULL;
|
||||
}
|
||||
im->xcbinf = xcbinf;
|
||||
im->xcbinf->references++;
|
||||
im->fkey = strdup(buf);
|
||||
im->file = (char *)evas_stringshare_add(file);
|
||||
if (key) im->key = (char *)evas_stringshare_add(key);
|
||||
im->w = im->im->image->w;
|
||||
im->h = im->im->image->h;
|
||||
im->references = 1;
|
||||
if (im->im->info.comment) im->comment = (char *)evas_stringshare_add(im->im->info.comment);
|
||||
/* if (im->im->info.format == 1) im->format = evas_stringshare_add("png"); */
|
||||
if (im->im->flags & RGBA_IMAGE_HAS_ALPHA) im->alpha = 1;
|
||||
_xr_image_hash = evas_hash_direct_add(_xr_image_hash, im->fkey, im);
|
||||
return im;
|
||||
}
|
||||
|
||||
XR_Image *
|
||||
_xre_image_new_from_data(XCBimage_Info *xcbinf, int w, int h, void *data)
|
||||
{
|
||||
XR_Image *im;
|
||||
|
||||
im = calloc(1, sizeof(XR_Image));
|
||||
if (!im) return NULL;
|
||||
im->xcbinf = xcbinf;
|
||||
im->xcbinf->references++;
|
||||
im->w = w;
|
||||
im->h = h;
|
||||
im->references = 1;
|
||||
im->data = data;
|
||||
im->alpha = 1;
|
||||
im->dirty = 1;
|
||||
__xre_image_dirty_hash_add(im);
|
||||
return im;
|
||||
}
|
||||
|
||||
XR_Image *
|
||||
_xre_image_new_from_copied_data(XCBimage_Info *xcbinf, int w, int h, void *data)
|
||||
{
|
||||
XR_Image *im;
|
||||
|
||||
im = calloc(1, sizeof(XR_Image));
|
||||
if (!im) return NULL;
|
||||
im->data = malloc(w * h * 4);
|
||||
if (!im->data)
|
||||
{
|
||||
free(im);
|
||||
return NULL;
|
||||
}
|
||||
if (data)
|
||||
{
|
||||
Gfx_Func_Blend_Src_Dst func;
|
||||
|
||||
func = evas_common_draw_func_copy_get(w * h, 0);
|
||||
if (func) func(data, im->data, w * h);
|
||||
evas_common_cpu_end_opt();
|
||||
}
|
||||
im->w = w;
|
||||
im->h = h;
|
||||
im->references = 1;
|
||||
im->xcbinf = xcbinf;
|
||||
im->xcbinf->references++;
|
||||
im->free_data = 1;
|
||||
im->alpha = 1;
|
||||
im->dirty = 1;
|
||||
__xre_image_dirty_hash_add(im);
|
||||
return im;
|
||||
}
|
||||
|
||||
XR_Image *
|
||||
_xre_image_new(XCBimage_Info *xcbinf, int w, int h)
|
||||
{
|
||||
XR_Image *im;
|
||||
|
||||
im = calloc(1, sizeof(XR_Image));
|
||||
if (!im) return NULL;
|
||||
im->data = malloc(w * h * 4);
|
||||
if (!im->data)
|
||||
{
|
||||
free(im);
|
||||
return NULL;
|
||||
}
|
||||
im->w = w;
|
||||
im->h = h;
|
||||
im->references = 1;
|
||||
im->xcbinf = xcbinf;
|
||||
im->xcbinf->references++;
|
||||
im->free_data = 1;
|
||||
im->alpha = 1;
|
||||
im->dirty = 1;
|
||||
__xre_image_dirty_hash_add(im);
|
||||
return im;
|
||||
}
|
||||
|
||||
static void
|
||||
__xre_image_real_free(XR_Image *im)
|
||||
{
|
||||
if (im->file) evas_stringshare_del(im->file);
|
||||
if (im->key) evas_stringshare_del(im->key);
|
||||
if (im->fkey) free(im->fkey);
|
||||
if (im->im) evas_common_image_unref(im->im);
|
||||
if ((im->data) && (im->dirty)) __xre_image_dirty_hash_del(im);
|
||||
if ((im->free_data) && (im->data)) free(im->data);
|
||||
if (im->surface) _xr_render_surface_free(im->surface);
|
||||
if (im->format) evas_stringshare_del(im->format);
|
||||
if (im->comment) evas_stringshare_del(im->comment);
|
||||
if (im->updates) evas_common_tilebuf_free(im->updates);
|
||||
_xr_image_info_free(im->xcbinf);
|
||||
free(im);
|
||||
}
|
||||
|
||||
void
|
||||
_xre_image_free(XR_Image *im)
|
||||
{
|
||||
im->references--;
|
||||
if (im->references != 0) return;
|
||||
if (!im->dirty)
|
||||
{
|
||||
if (im->fkey)
|
||||
_xr_image_hash = evas_hash_del(_xr_image_hash, im->fkey, im);
|
||||
_xr_image_cache = evas_list_prepend(_xr_image_cache, im);
|
||||
_xr_image_cache_usage += (im->w * im->h * 4);
|
||||
_xre_image_cache_set(_xr_image_cache_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
__xre_image_real_free(im);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_xre_image_region_dirty(XR_Image *im, int x, int y, int w, int h)
|
||||
{
|
||||
if (!im->updates)
|
||||
{
|
||||
im->updates = evas_common_tilebuf_new(im->w, im->h);
|
||||
if (im->updates) evas_common_tilebuf_set_tile_size(im->updates, 8, 8);
|
||||
}
|
||||
if (im->updates)
|
||||
evas_common_tilebuf_add_redraw(im->updates, x, y, w, h);
|
||||
}
|
||||
|
||||
void
|
||||
_xre_image_dirty(XR_Image *im)
|
||||
{
|
||||
if (im->dirty) return;
|
||||
if (im->fkey)
|
||||
_xr_image_hash = evas_hash_del(_xr_image_hash, im->fkey, im);
|
||||
im->dirty = 1;
|
||||
__xre_image_dirty_hash_add(im);
|
||||
}
|
||||
|
||||
XR_Image *
|
||||
_xre_image_copy(XR_Image *im)
|
||||
{
|
||||
XR_Image *im2;
|
||||
void *data = NULL;
|
||||
|
||||
if (im->data) data = im->data;
|
||||
else
|
||||
{
|
||||
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key);
|
||||
if (im->im)
|
||||
{
|
||||
evas_common_load_image_data_from_file(im->im);
|
||||
data = im->im->image->data;
|
||||
}
|
||||
}
|
||||
if (!data) return NULL;
|
||||
im2 = _xre_image_new_from_copied_data(im->xcbinf, im->w, im->h, data);
|
||||
if (im2) im2->alpha = im->alpha;
|
||||
if ((im->im) && (!im->dirty))
|
||||
{
|
||||
evas_common_image_unref(im->im);
|
||||
im->im = NULL;
|
||||
}
|
||||
return im2;
|
||||
}
|
||||
|
||||
void
|
||||
_xre_image_resize(XR_Image *im, int w, int h)
|
||||
{
|
||||
if ((w == im->w) && (h == im->h)) return;
|
||||
if (im->surface)
|
||||
{
|
||||
XCBrender_Surface *old_surface;
|
||||
int x = 0, y = 0, ww, hh;
|
||||
|
||||
ww = w; hh = h;
|
||||
RECTS_CLIP_TO_RECT(x, y, ww, hh, 0, 0, im->w, im->h);
|
||||
old_surface = im->surface;
|
||||
im->surface = _xr_render_surface_new(old_surface->xcbinf, w, h, old_surface->fmt, old_surface->alpha);
|
||||
if (im->surface)
|
||||
_xr_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, ww, hh);
|
||||
_xr_render_surface_free(old_surface);
|
||||
}
|
||||
if (im->data)
|
||||
{
|
||||
Gfx_Func_Blend_Src_Dst func;
|
||||
int x = 0, y = 0, ww, hh;
|
||||
unsigned int *sp, *dp;
|
||||
void *data;
|
||||
|
||||
data = malloc(w * h * 4);
|
||||
if (!data)
|
||||
{
|
||||
if (im->surface)
|
||||
{
|
||||
_xr_render_surface_free(im->surface);
|
||||
im->surface = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
ww = w; hh = h;
|
||||
|
||||
RECTS_CLIP_TO_RECT(x, y, ww, hh, 0, 0, im->w, im->h);
|
||||
func = evas_common_draw_func_copy_get(w * h, 0);
|
||||
if (func)
|
||||
{
|
||||
for (y = 0; y < hh; y++)
|
||||
{
|
||||
sp = ((unsigned int *)im->data) + (y * im->w);
|
||||
dp = ((unsigned int *)data) + (y * w);
|
||||
func(sp, dp, ww);
|
||||
}
|
||||
evas_common_cpu_end_opt();
|
||||
}
|
||||
__xre_image_dirty_hash_del(im);
|
||||
free(im->data);
|
||||
im->data = data;
|
||||
__xre_image_dirty_hash_add(im);
|
||||
}
|
||||
else if (im->im)
|
||||
{
|
||||
RGBA_Image *im_old;
|
||||
|
||||
im_old = im->im;
|
||||
im->im = evas_common_image_create(w, h);
|
||||
if (!im->im)
|
||||
{
|
||||
im->im = im_old;
|
||||
if (im->surface)
|
||||
{
|
||||
_xr_render_surface_free(im->surface);
|
||||
im->surface = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
evas_common_load_image_data_from_file(im_old);
|
||||
if (im_old->image->data)
|
||||
{
|
||||
int x = 0, y = 0, ww, hh;
|
||||
|
||||
ww = w; hh = h;
|
||||
RECTS_CLIP_TO_RECT(x, y, ww, hh, 0, 0, im->w, im->h);
|
||||
evas_common_blit_rectangle(im_old, im->im, 0, 0, ww, hh, 0, 0);
|
||||
evas_common_cpu_end_opt();
|
||||
}
|
||||
im->free_data = 1;
|
||||
im->data = im->im->image->data;
|
||||
im->im->image->data = NULL;
|
||||
evas_common_image_unref(im->im);
|
||||
im->im = NULL;
|
||||
evas_common_image_unref(im_old);
|
||||
__xre_image_dirty_hash_add(im);
|
||||
}
|
||||
else
|
||||
{
|
||||
im->data = malloc(w * h * 4);
|
||||
im->free_data = 1;
|
||||
__xre_image_dirty_hash_add(im);
|
||||
}
|
||||
im->w = w;
|
||||
im->h = h;
|
||||
}
|
||||
|
||||
void *
|
||||
_xre_image_data_get(XR_Image *im)
|
||||
{
|
||||
void *data = NULL;
|
||||
|
||||
if (im->data) data = im->data;
|
||||
else
|
||||
{
|
||||
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key);
|
||||
if (im->im)
|
||||
{
|
||||
evas_common_load_image_data_from_file(im->im);
|
||||
data = im->im->image->data;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
XR_Image *
|
||||
_xre_image_data_find(void *data)
|
||||
{
|
||||
XR_Image *im;
|
||||
|
||||
im = __xre_image_dirty_hash_find(data);
|
||||
if (im)
|
||||
{
|
||||
im->references++;
|
||||
}
|
||||
return im;
|
||||
}
|
||||
|
||||
void
|
||||
_xre_image_data_put(XR_Image *im, void *data)
|
||||
{
|
||||
void *imdata = NULL;
|
||||
|
||||
if (!data) return;
|
||||
if (im->data)
|
||||
{
|
||||
imdata = im->data;
|
||||
if (data == imdata) return;
|
||||
__xre_image_dirty_hash_del(im);
|
||||
if (im->free_data) free(im->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (im->im) imdata = im->im->image->data;
|
||||
if (data == imdata) return;
|
||||
if (im->im)
|
||||
{
|
||||
evas_common_image_unref(im->im);
|
||||
im->im = NULL;
|
||||
}
|
||||
}
|
||||
im->data = data;
|
||||
__xre_image_dirty_hash_add(im);
|
||||
im->free_data = 0;
|
||||
if (im->surface)
|
||||
{
|
||||
_xr_render_surface_free(im->surface);
|
||||
im->surface = NULL;
|
||||
}
|
||||
if (!im->dirty)
|
||||
{
|
||||
if (im->fkey)
|
||||
_xr_image_hash = evas_hash_del(_xr_image_hash, im->fkey, im);
|
||||
im->dirty = 1;
|
||||
}
|
||||
if (im->updates)
|
||||
{
|
||||
evas_common_tilebuf_free(im->updates);
|
||||
im->updates = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_xre_image_alpha_set(XR_Image *im, int alpha)
|
||||
{
|
||||
if (im->alpha == alpha) return;
|
||||
im->alpha = alpha;
|
||||
if (im->surface)
|
||||
{
|
||||
XCBrender_Surface *old_surface;
|
||||
|
||||
old_surface = im->surface;
|
||||
im->surface = NULL;
|
||||
if (im->alpha)
|
||||
im->surface = _xr_render_surface_new(im->xcbinf, im->w, im->h, im->xcbinf->fmt32, 1);
|
||||
else
|
||||
im->surface = _xr_render_surface_new(im->xcbinf, im->w, im->h, im->xcbinf->fmt24, 0);
|
||||
if (im->surface)
|
||||
_xr_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, im->w, im->h);
|
||||
_xr_render_surface_free(old_surface);
|
||||
}
|
||||
if (im->updates)
|
||||
{
|
||||
evas_common_tilebuf_free(im->updates);
|
||||
im->updates = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_xre_image_alpha_get(XR_Image *im)
|
||||
{
|
||||
return im->alpha;
|
||||
}
|
||||
|
||||
void
|
||||
_xre_image_surface_gen(XR_Image *im)
|
||||
{
|
||||
void *data = NULL;
|
||||
|
||||
if ((im->surface) && (!im->updates)) return;
|
||||
if (im->data) data = im->data;
|
||||
else
|
||||
{
|
||||
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key);
|
||||
if (im->im)
|
||||
{
|
||||
evas_common_load_image_data_from_file(im->im);
|
||||
data = im->im->image->data;
|
||||
}
|
||||
}
|
||||
if (!data) return;
|
||||
if (im->surface)
|
||||
{
|
||||
if (im->updates)
|
||||
{
|
||||
Tilebuf_Rect *rects, *r;
|
||||
|
||||
rects = evas_common_tilebuf_get_render_rects(im->updates);
|
||||
if (rects)
|
||||
{
|
||||
for (r = rects; r; r = (Tilebuf_Rect *)((Evas_Object_List *)r)->next)
|
||||
{
|
||||
int rx, ry, rw, rh;
|
||||
|
||||
rx = r->x; ry = r->y; rw = r->w, rh = r->h;
|
||||
RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, im->w, im->h);
|
||||
if (im->alpha)
|
||||
_xr_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh);
|
||||
else
|
||||
_xr_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh);
|
||||
}
|
||||
evas_common_tilebuf_free_render_rects(rects);
|
||||
}
|
||||
evas_common_tilebuf_free(im->updates);
|
||||
im->updates = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (im->alpha)
|
||||
{
|
||||
im->surface = _xr_render_surface_new(im->xcbinf, im->w, im->h, im->xcbinf->fmt32, 1);
|
||||
_xr_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h);
|
||||
}
|
||||
else
|
||||
{
|
||||
im->surface = _xr_render_surface_new(im->xcbinf, im->w, im->h, im->xcbinf->fmt24, 0);
|
||||
_xr_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h);
|
||||
}
|
||||
if ((im->im) && (!im->dirty))
|
||||
{
|
||||
evas_common_image_unref(im->im);
|
||||
im->im = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_xre_image_cache_set(int size)
|
||||
{
|
||||
_xr_image_cache_size = size;
|
||||
while (_xr_image_cache_usage > _xr_image_cache_size)
|
||||
{
|
||||
Evas_List *l;
|
||||
|
||||
l = evas_list_last(_xr_image_cache);
|
||||
if (l)
|
||||
{
|
||||
XR_Image *im;
|
||||
|
||||
im = l->data;
|
||||
_xr_image_cache = evas_list_remove_list(_xr_image_cache, l);
|
||||
_xr_image_cache_usage -= (im->w * im->h * 4);
|
||||
__xre_image_real_free(im);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_xre_image_cache_get(void)
|
||||
{
|
||||
return _xr_image_cache_size;
|
||||
}
|
|
@ -0,0 +1,545 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_private.h"
|
||||
#include "evas_engine.h"
|
||||
#include "Evas_Engine_XRender_Xcb.h"
|
||||
|
||||
static Evas_List *_image_info_list = NULL;
|
||||
|
||||
static int _xcb_err = 0;
|
||||
|
||||
enum
|
||||
{
|
||||
XCBRenderPICTFORMINFOId = 1 << 0,
|
||||
XCBRenderPICTFORMINFOType = 1 << 1,
|
||||
XCBRenderPICTFORMINFODepth = 1 << 2,
|
||||
XCBRenderPICTFORMINFORedShift = 1 << 3,
|
||||
XCBRenderPICTFORMINFORedMask = 1 << 4,
|
||||
XCBRenderPICTFORMINFOGreenShift = 1 << 5,
|
||||
XCBRenderPICTFORMINFOGreenMask = 1 << 6,
|
||||
XCBRenderPICTFORMINFOBlueShift = 1 << 7,
|
||||
XCBRenderPICTFORMINFOBlueMask = 1 << 8,
|
||||
XCBRenderPICTFORMINFOAlphaShift = 1 << 9,
|
||||
XCBRenderPICTFORMINFOAlphaMask = 1 << 10,
|
||||
XCBRenderPICTFORMINFOColormap = 1 << 11,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
XCBRenderStandardPICTFORMINFOARGB32,
|
||||
XCBRenderStandardPICTFORMINFORGB24,
|
||||
XCBRenderStandardPICTFORMINFOA8,
|
||||
XCBRenderStandardPICTFORMINFOA4,
|
||||
XCBRenderStandardPICTFORMINFOA1,
|
||||
XCBRenderStandardPICTFORMINFOCount
|
||||
};
|
||||
|
||||
static XCBRenderPICTFORMINFO *
|
||||
XCBRenderFindPICTFORMINFO (XCBConnection *conn, CARD32 mask, const XCBRenderPICTFORMINFO *template, int count)
|
||||
{
|
||||
XCBRenderQueryPictFormatsCookie cookie;
|
||||
XCBRenderQueryPictFormatsRep *rep;
|
||||
XCBRenderPICTFORMINFOIter iter_forminfo;
|
||||
|
||||
cookie = XCBRenderQueryPictFormats (conn);
|
||||
rep = XCBRenderQueryPictFormatsReply (conn, cookie, NULL);
|
||||
iter_forminfo = XCBRenderQueryPictFormatsFormatsIter (rep);
|
||||
for (; iter_forminfo.rem; XCBRenderPICTFORMINFONext (&iter_forminfo)) {
|
||||
if (mask & XCBRenderPICTFORMINFOId)
|
||||
if (template->id.xid != iter_forminfo.data->id.xid)
|
||||
continue;
|
||||
if (mask & XCBRenderPICTFORMINFOType)
|
||||
if (template->type != iter_forminfo.data->type)
|
||||
continue;
|
||||
if (mask & XCBRenderPICTFORMINFODepth)
|
||||
if (template->depth != iter_forminfo.data->depth)
|
||||
continue;
|
||||
if (mask & XCBRenderPICTFORMINFORedShift)
|
||||
if (template->direct.red_shift != iter_forminfo.data->direct.red_shift)
|
||||
continue;
|
||||
if (mask & XCBRenderPICTFORMINFORedMask)
|
||||
if (template->direct.red_mask != iter_forminfo.data->direct.red_mask)
|
||||
continue;
|
||||
if (mask & XCBRenderPICTFORMINFOGreenShift)
|
||||
if (template->direct.green_shift != iter_forminfo.data->direct.green_shift)
|
||||
continue;
|
||||
if (mask & XCBRenderPICTFORMINFOGreenMask)
|
||||
if (template->direct.green_mask != iter_forminfo.data->direct.green_mask)
|
||||
continue;
|
||||
if (mask & XCBRenderPICTFORMINFOBlueShift)
|
||||
if (template->direct.blue_shift != iter_forminfo.data->direct.blue_shift)
|
||||
continue;
|
||||
if (mask & XCBRenderPICTFORMINFOBlueMask)
|
||||
if (template->direct.blue_mask != iter_forminfo.data->direct.blue_mask)
|
||||
continue;
|
||||
if (mask & XCBRenderPICTFORMINFOAlphaShift)
|
||||
if (template->direct.alpha_shift != iter_forminfo.data->direct.alpha_shift)
|
||||
continue;
|
||||
if (mask & XCBRenderPICTFORMINFOAlphaMask)
|
||||
if (template->direct.alpha_mask != iter_forminfo.data->direct.alpha_mask)
|
||||
continue;
|
||||
if (mask & XCBRenderPICTFORMINFOColormap)
|
||||
if (template->colormap.xid != iter_forminfo.data->colormap.xid)
|
||||
continue;
|
||||
if (count-- == 0) {
|
||||
XCBRenderPICTFORMINFO *forminfo;
|
||||
|
||||
forminfo = (XCBRenderPICTFORMINFO *)malloc (sizeof (XCBRenderPICTFORMINFO));
|
||||
memcpy (forminfo, iter_forminfo.data, sizeof (XCBRenderPICTFORMINFO));
|
||||
|
||||
free (rep);
|
||||
return forminfo;
|
||||
}
|
||||
}
|
||||
free (rep);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static XCBRenderPICTFORMINFO *
|
||||
XCBRenderFindStandardPICTFORMINFO (XCBConnection *conn, int format)
|
||||
{
|
||||
XCBRenderPICTFORMINFO *forminfo = NULL;
|
||||
struct {
|
||||
XCBRenderPICTFORMINFO template;
|
||||
CARD32 mask;
|
||||
} standardFormats[XCBRenderStandardPICTFORMINFOCount] = {
|
||||
/* StandardPICTFORMINFOARGB32 */
|
||||
{
|
||||
{
|
||||
{ 0, }, /* id */
|
||||
XCBRenderPictTypeDirect, /* type */
|
||||
32, /* depth */
|
||||
{ 0, 0 }, /* pad */
|
||||
{ /* direct */
|
||||
16, /* direct.red_shift */
|
||||
0xff, /* direct.red_mask */
|
||||
8, /* direct.green_shift */
|
||||
0xff, /* direct.green_mask */
|
||||
0, /* direct.blue_shift */
|
||||
0xff, /* direct.blue_mask */
|
||||
24, /* direct.alpha_shift */
|
||||
0xff /* direct.alpha_mask */
|
||||
},
|
||||
{ 0, } /* colormap */
|
||||
},
|
||||
XCBRenderPICTFORMINFOType |
|
||||
XCBRenderPICTFORMINFODepth |
|
||||
XCBRenderPICTFORMINFORedShift |
|
||||
XCBRenderPICTFORMINFORedMask |
|
||||
XCBRenderPICTFORMINFOGreenShift |
|
||||
XCBRenderPICTFORMINFOGreenMask |
|
||||
XCBRenderPICTFORMINFOBlueShift |
|
||||
XCBRenderPICTFORMINFOBlueMask |
|
||||
XCBRenderPICTFORMINFOAlphaShift |
|
||||
XCBRenderPICTFORMINFOAlphaMask
|
||||
},
|
||||
/* StandardPICTFORMINFORGB24 */
|
||||
{
|
||||
{
|
||||
{ 0, }, /* id */
|
||||
XCBRenderPictTypeDirect, /* type */
|
||||
24, /* depth */
|
||||
{ 0, 0 }, /* pad */
|
||||
{ /* direct */
|
||||
16, /* direct.red_shift */
|
||||
0xff, /* direct.red_mask */
|
||||
8, /* direct.green_shift */
|
||||
0xff, /* direct.green_mask */
|
||||
0, /* direct.blue_shift */
|
||||
0xff, /* direct.blue_mask */
|
||||
0, /* direct.alpha_shift */
|
||||
0x00 /* direct.alpha_mask */
|
||||
},
|
||||
{ 0, } /* colormap */
|
||||
},
|
||||
XCBRenderPICTFORMINFOType |
|
||||
XCBRenderPICTFORMINFODepth |
|
||||
XCBRenderPICTFORMINFORedShift |
|
||||
XCBRenderPICTFORMINFORedMask |
|
||||
XCBRenderPICTFORMINFOGreenShift |
|
||||
XCBRenderPICTFORMINFOGreenMask |
|
||||
XCBRenderPICTFORMINFOBlueShift |
|
||||
XCBRenderPICTFORMINFOBlueMask |
|
||||
XCBRenderPICTFORMINFOAlphaMask
|
||||
},
|
||||
/* StandardPICTFORMINFOA8 */
|
||||
{
|
||||
{
|
||||
{ 0, }, /* id */
|
||||
XCBRenderPictTypeDirect, /* type */
|
||||
8, /* depth */
|
||||
{ 0, 0 }, /* pad */
|
||||
{ /* direct */
|
||||
0, /* direct.red_shift */
|
||||
0x00, /* direct.red_mask */
|
||||
0, /* direct.green_shift */
|
||||
0x00, /* direct.green_mask */
|
||||
0, /* direct.blue_shift */
|
||||
0x00, /* direct.blue_mask */
|
||||
0, /* direct.alpha_shift */
|
||||
0xff /* direct.alpha_mask */
|
||||
},
|
||||
{ 0, } /* colormap */
|
||||
},
|
||||
XCBRenderPICTFORMINFOType |
|
||||
XCBRenderPICTFORMINFODepth |
|
||||
XCBRenderPICTFORMINFORedMask |
|
||||
XCBRenderPICTFORMINFOGreenMask |
|
||||
XCBRenderPICTFORMINFOBlueMask |
|
||||
XCBRenderPICTFORMINFOAlphaShift |
|
||||
XCBRenderPICTFORMINFOAlphaMask
|
||||
},
|
||||
/* StandardPICTFORMINFOA4 */
|
||||
{
|
||||
{
|
||||
{ 0, }, /* id */
|
||||
XCBRenderPictTypeDirect, /* type */
|
||||
4, /* depth */
|
||||
{ 0, 0 }, /* pad */
|
||||
{ /* direct */
|
||||
0, /* direct.red_shift */
|
||||
0x00, /* direct.red_mask */
|
||||
0, /* direct.green_shift */
|
||||
0x00, /* direct.green_mask */
|
||||
0, /* direct.blue_shift */
|
||||
0x00, /* direct.blue_mask */
|
||||
0, /* direct.alpha_shift */
|
||||
0x0f /* direct.alpha_mask */
|
||||
},
|
||||
{ 0, } /* colormap */
|
||||
},
|
||||
XCBRenderPICTFORMINFOType |
|
||||
XCBRenderPICTFORMINFODepth |
|
||||
XCBRenderPICTFORMINFORedMask |
|
||||
XCBRenderPICTFORMINFOGreenMask |
|
||||
XCBRenderPICTFORMINFOBlueMask |
|
||||
XCBRenderPICTFORMINFOAlphaShift |
|
||||
XCBRenderPICTFORMINFOAlphaMask
|
||||
},
|
||||
/* StandardPICTFORMINFOA1 */
|
||||
{
|
||||
{
|
||||
{ 0, }, /* id */
|
||||
XCBRenderPictTypeDirect, /* type */
|
||||
1, /* depth */
|
||||
{ 0, 0 }, /* pad */
|
||||
{ /* direct */
|
||||
0, /* direct.red_shift */
|
||||
0x00, /* direct.red_mask */
|
||||
0, /* direct.green_shift */
|
||||
0x00, /* direct.green_mask */
|
||||
0, /* direct.blue_shift */
|
||||
0x00, /* direct.blue_mask */
|
||||
0, /* direct.alpha_shift */
|
||||
0x01 /* direct.alpha_mask */
|
||||
},
|
||||
{ 0, } /* colormap */
|
||||
},
|
||||
XCBRenderPICTFORMINFOType |
|
||||
XCBRenderPICTFORMINFODepth |
|
||||
XCBRenderPICTFORMINFORedMask |
|
||||
XCBRenderPICTFORMINFOGreenMask |
|
||||
XCBRenderPICTFORMINFOBlueMask |
|
||||
XCBRenderPICTFORMINFOAlphaShift |
|
||||
XCBRenderPICTFORMINFOAlphaMask
|
||||
},
|
||||
};
|
||||
if ((format >= 0) && (format < XCBRenderStandardPICTFORMINFOCount))
|
||||
forminfo = XCBRenderFindPICTFORMINFO (conn,
|
||||
standardFormats[format].mask,
|
||||
&standardFormats[format].template,
|
||||
0);
|
||||
return forminfo;
|
||||
}
|
||||
|
||||
static void
|
||||
_tmp_xcb_err(XCBConnection *conn/* , XErrorEvent *ev */)
|
||||
{
|
||||
_xcb_err = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
XCBimage_Info *
|
||||
_xr_image_info_get(XCBConnection *conn, XCBDRAWABLE draw, XCBVISUALID vis)
|
||||
{
|
||||
XCBGetGeometryCookie cookie;
|
||||
XCBGetGeometryRep *rep;
|
||||
XCBimage_Info *xcbinf;
|
||||
XCBimage_Info *xcbinf2;
|
||||
Evas_List *l;
|
||||
|
||||
xcbinf2 = NULL;
|
||||
for (l = _image_info_list; l; l = l->next)
|
||||
{
|
||||
xcbinf = l->data;
|
||||
if (xcbinf->conn == conn)
|
||||
{
|
||||
xcbinf2 = xcbinf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
xcbinf = calloc(1, sizeof(XCBimage_Info));
|
||||
if (!xcbinf) return NULL;
|
||||
|
||||
xcbinf->references = 1;
|
||||
xcbinf->conn = conn;
|
||||
xcbinf->draw = draw;
|
||||
cookie = XCBGetGeometry(xcbinf->conn, xcbinf->draw);
|
||||
rep = XCBGetGeometryReply(xcbinf->conn, cookie, NULL);
|
||||
xcbinf->root.window = rep->root;
|
||||
free(rep);
|
||||
xcbinf->vis = vis;
|
||||
xcbinf->fmt32 = XCBRenderFindStandardPICTFORMINFO(xcbinf->conn, XCBRenderStandardPICTFORMINFOARGB32);
|
||||
xcbinf->fmt24 = XCBRenderFindStandardPICTFORMINFO(xcbinf->conn, XCBRenderStandardPICTFORMINFORGB24);
|
||||
xcbinf->fmt8 = XCBRenderFindStandardPICTFORMINFO(xcbinf->conn, XCBRenderStandardPICTFORMINFOA8);
|
||||
xcbinf->fmt4 = XCBRenderFindStandardPICTFORMINFO(xcbinf->conn, XCBRenderStandardPICTFORMINFOA4);
|
||||
xcbinf->fmt1 = XCBRenderFindStandardPICTFORMINFO(xcbinf->conn, XCBRenderStandardPICTFORMINFOA1);
|
||||
xcbinf->mul = _xr_render_surface_new(xcbinf, 1, 1, xcbinf->fmt32, 1);
|
||||
_xr_render_surface_repeat_set(xcbinf->mul, 1);
|
||||
xcbinf->mul_r = xcbinf->mul_g = xcbinf->mul_b = xcbinf->mul_a = 0xff;
|
||||
_xr_render_surface_solid_rectangle_set(xcbinf->mul, xcbinf->mul_r, xcbinf->mul_g, xcbinf->mul_b, xcbinf->mul_a, 0, 0, 1, 1);
|
||||
if (xcbinf2)
|
||||
{
|
||||
xcbinf->can_do_shm = xcbinf2->can_do_shm;
|
||||
xcbinf->depth = xcbinf2->depth;
|
||||
}
|
||||
else
|
||||
{
|
||||
const XCBQueryExtensionRep *rep_shm;
|
||||
const XCBQueryExtensionRep *rep_xrender;
|
||||
|
||||
xcbinf->depth = 32;
|
||||
{
|
||||
XCBConnSetupSuccessRep *rep;
|
||||
XCBSCREENIter iter_screen;
|
||||
|
||||
rep = XCBGetSetup(xcbinf->conn);
|
||||
iter_screen = XCBConnSetupSuccessRepRootsIter(rep);
|
||||
for (; iter_screen.rem ; XCBSCREENNext (&iter_screen)) {
|
||||
XCBDEPTHIter iter_depth;
|
||||
|
||||
iter_depth = XCBSCREENAllowedDepthsIter (iter_screen.data);
|
||||
for (; iter_depth.rem ; XCBDEPTHNext (&iter_depth)) {
|
||||
XCBVISUALTYPEIter iter_visual;
|
||||
|
||||
iter_visual = XCBDEPTHVisualsIter (iter_depth.data);
|
||||
for (; iter_visual.rem ; XCBVISUALTYPENext (&iter_visual)) {
|
||||
if (iter_visual.data->visual_id.id == vis.id)
|
||||
xcbinf->depth = iter_depth.data->depth;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xcbinf->can_do_shm = 0;
|
||||
|
||||
XCBPrefetchExtensionData (xcbinf->conn, &XCBShmId);
|
||||
XCBPrefetchExtensionData (xcbinf->conn, &XCBRenderId);
|
||||
rep_shm = XCBGetExtensionData(xcbinf->conn, &XCBShmId);
|
||||
rep_xrender = XCBGetExtensionData(xcbinf->conn, &XCBRenderId);
|
||||
|
||||
if (rep_shm && rep_xrender && rep_shm->present && rep_xrender->present) {
|
||||
XCBShmSegmentInfo shm_info;
|
||||
XCBImage *xcbim;
|
||||
|
||||
shm_info.shmseg = XCBShmSEGNew(xcbinf->conn);
|
||||
xcbim = XCBImageSHMCreate(xcbinf->conn, xcbinf->depth, ZPixmap, NULL, 1, 1);
|
||||
if (xcbim) {
|
||||
shm_info.shmid = shmget(IPC_PRIVATE, xcbim->bytes_per_line * xcbim->height, IPC_CREAT | 0777);
|
||||
if (shm_info.shmid >= 0) {
|
||||
shm_info.shmaddr = xcbim->data = shmat(shm_info.shmid, 0, 0);
|
||||
if ((shm_info.shmaddr != NULL) && (shm_info.shmaddr != (void *) -1)) {
|
||||
/*
|
||||
* FIXME: no error mechanism
|
||||
*/
|
||||
/* XErrorHandler ph; */
|
||||
|
||||
XCBSync(xcbinf->conn, 0);
|
||||
_xcb_err = 0;
|
||||
/* ph = XSetErrorHandler((XErrorHandler)_tmp_xcb_err); */
|
||||
XCBShmAttach(xcbinf->conn, shm_info.shmseg, shm_info.shmid, 0);
|
||||
XCBSync(xcbinf->conn, 0);
|
||||
/* XSetErrorHandler((XErrorHandler)ph); */
|
||||
if (!_xcb_err) xcbinf->can_do_shm = 1;
|
||||
shmdt(shm_info.shmaddr);
|
||||
}
|
||||
shmctl(shm_info.shmid, IPC_RMID, 0);
|
||||
}
|
||||
XCBImageSHMDestroy(xcbim);
|
||||
}
|
||||
}
|
||||
}
|
||||
_image_info_list = evas_list_prepend(_image_info_list, xcbinf);
|
||||
return xcbinf;
|
||||
}
|
||||
|
||||
void
|
||||
_xr_image_info_free(XCBimage_Info *xcbinf)
|
||||
{
|
||||
if (xcbinf->pool) XCBSync(xcbinf->conn, 0);
|
||||
_xr_image_info_pool_flush(xcbinf, 0, 0);
|
||||
xcbinf->references--;
|
||||
if (xcbinf->references != 0) return;
|
||||
_xr_render_surface_free(xcbinf->mul);
|
||||
free(xcbinf);
|
||||
_image_info_list = evas_list_remove(_image_info_list, xcbinf);
|
||||
}
|
||||
|
||||
void
|
||||
_xr_image_info_pool_flush(XCBimage_Info *xcbinf, int max_num, int max_mem)
|
||||
{
|
||||
if ((xcbinf->pool_mem <= max_mem) && (evas_list_count(xcbinf->pool) <= max_num)) return;
|
||||
while ((xcbinf->pool_mem > max_mem) || (evas_list_count(xcbinf->pool) > max_num))
|
||||
{
|
||||
XCBimage_Image *xcbim;
|
||||
|
||||
if (!xcbinf->pool) break;
|
||||
xcbim = xcbinf->pool->data;
|
||||
_xr_image_free(xcbim);
|
||||
}
|
||||
}
|
||||
|
||||
XCBimage_Image *
|
||||
_xr_image_new(XCBimage_Info *xcbinf, int w, int h, int depth)
|
||||
{
|
||||
XCBimage_Image *xcbim, *xcbim2;
|
||||
Evas_List *l;
|
||||
|
||||
xcbim2 = NULL;
|
||||
for (l = xcbinf->pool; l; l = l->next)
|
||||
{
|
||||
xcbim = l->data;
|
||||
if ((xcbim->w >= w) && (xcbim->h >= h) && (xcbim->depth == depth) && (xcbim->available))
|
||||
{
|
||||
if (!xcbim2) xcbim2 = xcbim;
|
||||
else if ((xcbim->w * xcbim->h) < (xcbim2->w * xcbim2->h)) xcbim2 = xcbim;
|
||||
}
|
||||
}
|
||||
if (xcbim2)
|
||||
{
|
||||
xcbim2->available = 0;
|
||||
return xcbim2;
|
||||
}
|
||||
xcbim = calloc(1, sizeof(XCBimage_Image));
|
||||
if (xcbim)
|
||||
{
|
||||
xcbim->xcbinf = xcbinf;
|
||||
xcbim->w = w;
|
||||
xcbim->h = h;
|
||||
xcbim->depth = depth;
|
||||
xcbim->available = 0;
|
||||
if (xcbim->xcbinf->can_do_shm)
|
||||
{
|
||||
xcbim->shm_info = calloc(1, sizeof(XCBShmSegmentInfo));
|
||||
if (xcbim->shm_info)
|
||||
{
|
||||
xcbim->shm_info->shmseg = XCBShmSEGNew(xcbinf->conn);
|
||||
xcbim->xcbim = XCBImageSHMCreate(xcbim->xcbinf->conn, xcbim->depth, ZPixmap, NULL, xcbim->w, xcbim->h);
|
||||
if (xcbim->xcbim)
|
||||
{
|
||||
xcbim->shm_info->shmid = shmget(IPC_PRIVATE, xcbim->xcbim->bytes_per_line * xcbim->xcbim->height, IPC_CREAT | 0777);
|
||||
if (xcbim->shm_info->shmid >= 0)
|
||||
{
|
||||
xcbim->shm_info->shmaddr = xcbim->xcbim->data = shmat(xcbim->shm_info->shmid, 0, 0);
|
||||
if ((xcbim->shm_info->shmaddr) && (xcbim->shm_info->shmaddr != (void *) -1))
|
||||
{
|
||||
/*
|
||||
* FIXME: no error mechanism
|
||||
*/
|
||||
/* XErrorHandler ph; */
|
||||
|
||||
XCBSync(xcbim->xcbinf->conn, 0);
|
||||
_xcb_err = 0;
|
||||
/* ph = XSetErrorHandler((XErrorHandler)_tmp_xcb_err); */
|
||||
XCBShmAttach(xcbim->xcbinf->conn, xcbim->shm_info->shmseg, xcbim->shm_info->shmid, 0);
|
||||
XCBSync(xcbim->xcbinf->conn, 0);
|
||||
/* XSetErrorHandler((XErrorHandler)ph); */
|
||||
if (!_xcb_err) goto xcbim_ok;
|
||||
shmdt(xcbim->shm_info->shmaddr);
|
||||
}
|
||||
shmctl(xcbim->shm_info->shmid, IPC_RMID, 0);
|
||||
}
|
||||
XCBImageSHMDestroy(xcbim->xcbim);
|
||||
}
|
||||
free(xcbim->shm_info);
|
||||
xcbim->shm_info = NULL;
|
||||
}
|
||||
}
|
||||
xcbim->xcbim = XCBImageCreate(xcbim->xcbinf->conn, xcbim->depth, ZPixmap, 0, NULL, xcbim->w, xcbim->h, 32, 0);
|
||||
if (!xcbim->xcbim)
|
||||
{
|
||||
free(xcbim);
|
||||
return NULL;
|
||||
}
|
||||
xcbim->xcbim->data = malloc(xcbim->xcbim->bytes_per_line * xcbim->xcbim->height);
|
||||
if (!xcbim->xcbim->data)
|
||||
{
|
||||
XCBImageDestroy(xcbim->xcbim);
|
||||
free(xcbim);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
xcbim_ok:
|
||||
_xr_image_info_pool_flush(xcbinf, 32, (1600 * 1200 * 32 * 2));
|
||||
|
||||
xcbim->line_bytes = xcbim->xcbim->bytes_per_line;
|
||||
xcbim->data = (void *)(xcbim->xcbim->data);
|
||||
xcbinf->pool_mem += (xcbim->w * xcbim->h * xcbim->depth);
|
||||
xcbinf->pool = evas_list_append(xcbinf->pool, xcbim);
|
||||
return xcbim;
|
||||
}
|
||||
|
||||
void
|
||||
_xr_image_free(XCBimage_Image *xcbim)
|
||||
{
|
||||
if (xcbim->shm_info)
|
||||
{
|
||||
if (!xcbim->available) XCBSync(xcbim->xcbinf->conn, 0);
|
||||
XCBShmDetach(xcbim->xcbinf->conn, xcbim->shm_info->shmseg);
|
||||
XCBImageSHMDestroy(xcbim->xcbim);
|
||||
shmdt(xcbim->shm_info->shmaddr);
|
||||
shmctl(xcbim->shm_info->shmid, IPC_RMID, 0);
|
||||
free(xcbim->shm_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(xcbim->xcbim->data);
|
||||
xcbim->xcbim->data = NULL;
|
||||
XCBImageDestroy(xcbim->xcbim);
|
||||
}
|
||||
xcbim->xcbinf->pool_mem -= (xcbim->w * xcbim->h * xcbim->depth);
|
||||
xcbim->xcbinf->pool = evas_list_remove(xcbim->xcbinf->pool, xcbim);
|
||||
free(xcbim);
|
||||
}
|
||||
|
||||
void
|
||||
_xr_image_put(XCBimage_Image *xcbim, XCBDRAWABLE draw, int x, int y, int w, int h)
|
||||
{
|
||||
XCBGCONTEXT gc;
|
||||
|
||||
gc = XCBGCONTEXTNew(xcbim->xcbinf->conn);
|
||||
XCBCreateGC(xcbim->xcbinf->conn, gc, draw, 0, NULL);
|
||||
if (xcbim->shm_info)
|
||||
{
|
||||
XCBImageSHMPut (xcbim->xcbinf->conn, draw, gc,
|
||||
xcbim->xcbim, *xcbim->shm_info,
|
||||
0, 0,
|
||||
x, y,
|
||||
xcbim->xcbim->width, xcbim->xcbim->height,
|
||||
0);
|
||||
/* XCBShmPutImage(xcbim->xcbinf->conn, draw, gc, */
|
||||
/* xcbim->xcbim->width, xcbim->xcbim->height, */
|
||||
/* 0, 0, */
|
||||
/* w, h, */
|
||||
/* x, y, */
|
||||
/* xcbim->xcbim->depth, xcbim->xcbim->format, */
|
||||
/* 0, */
|
||||
/* xcbim->shm_info->shmseg, */
|
||||
/* xcbim->xcbim->data - xcbim->shm_info->shmaddr); */
|
||||
XCBSync(xcbim->xcbinf->conn, 0);
|
||||
}
|
||||
else
|
||||
XCBImagePut(xcbim->xcbinf->conn, draw, gc, xcbim->xcbim, 0, 0, x, y, w, h);
|
||||
xcbim->available = 1;
|
||||
XCBFreeGC(xcbim->xcbinf->conn, gc);
|
||||
}
|
|
@ -0,0 +1,645 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_macros.h"
|
||||
#include "evas_private.h"
|
||||
#include "evas_engine.h"
|
||||
#include "Evas_Engine_XRender_Xcb.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
XCBRenderPICTFORMINFO *
|
||||
XCBRenderFindVisualFormat (XCBConnection *c, XCBVISUALID visual)
|
||||
{
|
||||
XCBRenderQueryPictFormatsCookie cookie;
|
||||
XCBRenderQueryPictFormatsRep *rep;
|
||||
XCBRenderPICTSCREENIter screen_iter;
|
||||
XCBRenderPICTFORMAT format = { 0 };
|
||||
|
||||
cookie = XCBRenderQueryPictFormats (c);
|
||||
rep = XCBRenderQueryPictFormatsReply (c, cookie, NULL);
|
||||
if (!rep)
|
||||
return NULL;
|
||||
|
||||
screen_iter = XCBRenderQueryPictFormatsScreensIter (rep);
|
||||
for (; screen_iter.rem; XCBRenderPICTSCREENNext (&screen_iter)) {
|
||||
XCBRenderPICTDEPTHIter depth_iter;
|
||||
|
||||
depth_iter = XCBRenderPICTSCREENDepthsIter (screen_iter.data);
|
||||
for (; depth_iter.rem; XCBRenderPICTDEPTHNext (&depth_iter)) {
|
||||
XCBRenderPICTVISUALIter visual_iter;
|
||||
|
||||
visual_iter = XCBRenderPICTDEPTHVisualsIter (depth_iter.data);
|
||||
for (; visual_iter.rem; XCBRenderPICTVISUALNext (&visual_iter)) {
|
||||
if (visual.id == visual_iter.data->visual.id) {
|
||||
format = visual_iter.data->format;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (format.xid != 0) {
|
||||
XCBRenderPICTFORMINFOIter forminfo_iter;
|
||||
|
||||
forminfo_iter = XCBRenderQueryPictFormatsFormatsIter (rep);
|
||||
for (; forminfo_iter.rem; XCBRenderPICTFORMINFONext (&forminfo_iter)) {
|
||||
if (forminfo_iter.data->id.xid == format.xid) {
|
||||
XCBRenderPICTFORMINFO *forminfo;
|
||||
|
||||
forminfo = (XCBRenderPICTFORMINFO *)malloc (sizeof (XCBRenderPICTFORMINFO));
|
||||
memcpy (forminfo, forminfo_iter.data, sizeof (XCBRenderPICTFORMINFO));
|
||||
free (rep);
|
||||
|
||||
return forminfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
free (rep);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XCBrender_Surface *
|
||||
_xr_render_surface_new(XCBimage_Info *xcbinf, int w, int h, XCBRenderPICTFORMINFO *fmt, int alpha)
|
||||
{
|
||||
XCBrender_Surface *rs;
|
||||
CARD32 mask;
|
||||
CARD32 values[3];
|
||||
|
||||
rs = calloc(1, sizeof(XCBrender_Surface));
|
||||
if (!rs) return NULL;
|
||||
rs->xcbinf = xcbinf;
|
||||
rs->w = w;
|
||||
rs->h = h;
|
||||
rs->fmt = fmt;
|
||||
rs->alpha = alpha;
|
||||
rs->depth = fmt->depth;
|
||||
rs->allocated = 1;
|
||||
rs->draw.pixmap = XCBPIXMAPNew(xcbinf->conn);
|
||||
XCBCreatePixmap(xcbinf->conn, fmt->depth, rs->draw.pixmap, xcbinf->root, w, h);
|
||||
rs->xcbinf->references++;
|
||||
mask = XCBRenderCPRepeat | XCBRenderCPDither | XCBRenderCPComponentAlpha;
|
||||
values[0] = 0;
|
||||
values[1] = 0;
|
||||
values[2] = 0;
|
||||
rs->pic = XCBRenderPICTURENew(xcbinf->conn);
|
||||
XCBRenderCreatePicture(xcbinf->conn, rs->pic, rs->draw, fmt->id, mask, values);
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
XCBrender_Surface *
|
||||
_xr_render_surface_adopt(XCBimage_Info *xcbinf, XCBDRAWABLE draw, int w, int h, int alpha)
|
||||
{
|
||||
XCBrender_Surface *rs;
|
||||
XCBRenderPICTFORMINFO *fmt;
|
||||
CARD32 mask;
|
||||
CARD32 values[3];
|
||||
|
||||
rs = calloc(1, sizeof(XCBrender_Surface));
|
||||
|
||||
fmt = XCBRenderFindVisualFormat(xcbinf->conn, xcbinf->vis);
|
||||
rs->xcbinf = xcbinf;
|
||||
rs->w = w;
|
||||
rs->h = h;
|
||||
/* if (fmt->depth == xcbinf->fmt32->depth) */
|
||||
/* rs->fmt = xcbinf->fmt32; */
|
||||
/* else if (fmt->depth == xcbinf->fmt24->depth) */
|
||||
/* rs->fmt = xcbinf->fmt24; */
|
||||
/* else if (fmt->depth == xcbinf->fmt8->depth) */
|
||||
/* rs->fmt = xcbinf->fmt8; */
|
||||
/* else if (fmt->depth == xcbinf->fmt4->depth) */
|
||||
/* rs->fmt = xcbinf->fmt4; */
|
||||
/* else */
|
||||
/* rs->fmt = xcbinf->fmt1; */
|
||||
/* free(fmt); */
|
||||
|
||||
rs->fmt = fmt;
|
||||
|
||||
rs->alpha = alpha;
|
||||
rs->depth = fmt->depth;
|
||||
if (fmt->depth == 32) rs->alpha = 1;
|
||||
rs->allocated = 0;
|
||||
rs->draw = draw;
|
||||
rs->xcbinf->references++;
|
||||
mask = XCBRenderCPRepeat | XCBRenderCPDither | XCBRenderCPComponentAlpha;
|
||||
values[0] = 0;
|
||||
values[1] = 0;
|
||||
values[2] = 0;
|
||||
rs->pic = XCBRenderPICTURENew(xcbinf->conn);
|
||||
XCBRenderCreatePicture(xcbinf->conn, rs->pic, rs->draw, fmt->id, mask, values);
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
XCBrender_Surface *
|
||||
_xr_render_surface_format_adopt(XCBimage_Info *xcbinf, XCBDRAWABLE draw, int w, int h, XCBRenderPICTFORMINFO *fmt, int alpha)
|
||||
{
|
||||
XCBrender_Surface *rs;
|
||||
CARD32 mask;
|
||||
CARD32 values[3];
|
||||
|
||||
rs = calloc(1, sizeof(XCBrender_Surface));
|
||||
rs->xcbinf = xcbinf;
|
||||
rs->w = w;
|
||||
rs->h = h;
|
||||
rs->fmt = fmt;
|
||||
rs->alpha = alpha;
|
||||
rs->depth = fmt->depth;
|
||||
if (fmt->depth == 32) rs->alpha = 1;
|
||||
rs->xcbinf->references++;
|
||||
rs->allocated = 0;
|
||||
rs->draw = draw;
|
||||
mask = XCBRenderCPRepeat | XCBRenderCPDither | XCBRenderCPComponentAlpha;
|
||||
values[0] = 0;
|
||||
values[1] = 0;
|
||||
values[2] = 0;
|
||||
rs->pic = XCBRenderPICTURENew(xcbinf->conn);
|
||||
XCBRenderCreatePicture(xcbinf->conn, rs->pic, rs->draw, fmt->id, mask, values);
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
void
|
||||
_xr_render_surface_free(XCBrender_Surface *rs)
|
||||
{
|
||||
if (rs->allocated) XCBFreePixmap(rs->xcbinf->conn, rs->draw.pixmap);
|
||||
XCBRenderFreePicture(rs->xcbinf->conn, rs->pic);
|
||||
_xr_image_info_free(rs->xcbinf);
|
||||
rs->xcbinf = NULL;
|
||||
free(rs);
|
||||
}
|
||||
|
||||
void
|
||||
_xr_render_surface_repeat_set(XCBrender_Surface *rs, int repeat)
|
||||
{
|
||||
CARD32 mask;
|
||||
CARD32 value[1];
|
||||
|
||||
mask = XCBRenderCPRepeat;
|
||||
value[0] = repeat;
|
||||
XCBRenderChangePicture(rs->xcbinf->conn, rs->pic, mask, value);
|
||||
}
|
||||
|
||||
void
|
||||
_xr_render_surface_solid_rectangle_set(XCBrender_Surface *rs, int r, int g, int b, int a, int x, int y, int w, int h)
|
||||
{
|
||||
XCBRenderCOLOR col;
|
||||
XCBRECTANGLE rect;
|
||||
int aa;
|
||||
|
||||
aa = a +1;
|
||||
r = (r * aa) >> 8;
|
||||
g = (g * aa) >> 8;
|
||||
b = (b * aa) >> 8;
|
||||
col.red = (r << 8) | r;
|
||||
col.green = (g << 8) | g;
|
||||
col.blue = (b << 8) | b;
|
||||
col.alpha = (a << 8) | a;
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = w;
|
||||
rect.height = h;
|
||||
XCBRenderFillRectangles(rs->xcbinf->conn, XCBRenderPictOpSrc, rs->pic, col, 1, &rect);
|
||||
}
|
||||
|
||||
void
|
||||
_xr_render_surface_argb_pixels_fill(XCBrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h)
|
||||
{
|
||||
XCBimage_Image *xcbim;
|
||||
unsigned int *p, *sp, *sple, *spe;
|
||||
unsigned int jump, sjump;
|
||||
unsigned int a, r, g, b, aa;
|
||||
|
||||
xcbim = _xr_image_new(rs->xcbinf, w, h, rs->depth);
|
||||
if (!xcbim) return;
|
||||
p = (unsigned int *)xcbim->data;
|
||||
sp = ((unsigned int *)pixels) + (y * sw) + x;
|
||||
jump = ((xcbim->line_bytes / 4) - w);
|
||||
sjump = sw - w;
|
||||
spe = sp + ((h - 1) * sw) + w;
|
||||
if
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
(xcbim->xcbim->image_byte_order == LSBFirst)
|
||||
#else
|
||||
(xcbim->xcbim->image_byte_order == MSBFirst)
|
||||
#endif
|
||||
{
|
||||
while (sp < spe)
|
||||
{
|
||||
sple = sp + w;
|
||||
while (sp < sple)
|
||||
{
|
||||
switch (a = A_VAL(sp))
|
||||
{
|
||||
case 0:
|
||||
*p = 0;
|
||||
break;
|
||||
case 255:
|
||||
*p = (B_VAL(sp) << 24) | (G_VAL(sp) << 16) | (R_VAL(sp) << 8) | 0xff;
|
||||
break;
|
||||
default:
|
||||
aa = a + 1;
|
||||
r = ((R_VAL(sp)) * aa) >> 8;
|
||||
g = ((G_VAL(sp)) * aa) >> 8;
|
||||
b = ((B_VAL(sp)) * aa) >> 8;
|
||||
*p = (b << 24) | (g << 16) | (r << 8) | a;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
sp++;
|
||||
}
|
||||
p += jump;
|
||||
sp += sjump;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (sp < spe)
|
||||
{
|
||||
sple = sp + w;
|
||||
while (sp < sple)
|
||||
{
|
||||
switch (a = A_VAL(sp))
|
||||
{
|
||||
case 0:
|
||||
*p = 0;
|
||||
break;
|
||||
case 255:
|
||||
*p = *sp;
|
||||
break;
|
||||
default:
|
||||
aa = a + 1;
|
||||
r = ((R_VAL(sp)) * aa) >> 8;
|
||||
g = ((G_VAL(sp)) * aa) >> 8;
|
||||
b = ((B_VAL(sp)) * aa) >> 8;
|
||||
*p = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
sp++;
|
||||
}
|
||||
p += jump;
|
||||
sp += sjump;
|
||||
}
|
||||
}
|
||||
_xr_image_put(xcbim, rs->draw, x, y, w, h);
|
||||
}
|
||||
|
||||
void
|
||||
_xr_render_surface_rgb_pixels_fill(XCBrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h)
|
||||
{
|
||||
XCBimage_Image *xcbim;
|
||||
unsigned int *p, *sp, *sple, *spe;
|
||||
unsigned int jump, sjump;
|
||||
|
||||
xcbim = _xr_image_new(rs->xcbinf, w, h, rs->depth);
|
||||
if (!xcbim) return;
|
||||
p = (unsigned int *)xcbim->data;
|
||||
sp = ((unsigned int *)pixels) + (y * sw) + x;
|
||||
jump = ((xcbim->line_bytes / 4) - w);
|
||||
sjump = sw - w;
|
||||
spe = sp + ((h - 1) * sw) + w;
|
||||
if
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
(xcbim->xcbim->image_byte_order == LSBFirst)
|
||||
#else
|
||||
(xcbim->xcbim->image_byte_order == MSBFirst)
|
||||
#endif
|
||||
{
|
||||
while (sp < spe)
|
||||
{
|
||||
sple = sp + w;
|
||||
while (sp < sple)
|
||||
{
|
||||
*p = ((B_VAL(sp)) << 24) | ((G_VAL(sp)) << 16) | ((R_VAL(sp)) << 8) | 0x000000ff;
|
||||
p++;
|
||||
sp++;
|
||||
}
|
||||
p += jump;
|
||||
sp += sjump;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (sp < spe)
|
||||
{
|
||||
sple = sp + w;
|
||||
while (sp < sple)
|
||||
{
|
||||
*p = 0xff000000 | ((R_VAL(sp)) << 16) | ((G_VAL(sp)) << 8) | (B_VAL(sp));
|
||||
p++;
|
||||
sp++;
|
||||
}
|
||||
p += jump;
|
||||
sp += sjump;
|
||||
}
|
||||
}
|
||||
_xr_image_put(xcbim, rs->draw, x, y, w, h);
|
||||
}
|
||||
|
||||
void
|
||||
_xr_render_surface_clips_set(XCBrender_Surface *rs, RGBA_Draw_Context *dc, int rx, int ry, int rw, int rh)
|
||||
{
|
||||
int num = 0;
|
||||
XCBRECTANGLE *rect = NULL;
|
||||
|
||||
if ((dc) && (dc->clip.use))
|
||||
{
|
||||
RECTS_CLIP_TO_RECT(rx, ry, rw, rh,
|
||||
dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
|
||||
}
|
||||
if ((!dc) || (!dc->cutout.rects))
|
||||
{
|
||||
rect = malloc(sizeof(XCBRECTANGLE));
|
||||
if (!rect) return;
|
||||
rect->x = rx;
|
||||
rect->y = ry;
|
||||
rect->width = rw;
|
||||
rect->height = rh;
|
||||
num = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
Cutout_Rect *rects, *r;
|
||||
Evas_Object_List *l;
|
||||
|
||||
rects = evas_common_draw_context_apply_cutouts(dc);
|
||||
for (num = 0, l = (Evas_Object_List *)rects; l; l = l->next) num++;
|
||||
rect = malloc(num * sizeof(XCBRECTANGLE));
|
||||
if (!rect) return;
|
||||
for (i = 0, l = (Evas_Object_List *)rects; l; l = l->next, i++)
|
||||
{
|
||||
r = (Cutout_Rect *)l;
|
||||
rect[i].x = r->x;
|
||||
rect[i].y = r->y;
|
||||
rect[i].width = r->w;
|
||||
rect[i].height = r->h;
|
||||
}
|
||||
evas_common_draw_context_apply_free_cutouts(rects);
|
||||
}
|
||||
if (!rect) return;
|
||||
XCBRenderSetPictureClipRectangles(rs->xcbinf->conn, rs->pic, 0, 0, num, rect);
|
||||
free(rect);
|
||||
}
|
||||
|
||||
// when color multiplier is used want: instead
|
||||
// CA src IN mask SRC temp; non-CA temp OVER dst. - i think. need to check.
|
||||
void
|
||||
_xr_render_surface_composite(XCBrender_Surface *srs, XCBrender_Surface *drs, RGBA_Draw_Context *dc, int sx, int sy, int sw, int sh, int x, int y, int w, int h, int smooth)
|
||||
{
|
||||
XCBRenderTRANSFORM xf;
|
||||
XCBRenderPICTURE mask;
|
||||
CARD32 value_mask;
|
||||
CARD32 value_list[1];
|
||||
int r, g, b, a;
|
||||
int sf;
|
||||
int op;
|
||||
|
||||
if ((sw <= 0) || (sh <= 0) || (w <= 0) || (h <= 0)) return;
|
||||
|
||||
sf = MAX(sw, sh);
|
||||
#define BMAX 26
|
||||
if (sf <= 8 ) sf = 1 << (BMAX - 3);
|
||||
else if (sf <= 16 ) sf = 1 << (BMAX - 4);
|
||||
else if (sf <= 32 ) sf = 1 << (BMAX - 5);
|
||||
else if (sf <= 64 ) sf = 1 << (BMAX - 6);
|
||||
else if (sf <= 128 ) sf = 1 << (BMAX - 7);
|
||||
else if (sf <= 256 ) sf = 1 << (BMAX - 8);
|
||||
else if (sf <= 512 ) sf = 1 << (BMAX - 9);
|
||||
else if (sf <= 1024 ) sf = 1 << (BMAX - 10);
|
||||
else if (sf <= 2048 ) sf = 1 << (BMAX - 11);
|
||||
else if (sf <= 4096 ) sf = 1 << (BMAX - 12);
|
||||
else if (sf <= 8192 ) sf = 1 << (BMAX - 13);
|
||||
else if (sf <= 16384) sf = 1 << (BMAX - 14);
|
||||
else sf = 1 << (BMAX - 15);
|
||||
|
||||
xf.matrix11 = (sf * sw) / w;
|
||||
xf.matrix12 = 0;
|
||||
xf.matrix13 = 0;
|
||||
|
||||
xf.matrix21 = 0;
|
||||
xf.matrix22 = (sf * sh) / h;
|
||||
xf.matrix23 = 0;
|
||||
|
||||
xf.matrix31 = 0;
|
||||
xf.matrix32 = 0;
|
||||
xf.matrix33 = sf;
|
||||
|
||||
op = XCBRenderPictOpSrc;
|
||||
if (srs->alpha) op = XCBRenderPictOpOver;
|
||||
mask.xid = 0;
|
||||
if ((dc) && (dc->mul.use))
|
||||
{
|
||||
r = (int)(R_VAL(&dc->mul.col));
|
||||
g = (int)(G_VAL(&dc->mul.col));
|
||||
b = (int)(B_VAL(&dc->mul.col));
|
||||
a = (int)(A_VAL(&dc->mul.col));
|
||||
if ((r != 0xff) || (g != 0xff) || (b != 0xff) || (a != 0xff))
|
||||
{
|
||||
if ((srs->xcbinf->mul_r != r) || (srs->xcbinf->mul_g != g) ||
|
||||
(srs->xcbinf->mul_b != b) || (srs->xcbinf->mul_a != a))
|
||||
{
|
||||
srs->xcbinf->mul_r = r;
|
||||
srs->xcbinf->mul_g = g;
|
||||
srs->xcbinf->mul_b = b;
|
||||
srs->xcbinf->mul_a = a;
|
||||
_xr_render_surface_solid_rectangle_set(srs->xcbinf->mul, r, g, b, a, 0, 0, 1, 1);
|
||||
}
|
||||
op = XCBRenderPictOpOver;
|
||||
mask = srs->xcbinf->mul->pic;
|
||||
}
|
||||
}
|
||||
|
||||
XCBRenderSetPictureTransform(srs->xcbinf->conn, srs->pic, xf);
|
||||
value_mask = XCBRenderCPClipMask;
|
||||
value_list[0] = 0;
|
||||
XCBRenderChangePicture(srs->xcbinf->conn, srs->pic, value_mask, value_list);
|
||||
XCBRenderChangePicture(srs->xcbinf->conn, drs->pic, value_mask, value_list);
|
||||
|
||||
if (smooth) XCBRenderSetPictureFilter(srs->xcbinf->conn, srs->pic, strlen("best"), "best", 0, NULL);
|
||||
else XCBRenderSetPictureFilter(srs->xcbinf->conn, srs->pic, strlen("nearest"), "nearest", 0, NULL);
|
||||
|
||||
_xr_render_surface_clips_set(drs, dc, x, y, w, h);
|
||||
XCBRenderComposite(srs->xcbinf->conn, op, srs->pic, mask, drs->pic,
|
||||
((sx * w) + (sw / 2)) / sw,
|
||||
((sy * h) + (sh / 2)) / sh,
|
||||
0, 0, x, y, w, h);
|
||||
}
|
||||
|
||||
void
|
||||
_xr_render_surface_copy(XCBrender_Surface *srs, XCBrender_Surface *drs, int sx, int sy, int x, int y, int w, int h)
|
||||
{
|
||||
XCBRenderTRANSFORM xf;
|
||||
XCBRenderPICTURE mask = { 0 };
|
||||
CARD32 value_mask;
|
||||
CARD32 value_list[1];
|
||||
|
||||
if ((w <= 0) || (h <= 0)) return;
|
||||
xf.matrix11 = 1;
|
||||
xf.matrix12 = 0;
|
||||
xf.matrix13 = 0;
|
||||
|
||||
xf.matrix21 = 0;
|
||||
xf.matrix22 = 1;
|
||||
xf.matrix23 = 0;
|
||||
|
||||
xf.matrix31 = 0;
|
||||
xf.matrix32 = 0;
|
||||
xf.matrix33 = 1;
|
||||
|
||||
XCBRenderSetPictureTransform(srs->xcbinf->conn, srs->pic, xf);
|
||||
value_mask = XCBRenderCPClipMask;
|
||||
value_list[0] = 0;
|
||||
XCBRenderChangePicture(srs->xcbinf->conn, srs->pic, value_mask, value_list);
|
||||
XCBRenderChangePicture(srs->xcbinf->conn, drs->pic, value_mask, value_list);
|
||||
XCBRenderSetPictureFilter(srs->xcbinf->conn, srs->pic, strlen("nearest"), "nearest", 0, NULL);
|
||||
|
||||
XCBRenderComposite(srs->xcbinf->conn, XCBRenderPictOpSrc, srs->pic, mask, drs->pic,
|
||||
sx, sy, 0, 0, x, y, w, h);
|
||||
}
|
||||
|
||||
void
|
||||
_xr_render_surface_rectangle_draw(XCBrender_Surface *rs, RGBA_Draw_Context *dc, int x, int y, int w, int h)
|
||||
{
|
||||
XCBRenderCOLOR col;
|
||||
XCBRECTANGLE rect;
|
||||
CARD32 value_mask;
|
||||
CARD32 value_list[1];
|
||||
int r, g, b, a, aa, op;
|
||||
|
||||
if ((w <= 0) || (h <= 0)) return;
|
||||
a = (dc->col.col >> 24) & 0xff;
|
||||
if (a == 0) return;
|
||||
r = (dc->col.col >> 16) & 0xff;
|
||||
g = (dc->col.col >> 8 ) & 0xff;
|
||||
b = (dc->col.col ) & 0xff;
|
||||
aa = a +1;
|
||||
r = (r * aa) >> 8;
|
||||
g = (g * aa) >> 8;
|
||||
b = (b * aa) >> 8;
|
||||
col.red = (r << 8) | r;
|
||||
col.green = (g << 8) | g;
|
||||
col.blue = (b << 8) | b;
|
||||
col.alpha = (a << 8) | a;
|
||||
op = XCBRenderPictOpSrc;
|
||||
if (a < 0xff) op = XCBRenderPictOpOver;
|
||||
value_mask = XCBRenderCPClipMask;
|
||||
value_list[0] = 0;
|
||||
XCBRenderChangePicture(rs->xcbinf->conn, rs->pic, value_mask, value_list);
|
||||
|
||||
_xr_render_surface_clips_set(rs, dc, x, y, w, h);
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = w;
|
||||
rect.height = h;
|
||||
XCBRenderFillRectangles(rs->xcbinf->conn, op, rs->pic, col, 1, &rect);
|
||||
}
|
||||
|
||||
void
|
||||
_xr_render_surface_line_draw(XCBrender_Surface *rs, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
/* CARD32 value_mask; */
|
||||
/* CARD32 value_list[1]; */
|
||||
/* int op; */
|
||||
|
||||
/* op = XCBRenderPictOpSrc; */
|
||||
/* value_mask = XCBRenderCPClipMask; */
|
||||
/* value_list[0] = 0; */
|
||||
/* XCBRenderChangePicture(rs->xcbinf->conn, rs->pic, value_mask, value_list); */
|
||||
/* _xr_render_surface_clips_set(rs, dc, 0, 0, rs->w, rs->h); */
|
||||
|
||||
/* { */
|
||||
/* int r, g, b, a; */
|
||||
/* XPointDouble poly[4]; */
|
||||
/* int dx, dy; */
|
||||
/* double len, ddx, ddy; */
|
||||
|
||||
/* dx = x2 - x1; */
|
||||
/* dy = y2 - y1; */
|
||||
/* len = sqrt((double)(dx * dx) + (double)(dy * dy)); */
|
||||
/* ddx = (0.5 * dx) / len; */
|
||||
/* ddy = (0.5 * dy) / len; */
|
||||
/* poly[0].x = (x1 + ddx); */
|
||||
/* poly[0].y = (y1 - ddy); */
|
||||
/* poly[1].x = (x2 + ddx); */
|
||||
/* poly[1].y = (y2 - ddy); */
|
||||
/* poly[2].x = (x2 - ddx); */
|
||||
/* poly[2].y = (y2 + ddy); */
|
||||
/* poly[3].x = (x1 - ddx); */
|
||||
/* poly[3].y = (y1 + ddy); */
|
||||
|
||||
/* a = (dc->col.col >> 24) & 0xff; */
|
||||
/* if (a == 0) return; */
|
||||
/* if (a < 0xff) op = XCBRenderPictOpOver; */
|
||||
/* r = (dc->col.col >> 16) & 0xff; */
|
||||
/* g = (dc->col.col >> 8 ) & 0xff; */
|
||||
/* b = (dc->col.col ) & 0xff; */
|
||||
/* if ((rs->xcbinf->mul_r != r) || (rs->xcbinf->mul_g != g) || */
|
||||
/* (rs->xcbinf->mul_b != b) || (rs->xcbinf->mul_a != a)) */
|
||||
/* { */
|
||||
/* rs->xcbinf->mul_r = r; */
|
||||
/* rs->xcbinf->mul_g = g; */
|
||||
/* rs->xcbinf->mul_b = b; */
|
||||
/* rs->xcbinf->mul_a = a; */
|
||||
/* _xr_render_surface_solid_rectangle_set(rs->xcbinf->mul, r, g, b, a, 0, 0, 1, 1); */
|
||||
/* } */
|
||||
/* XRenderCompositeDoublePoly(rs->xcbinf->conn, op, */
|
||||
/* rs->xcbinf->mul->pic, rs->pic, */
|
||||
/* rs->xcbinf->fmt8, 0, 0, 0, 0, */
|
||||
/* poly, 4, EvenOddRule); */
|
||||
/* } */
|
||||
}
|
||||
|
||||
void
|
||||
_xre_poly_draw(XCBrender_Surface *rs, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points)
|
||||
{
|
||||
/* RGBA_Polygon_Point *pt; */
|
||||
/* int i, num; */
|
||||
/* XPointDouble *pts; */
|
||||
/* int r, g, b, a; */
|
||||
/* CARD32 value_mask; */
|
||||
/* CARD32 value_list[1]; */
|
||||
/* int op; */
|
||||
|
||||
/* op = XCBRenderPictOpSrc; */
|
||||
/* num = 0; */
|
||||
/* for (pt = points; pt; pt = (RGBA_Polygon_Point *)(((Evas_Object_List *)pt)->next)) num++; */
|
||||
/* if (num < 3) return; */
|
||||
/* a = (dc->col.col >> 24) & 0xff; */
|
||||
/* if (a == 0) return; */
|
||||
/* if (a < 0xff) op = XCBRenderPictOpOver; */
|
||||
/* r = (dc->col.col >> 16) & 0xff; */
|
||||
/* g = (dc->col.col >> 8 ) & 0xff; */
|
||||
/* b = (dc->col.col ) & 0xff; */
|
||||
/* if ((rs->xcbinf->mul_r != r) || (rs->xcbinf->mul_g != g) || */
|
||||
/* (rs->xcbinf->mul_b != b) || (rs->xcbinf->mul_a != a)) */
|
||||
/* { */
|
||||
/* rs->xcbinf->mul_r = r; */
|
||||
/* rs->xcbinf->mul_g = g; */
|
||||
/* rs->xcbinf->mul_b = b; */
|
||||
/* rs->xcbinf->mul_a = a; */
|
||||
/* _xr_render_surface_solid_rectangle_set(rs->xcbinf->mul, r, g, b, a, 0, 0, 1, 1); */
|
||||
/* } */
|
||||
/* pts = malloc(num * sizeof(XPointDouble)); */
|
||||
/* if (!pts) return; */
|
||||
/* i = 0; */
|
||||
/* for (pt = points; pt; pt = (RGBA_Polygon_Point *)(((Evas_Object_List *)pt)->next)) */
|
||||
/* { */
|
||||
/* if (i < num) */
|
||||
/* { */
|
||||
/* pts[i].x = pt->x; */
|
||||
/* pts[i].y = pt->y; */
|
||||
/* i++; */
|
||||
/* } */
|
||||
/* } */
|
||||
/* value_mask = XCBRenderCPClipMask; */
|
||||
/* value_list[0] = 0; */
|
||||
/* XCBRenderChangePicture(rs->xcbinf->conn, rs->pic, value_mask, value_list); */
|
||||
|
||||
/* _xr_render_surface_clips_set(rs, dc, 0, 0, rs->w, rs->h); */
|
||||
/* XRenderCompositeDoublePoly(rs->xcbinf->conn, op, */
|
||||
/* rs->xcbinf->mul->pic, rs->pic, */
|
||||
/* rs->xcbinf->fmt8, 0, 0, 0, 0, */
|
||||
/* pts, num, Complex); */
|
||||
/* free(pts); */
|
||||
}
|
||||
|
Loading…
Reference in New Issue