From 2b2a800ad6450b6c74beb3d5de97e6bc064dcc01 Mon Sep 17 00:00:00 2001 From: doursse Date: Sun, 20 Mar 2005 23:44:22 +0000 Subject: [PATCH] xcb port SVN revision: 13822 --- legacy/evas/configure.in | 72 + legacy/evas/src/bin/Makefile.am | 19 + legacy/evas/src/bin/evas_software_xcb_main.c | 304 ++++ .../src/bin/evas_software_xcb_perf_load.c | 245 +++ .../src/bin/evas_software_xcb_perf_test.c | 219 +++ .../evas/src/lib/Evas_Engine_Software_Xcb.h | 58 + legacy/evas/src/lib/Makefile.am | 14 +- legacy/evas/src/lib/canvas/evas_main.c | 16 +- legacy/evas/src/lib/engines/Makefile.am | 1 + .../src/lib/engines/software_xcb/Makefile.am | 37 + .../lib/engines/software_xcb/evas_engine.c | 1277 ++++++++++++++ .../lib/engines/software_xcb/evas_engine.h | 215 +++ .../lib/engines/software_xcb/evas_outbuf.c | 1504 +++++++++++++++++ .../engines/software_xcb/evas_xcb_buffer.c | 231 +++ .../lib/engines/software_xcb/evas_xcb_color.c | 359 ++++ .../lib/engines/software_xcb/evas_xcb_main.c | 9 + legacy/evas/src/lib/include/Makefile.am | 1 + .../include/evas_engine_api_software_xcb.h | 7 + legacy/evas/src/lib/include/evas_private.h | 1 + 19 files changed, 4587 insertions(+), 2 deletions(-) create mode 100644 legacy/evas/src/bin/evas_software_xcb_main.c create mode 100644 legacy/evas/src/bin/evas_software_xcb_perf_load.c create mode 100644 legacy/evas/src/bin/evas_software_xcb_perf_test.c create mode 100644 legacy/evas/src/lib/Evas_Engine_Software_Xcb.h create mode 100644 legacy/evas/src/lib/engines/software_xcb/Makefile.am create mode 100644 legacy/evas/src/lib/engines/software_xcb/evas_engine.c create mode 100644 legacy/evas/src/lib/engines/software_xcb/evas_engine.h create mode 100644 legacy/evas/src/lib/engines/software_xcb/evas_outbuf.c create mode 100644 legacy/evas/src/lib/engines/software_xcb/evas_xcb_buffer.c create mode 100644 legacy/evas/src/lib/engines/software_xcb/evas_xcb_color.c create mode 100644 legacy/evas/src/lib/engines/software_xcb/evas_xcb_main.c create mode 100644 legacy/evas/src/lib/include/evas_engine_api_software_xcb.h diff --git a/legacy/evas/configure.in b/legacy/evas/configure.in index a9398fe549..c1249bd7f5 100644 --- a/legacy/evas/configure.in +++ b/legacy/evas/configure.in @@ -92,6 +92,9 @@ AC_DEFINE_UNQUOTED(PACKAGE_SOURCE_DIR, "${packagesrcdir}", [Source Code Director x_dir="" x_cflags="" x_libs="" +xcb_dir="" +xcb_cflags="" +xcb_libs="" gl_dir="" gl_cflags="" gl_libs="" @@ -170,6 +173,69 @@ else AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_X11, false) fi +####################################### +## Check if we should build the software_xcb engine +have_evas_software_xcb="no"; +ENGINE_SOFTWARE_XCB_PRG=""; + +## Automatic check... +PKG_CHECK_MODULES( + XCB, + xcb-image, + [AC_CHECK_HEADER( + X11/X.h, + [have_evas_software_xcb="yes"], + [have_evas_software_xcb="no"])], + [ have_evas_software_xcb="no" ]) + +PKG_CHECK_MODULES( + XCB_ICCCM, + xcb-icccm, + [ have_evas_software_xcb="yes" ], + [ have_evas_software_xcb="no" ]) + +## Manual override +AC_MSG_CHECKING(whether software xcb backend is to be built) +AC_ARG_ENABLE(software-xcb, [ --enable-software-xcb enable the Software XCB rendering backend], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_evas_software_xcb="yes" + else + AC_MSG_RESULT(no) + have_evas_software_xcb="no" + fi + ], [ + AC_MSG_RESULT($have_evas_software_xcb) + ] +) +if test "x$have_evas_software_xcb" = "xyes"; then + AC_PATH_XTRA + + PKG_CHECK_MODULES( + XCB_ICCCM, + xcb-icccm) + + PKG_CHECK_MODULES( + XCB, + xcb-image, + [AC_CHECK_HEADER( + X11/X.h, + [AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_XCB, true) + AC_DEFINE(BUILD_ENGINE_SOFTWARE_XCB, 1, [Software XCB Rendering Backend]) + xcb_dir=${x_dir:-/usr/X11R6} + xcb_cflags="${x_cflags:--I${x_includes:-$x_dir/include}} $XCB_CFLAGS $XCB_ICCCM_CFLAGS" + xcb_libs="${x_libs:--L${x_libraries:-$x_dir/lib}} $XCB_LIBS $XCB_ICCCM_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) + have_evas_software_xcb="no"])], + [AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_XCB, false) + AC_MSG_RESULT(disabling software XCB engine) + have_evas_software_xcb="no" ]) +else + AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_XCB, false) +fi + ####################################### ## Check if we should build the directfb engine have_evas_directfb="no"; @@ -1413,6 +1479,9 @@ AC_SUBST(freetype_libs) AC_SUBST(x_cflags) AC_SUBST(x_libs) +AC_SUBST(xcb_cflags) +AC_SUBST(xcb_libs) + AC_SUBST(gl_cflags) AC_SUBST(gl_libs) @@ -1443,6 +1512,7 @@ fi AC_SUBST(requirements) AC_SUBST(ENGINE_SOFTWARE_X11_PRG) +AC_SUBST(ENGINE_SOFTWARE_XCB_PRG) AC_SUBST(ENGINE_DIRECTFB_PRG) AC_SUBST(ENGINE_FB_PRG) AC_SUBST(ENGINE_BUFFER_PRG) @@ -1470,6 +1540,7 @@ src/lib/imaging/Makefile src/lib/engines/Makefile src/lib/engines/common/Makefile src/lib/engines/software_x11/Makefile +src/lib/engines/software_xcb/Makefile src/lib/engines/fb/Makefile src/lib/engines/buffer/Makefile src/lib/engines/software_win32_gdi/Makefile @@ -1509,6 +1580,7 @@ echo "Configuration Options Summary:" echo echo "Engines:" echo " Software X11............: $have_evas_software_x11" +echo " Software XCB............: $have_evas_software_xcb" echo " Software Framebuffer....: $have_evas_fb" echo " Software Qtopia.........: $have_evas_qtopia" echo " Software Memory Buffer..: $have_evas_buffer" diff --git a/legacy/evas/src/bin/Makefile.am b/legacy/evas/src/bin/Makefile.am index 9dd530e44b..999cfaea95 100644 --- a/legacy/evas/src/bin/Makefile.am +++ b/legacy/evas/src/bin/Makefile.am @@ -6,6 +6,7 @@ INCLUDES = \ bin_PROGRAMS = \ @ENGINE_SOFTWARE_X11_PRG@ \ +@ENGINE_SOFTWARE_XCB_PRG@ \ @ENGINE_DIRECTFB_PRG@ \ @ENGINE_FB_PRG@ \ @ENGINE_BUFFER_PRG@ \ @@ -17,6 +18,9 @@ EXTRA_PROGRAMS = \ evas_software_x11_test \ evas_software_x11_perf_test \ evas_software_x11_perf_load \ +evas_software_xcb_test \ +evas_software_xcb_perf_test \ +evas_software_xcb_perf_load \ evas_directfb_test \ evas_directfb_window \ evas_fb_test \ @@ -42,6 +46,21 @@ evas_software_x11_perf_load_LDADD = $(top_builddir)/src/lib/libevas.la -lm @x_li evas_software_x11_perf_load_CFLAGS = $(CFLAGS) @x_cflags@ evas_software_x11_perf_load_DEPENDENCIES = $(top_builddir)/src/lib/libevas.la +evas_software_xcb_test_SOURCES = evas_test_main.h evas_test_main.c evas_software_xcb_main.c +evas_software_xcb_test_LDADD = $(top_builddir)/src/lib/libevas.la -lm @xcb_libs@ +evas_software_xcb_test_CFLAGS = $(CFLAGS) @xcb_cflags@ +evas_software_xcb_test_DEPENDENCIES = $(top_builddir)/src/lib/libevas.la + +evas_software_xcb_perf_test_SOURCES = evas_software_xcb_perf_test.c +evas_software_xcb_perf_test_LDADD = $(top_builddir)/src/lib/libevas.la -lm @xcb_libs@ +evas_software_xcb_perf_test_CFLAGS = $(CFLAGS) @xcb_cflags@ +evas_software_xcb_perf_test_DEPENDENCIES = $(top_builddir)/src/lib/libevas.la + +evas_software_xcb_perf_load_SOURCES = evas_software_xcb_perf_load.c +evas_software_xcb_perf_load_LDADD = $(top_builddir)/src/lib/libevas.la -lm @xcb_libs@ +evas_software_xcb_perf_load_CFLAGS = $(CFLAGS) @xcb_cflags@ +evas_software_xcb_perf_load_DEPENDENCIES = $(top_builddir)/src/lib/libevas.la + evas_directfb_test_SOURCES = evas_test_main.h evas_test_main.c evas_directfb_main.c evas_directfb_test_LDADD = $(top_builddir)/src/lib/libevas.la -lm @DIRECTFB_LIBS@ evas_directfb_test_CFLAGS = $(CFLAGS) @DIRECTFB_CFLAGS@ diff --git a/legacy/evas/src/bin/evas_software_xcb_main.c b/legacy/evas/src/bin/evas_software_xcb_main.c new file mode 100644 index 0000000000..460875ca5e --- /dev/null +++ b/legacy/evas/src/bin/evas_software_xcb_main.c @@ -0,0 +1,304 @@ +#include "evas_test_main.h" + +#include +#include + +#include "Evas.h" +#include "Evas_Engine_Software_Xcb.h" + + + +XCBVISUALTYPE * +get_visual(XCBConnection *conn, + XCBSCREEN *root) +{ + XCBDEPTH *d; + XCBVISUALTYPEIter iter; + int cur; + + d = XCBSCREENAllowedDepthsIter(root).data; + if (!d) return NULL; + + iter = XCBDEPTHVisualsIter(d); + for (cur = 0 ; cur < iter.rem ; XCBVISUALTYPENext(&iter), ++cur) + if (root->root_visual.id == iter.data->visual_id.id) + 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; +} + +int +main(int argc, char **argv) +{ + int pause_me = 0; + XCBConnection *conn; + XCBDRAWABLE win; + XCBSCREEN *screen; + XCBGenericEvent *e; + CARD32 mask; + CARD32 value[6]; +/* XClassHint chint; */ + SizeHints *szhints; + + conn = XCBConnectBasic (); + if (!conn) + { + printf("Error: cannot open a connection.\n"); + exit(-1); + } + + screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup(conn)).data; + + mask = + CWBackingStore | CWColormap | + CWBackPixmap | CWBorderPixel | + CWBitGravity | CWEventMask; + + 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); + +/* XStoreName(disp, win, "Evas Software X11 Test"); */ +/* chint.res_name = "Evas_Software_X11_Test"; */ +/* chint.res_class = "Main"; */ +/* SetClassHint(disp, win, &chint); */ +#if 0 + szhints = AllocSizeHints(); + SizeHintsSetMinSize(szhints, win_w, win_h); + SizeHintsSetMaxSize(szhints, win_w, win_h); + SizeHintsSetSize(szhints, 0, win_w, win_h); + SetWMNormalHints(conn, win.window, szhints); + FreeSizeHints(szhints); +#endif + XCBMapWindow (conn, win.window); + XCBSync(conn, 0); + + /* test evas_free.... :) */ + evas = evas_new(); + evas_output_method_set(evas, evas_render_method_lookup("software_xcb")); + evas_output_size_set(evas, win_w, win_h); + evas_output_viewport_set(evas, 0, 0, win_w, win_h); + { + Evas_Engine_Info_Software_Xcb *einfo; + + einfo = (Evas_Engine_Info_Software_Xcb *) evas_engine_info_get(evas); + + /* the following is specific to the engine */ + einfo->info.conn = conn; + einfo->info.visual = get_visual (conn, screen); + einfo->info.colormap = screen->default_colormap; + einfo->info.drawable = win; + einfo->info.depth = get_depth(conn, screen); + einfo->info.rotation = 0; + einfo->info.debug = 0; + evas_engine_info_set(evas, (Evas_Engine_Info *) einfo); + } + setup(); + printf("################ evas free\n"); + evas_free(evas); + printf("evas freed. DONE\n"); + + evas = evas_new(); + evas_output_method_set(evas, evas_render_method_lookup("software_xcb")); + evas_output_size_set(evas, win_w, win_h); + evas_output_viewport_set(evas, 0, 0, win_w, win_h); + { + Evas_Engine_Info_Software_Xcb *einfo; + + einfo = (Evas_Engine_Info_Software_Xcb *) evas_engine_info_get(evas); + + /* the following is specific to the engine */ + einfo->info.conn = conn; + einfo->info.visual = get_visual (conn, screen); + einfo->info.colormap = screen->default_colormap; + einfo->info.drawable = win; + einfo->info.depth = get_depth(conn, screen); + einfo->info.rotation = 0; + einfo->info.debug = 0; + evas_engine_info_set(evas, (Evas_Engine_Info *) einfo); + } + setup(); + printf("################ evas free\n"); + evas_free(evas); + printf("evas freed. DONE\n"); + + evas = evas_new(); + evas_output_method_set(evas, evas_render_method_lookup("software_xcb")); + evas_output_size_set(evas, win_w, win_h); + evas_output_viewport_set(evas, 0, 0, win_w, win_h); + { + Evas_Engine_Info_Software_Xcb *einfo; + + einfo = (Evas_Engine_Info_Software_Xcb *) evas_engine_info_get(evas); + + /* the following is specific to the engine */ + einfo->info.conn = conn; + einfo->info.visual = get_visual (conn, screen); + einfo->info.colormap = screen->default_colormap; + einfo->info.drawable = win; + einfo->info.depth = get_depth(conn, screen); + einfo->info.rotation = 0; + einfo->info.debug = 0; + evas_engine_info_set(evas, (Evas_Engine_Info *) einfo); + } + setup(); + printf("################ evas free\n"); + evas_free(evas); + printf("evas freed. DONE\n"); + + evas = evas_new(); + evas_output_method_set(evas, evas_render_method_lookup("software_xcb")); + evas_output_size_set(evas, win_w, win_h); + evas_output_viewport_set(evas, 0, 0, win_w, win_h); + { + Evas_Engine_Info_Software_Xcb *einfo; + + einfo = (Evas_Engine_Info_Software_Xcb *) evas_engine_info_get(evas); + + /* the following is specific to the engine */ + einfo->info.conn = conn; + einfo->info.visual = get_visual (conn, screen); + einfo->info.colormap = screen->default_colormap; + einfo->info.drawable = win; + einfo->info.depth = get_depth(conn, screen); + einfo->info.rotation = 0; + einfo->info.debug = 0; + evas_engine_info_set(evas, (Evas_Engine_Info *) einfo); + } + setup(); + printf("################ evas free\n"); + evas_free(evas); + printf("evas freed. DONE\n"); + + evas = evas_new(); + evas_output_method_set(evas, evas_render_method_lookup("software_xcb")); + evas_output_size_set(evas, win_w, win_h); + evas_output_viewport_set(evas, 0, 0, win_w, win_h); + { + Evas_Engine_Info_Software_Xcb *einfo; + + einfo = (Evas_Engine_Info_Software_Xcb *) evas_engine_info_get(evas); + + /* the following is specific to the engine */ + einfo->info.conn = conn; + einfo->info.visual = get_visual (conn, screen); + einfo->info.colormap = screen->default_colormap; + einfo->info.drawable = win; + einfo->info.depth = get_depth(conn, screen); + einfo->info.rotation = 0; + einfo->info.debug = 0; + 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->state | Button3Mask) == Button3Mask) + 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, NULL); + evas_event_feed_mouse_down(evas, ev->state, EVAS_BUTTON_NONE, NULL); + break; + } + case XCBButtonRelease: { + XCBButtonReleaseEvent *ev = (XCBButtonReleaseEvent *)e; + + evas_event_feed_mouse_move(evas, ev->event_x, ev->event_y, NULL); + evas_event_feed_mouse_up(evas, ev->state, EVAS_BUTTON_NONE, NULL); + break; + } + case XCBMotionNotify: { + XCBMotionNotifyEvent *ev = (XCBMotionNotifyEvent *)e; + + evas_event_feed_mouse_move(evas, ev->event_x, ev->event_y, 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); + } + + return 0; +} + diff --git a/legacy/evas/src/bin/evas_software_xcb_perf_load.c b/legacy/evas/src/bin/evas_software_xcb_perf_load.c new file mode 100644 index 0000000000..2f062dc7b2 --- /dev/null +++ b/legacy/evas/src/bin/evas_software_xcb_perf_load.c @@ -0,0 +1,245 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Evas.h" +#include "Evas_Engine_Software_Xcb.h" + +XCBConnection *c = NULL; +XCBDRAWABLE win; + +Evas *evas = NULL; + +int win_w = 240; +int win_h = 240; + +XCBVISUALTYPE * +get_visual(XCBConnection *conn, + XCBSCREEN *root) +{ + XCBDEPTH *d; + XCBVISUALTYPEIter iter; + int cur; + + d = XCBSCREENAllowedDepthsIter(root).data; + if (!d) return NULL; + + iter = XCBDEPTHVisualsIter(d); + for (cur = 0 ; cur < iter.rem ; XCBVISUALTYPENext(&iter), ++cur) + if (root->root_visual.id == iter.data->visual_id.id) + 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; +} + +int +main(int argc, char **argv) +{ + int exposed = 0; + + XCBSCREEN *screen; + XCBGenericEvent *e; + CARD32 mask = 0; + CARD32 value[6]; +/* XClassHint chint; */ + SizeHints *szhints; + + c = XCBConnectBasic (); + if (!c) + { + printf("Error: cannot open a connection.\n"); + exit(-1); + } + + screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup(c)).data; + + mask = CWBackingStore | CWColormap | + CWBackPixmap | CWBorderPixel | + CWBitGravity | CWEventMask; + + value[0] = None; + value[1] = 0; + value[2] = ForgetGravity; + value[3] = NotUseful; + value[4] = ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; + value[5] = screen->default_colormap.xid; + + win.window = XCBWINDOWNew(c); + XCBCreateWindow (c, + get_depth(c, screen), + win.window, screen->root, + 0, 0, + win_w, win_h, + 0, + InputOutput, + screen->root_visual, + mask, value); + +/* XStoreName(disp, win, "Evas Performance Test"); */ +/* chint.res_name = "Evas_Test"; */ +/* chint.res_class = "Main"; */ +/* XSetClassHint(disp, win, &chint); */ + + szhints = AllocSizeHints(); + SizeHintsSetMinSize(szhints, win_w, win_h); + SizeHintsSetMaxSize(szhints, win_w, win_h); + SizeHintsSetSize(szhints, 0, win_w, win_h); + SetWMNormalHints(c, win.window, szhints); + FreeSizeHints(szhints); + + XCBMapWindow (c, win.window); + + evas = evas_new(); + evas_output_method_set(evas, evas_render_method_lookup("software_xcb")); + evas_output_size_set(evas, win_w, win_h); + evas_output_viewport_set(evas, 0, 0, win_w, win_h); + { + Evas_Engine_Info_Software_Xcb *einfo; + + einfo = (Evas_Engine_Info_Software_Xcb *) evas_engine_info_get(evas); + + /* the following is specific to the engine */ + einfo->info.conn = c; + einfo->info.visual = get_visual (c, screen); + einfo->info.colormap = screen->default_colormap; + einfo->info.drawable = win; + einfo->info.depth = get_depth(c, screen); + einfo->info.rotation = 0; + + evas_engine_info_set(evas, (Evas_Engine_Info *) einfo); + } + + while (1) + { + e = XCBPollForEvent(c, NULL); + + if (e) + { + switch (e->response_type) + { + case ButtonPress: { + XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e; + +/* evas_event_button_down(evas, ev->event_x, ev->event_y, ev->detail.id);*/ + break; + } + case ButtonRelease: { + XCBButtonReleaseEvent *ev = (XCBButtonReleaseEvent *)e; + + /* evas_event_button_up(evas, ev->event_x, ev->event_y, ev->detail.id);*/ + break; + } + case MotionNotify: { + XCBMotionNotifyEvent *ev = (XCBMotionNotifyEvent *)e; + +/* evas_event_move(evas, ev->event_x, ev->event_y);*/ + break; + } + case Expose: { + XCBExposeEvent *ev = (XCBExposeEvent *)e; + + exposed = 1; + evas_damage_rectangle_add(evas, + ev->x, + ev->y, + ev->width, + ev->height); + break; + } + default: + break; + } + } + evas_render(evas); + XCBFlush(c); + + if (exposed) + { + Evas_Engine_Info_Software_Xcb *einfo; + Evas_Performance *perf; + char buf[4096]; + char *data, *key; + static mode_t default_mode = + S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | + S_IXOTH; + FILE *f; + + data = NULL; + einfo = + (Evas_Engine_Info_Software_Xcb *) evas_engine_info_get(evas); + perf = + einfo->func.performance_new(evas, c, + get_visual (c, screen), + screen->default_colormap, + win, + get_depth(c, screen)); + key = einfo->func.performance_key_get(perf); + snprintf(buf, sizeof(buf), "%s/.evas/%s", getenv("HOME"), key); + free(key); + f = fopen(buf, "r"); + if (f) + { + char buf[4096]; + size_t sz; + + sz = fread(buf, 1, 4000, f); + if (sz > 0) + { + data = malloc(sz + 1); + if (data) + { + strncpy(data, buf, sz); + data[sz] = 0; + } + } + fclose(f); + } + if (data) + { + einfo->func.performance_build(perf, data); + einfo->func.performance_device_store(perf); + free(data); + } + else + { + printf("No cached performance values for your display.\n"); + printf("Please run evas_perf_test to generate them.\n"); + einfo->func.performance_free(perf); + exit(-1); + } + einfo->func.performance_free(perf); + exit(0); + } + } + + return 0; +} diff --git a/legacy/evas/src/bin/evas_software_xcb_perf_test.c b/legacy/evas/src/bin/evas_software_xcb_perf_test.c new file mode 100644 index 0000000000..a35b923e5a --- /dev/null +++ b/legacy/evas/src/bin/evas_software_xcb_perf_test.c @@ -0,0 +1,219 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Evas.h" +#include "Evas_Engine_Software_Xcb.h" + +XCBConnection *c = NULL; +XCBDRAWABLE win; + +Evas *evas = NULL; + +int win_w = 240; +int win_h = 240; + +XCBVISUALTYPE * +get_visual(XCBConnection *conn, + XCBSCREEN *root) +{ + XCBDEPTH *d; + XCBVISUALTYPEIter iter; + int cur; + + d = XCBSCREENAllowedDepthsIter(root).data; + if (!d) return NULL; + + iter = XCBDEPTHVisualsIter(d); + for (cur = 0 ; cur < iter.rem ; XCBVISUALTYPENext(&iter), ++cur) + if (root->root_visual.id == iter.data->visual_id.id) + 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; +} + +int +main(int argc, char **argv) +{ + int exposed = 0; + + XCBSCREEN *screen; + XCBGenericEvent *e; + CARD32 mask = 0; + CARD32 value[6]; +/* XClassHint chint; */ + SizeHints *szhints; + + c = XCBConnectBasic (); + if (!c) + { + printf("Error: cannot open a connection.\n"); + exit(-1); + } + + screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup(c)).data; + + mask = CWBackingStore | CWColormap | + CWBackPixmap | CWBorderPixel | + CWBitGravity | CWEventMask; + + value[0] = None; + value[1] = 0; + value[2] = ForgetGravity; + value[3] = NotUseful; + value[4] = ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; + value[5] = screen->default_colormap.xid; + + win.window = XCBWINDOWNew(c); + XCBCreateWindow (c, + get_depth(c, screen), + win.window, screen->root, + 0, 0, + win_w, win_h, + 0, + InputOutput, + screen->root_visual, + mask, value); +/* XStoreName(disp, win, "Evas Performance Test"); */ +/* chint.res_name = "Evas_Test"; */ +/* chint.res_class = "Main"; */ +/* XSetClassHint(disp, win, &chint); */ + + szhints = AllocSizeHints(); + SizeHintsSetMinSize(szhints, win_w, win_h); + SizeHintsSetMaxSize(szhints, win_w, win_h); + SizeHintsSetSize(szhints, 0, win_w, win_h); + SetWMNormalHints(c, win.window, szhints); + FreeSizeHints(szhints); + + XCBMapWindow (c, win.window); + XCBSync(c, 0); + sleep(1); + + evas = evas_new(); + evas_output_method_set(evas, evas_render_method_lookup("software_xcb")); + evas_output_size_set(evas, win_w, win_h); + evas_output_viewport_set(evas, 0, 0, win_w, win_h); + { + Evas_Engine_Info_Software_Xcb *einfo; + + einfo = (Evas_Engine_Info_Software_Xcb *) evas_engine_info_get(evas); + + /* the following is specific to the engine */ + einfo->info.conn = c; + einfo->info.visual = get_visual (c, screen); + einfo->info.colormap = screen->default_colormap; + einfo->info.drawable = win; + einfo->info.depth = get_depth(c, screen); + einfo->info.rotation = 0; + + evas_engine_info_set(evas, (Evas_Engine_Info *) einfo); + } + + while (1) + { + e = XCBPollForEvent(c, NULL); + + if (e) + { + switch (e->response_type) + { + case XCBButtonPress: { + XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e; + +/* evas_event_button_down(evas, ev->event_x, ev->event_y, ev->detail.id);*/ + break; + } + case XCBButtonRelease: { + XCBButtonReleaseEvent *ev = (XCBButtonReleaseEvent *)e; + + /* evas_event_button_up(evas, ev->event_x, ev->event_y, ev->detail.id);*/ + break; + } + case XCBExpose: { + XCBExposeEvent *ev = (XCBExposeEvent *)e; + + exposed = 1; + evas_damage_rectangle_add(evas, + ev->x, + ev->y, + ev->width, + ev->height); + break; + } + } + free (e); + } + + evas_render(evas); + XCBFlush(c); + + if (exposed) + { + Evas_Engine_Info_Software_Xcb *einfo; + Evas_Performance *perf; + char buf[4096]; + char *data, *key; + static mode_t default_mode = + S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | + S_IXOTH; + FILE *f; + + einfo = + (Evas_Engine_Info_Software_Xcb *) evas_engine_info_get(evas); + perf = + einfo->func.performance_test(evas, c, + get_visual (c, screen), + screen->default_colormap, + win, + get_depth(c, screen)); + einfo->func.performance_device_store(perf); + data = einfo->func.performance_data_get(perf); + key = einfo->func.performance_key_get(perf); + snprintf(buf, sizeof(buf), "%s/.evas", getenv("HOME")); + mkdir(buf, default_mode); + snprintf(buf, sizeof(buf), "%s/.evas/%s", getenv("HOME"), key); + free(key); + f = fopen(buf, "w"); + if (f) + { + fprintf(f, "%s", data); + free(data); + fclose(f); + } + einfo->func.performance_free(perf); + exit(0); + } + } + + return 0; +} diff --git a/legacy/evas/src/lib/Evas_Engine_Software_Xcb.h b/legacy/evas/src/lib/Evas_Engine_Software_Xcb.h new file mode 100644 index 0000000000..e84250d723 --- /dev/null +++ b/legacy/evas/src/lib/Evas_Engine_Software_Xcb.h @@ -0,0 +1,58 @@ +#ifndef _EVAS_ENGINE_SOFTWARE_XCB_H +#define _EVAS_ENGINE_SOFTWARE_XCB_H + +#include + +typedef struct _Evas_Engine_Info_Software_Xcb Evas_Engine_Info_Software_Xcb; + +struct _Evas_Engine_Info_Software_Xcb +{ + /* PRIVATE - don't mess with this baby or evas will poke its tongue out */ + /* at you and make nasty noises */ + Evas_Engine_Info magic; + + /* engine specific data & parameters it needs to set up */ + struct { + XCBConnection *conn; + XCBDRAWABLE drawable; + XCBDRAWABLE mask; + XCBVISUALTYPE *visual; + XCBCOLORMAP colormap; + int depth; + int rotation; + + int alloc_grayscale : 1; + int debug : 1; + int shape_dither : 1; + + int alloc_colors_max; + } info; + /* engine specific function calls to query stuff about the destination */ + /* engine (what visual & colormap & depth to use, performance info etc. */ + struct { + XCBVISUALTYPE * (*best_visual_get) (XCBConnection *conn, int screen); + XCBCOLORMAP (*best_colormap_get) (XCBConnection *conn, int screen); + int (*best_depth_get) (XCBConnection *conn, int screen); + + Evas_Performance *(*performance_test) (Evas *e, + XCBConnection *conn, + XCBVISUALTYPE *vis, + XCBCOLORMAP cmap, + XCBDRAWABLE draw, + int depth); + void (*performance_free) (Evas_Performance *perf); + char * (*performance_data_get) (Evas_Performance *perf); + char * (*performance_key_get) (Evas_Performance *perf); + Evas_Performance *(*performance_new) (Evas *e, + XCBConnection *conn, + XCBVISUALTYPE *vis, + XCBCOLORMAP cmap, + XCBDRAWABLE draw, + int depth); + void (*performance_build) (Evas_Performance *perf, + const char *data); + void (*performance_device_store) (Evas_Performance *perf); + } func; +}; + +#endif /* _EVAS_ENGINE_SOFTWARE_XCB_H */ diff --git a/legacy/evas/src/lib/Makefile.am b/legacy/evas/src/lib/Makefile.am index 4c680b11af..7efb6257b0 100644 --- a/legacy/evas/src/lib/Makefile.am +++ b/legacy/evas/src/lib/Makefile.am @@ -4,7 +4,7 @@ SUBDIRS = canvas data file engines imaging include AUTOMAKE_OPTIONS = 1.4 foreign -INCLUDES = @freetype_cflags@ @x_cflags@ @qt_cflags@ @DIRECTFB_CFLAGS@ @gl_cflags@ \ +INCLUDES = @freetype_cflags@ @x_cflags@ @xcb_cflags@ @qt_cflags@ @DIRECTFB_CFLAGS@ @gl_cflags@ \ -I. \ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/lib/include @@ -13,6 +13,7 @@ lib_LTLIBRARIES = libevas.la EXTRA_DIST = \ Evas_Engine_Software_X11.h \ +Evas_Engine_Software_Xcb.h \ Evas_Engine_DirectFB.h \ Evas_Engine_FB.h \ Evas_Engine_Buffer.h \ @@ -29,6 +30,14 @@ ENGINE_SOFTWARE_X11 = ENGINE_SOFTWARE_X11_INC = endif +if BUILD_ENGINE_SOFTWARE_XCB +ENGINE_SOFTWARE_XCB = engines/software_xcb/libevas_engine_software_xcb.la +ENGINE_SOFTWARE_XCB_INC = Evas_Engine_Software_Xcb.h +else +ENGINE_SOFTWARE_XCB = +ENGINE_SOFTWARE_XCB_INC = +endif + if BUILD_ENGINE_DIRECTFB ENGINE_DIRECTFB = engines/directfb/libevas_engine_directfb.la ENGINE_DIRECTFB_INC = Evas_Engine_DirectFB.h @@ -96,6 +105,7 @@ endif include_HEADERS = \ Evas.h \ $(ENGINE_SOFTWARE_X11_INC) \ +$(ENGINE_SOFTWARE_XCB_INC) \ $(ENGINE_DIRECTFB_INC) \ $(ENGINE_FB_INC) \ $(ENGINE_BUFFER_INC) \ @@ -118,6 +128,7 @@ libevas_la_LIBADD = \ @freetype_libs@ \ @png_libs@ @jpeg_libs@ @eet_libs@ @edb_libs@ \ $(ENGINE_SOFTWARE_X11) \ + $(ENGINE_SOFTWARE_XCB) \ $(ENGINE_DIRECTFB) \ $(ENGINE_FB) \ $(ENGINE_BUFFER) \ @@ -136,6 +147,7 @@ libevas_la_DEPENDENCIES = \ imaging/libevas_imaging.la \ engines/common/libevas_engine_common.la \ $(ENGINE_SOFTWARE_X11) \ + $(ENGINE_SOFTWARE_XCB) \ $(ENGINE_DIRECTFB) \ $(ENGINE_FB) \ $(ENGINE_BUFFER) \ diff --git a/legacy/evas/src/lib/canvas/evas_main.c b/legacy/evas/src/lib/canvas/evas_main.c index 0161e07135..4cc447dea2 100644 --- a/legacy/evas/src/lib/canvas/evas_main.c +++ b/legacy/evas/src/lib/canvas/evas_main.c @@ -3,6 +3,9 @@ #ifdef BUILD_ENGINE_SOFTWARE_X11 #include "evas_engine_api_software_x11.h" #endif +#ifdef BUILD_ENGINE_SOFTWARE_XCB +#include "evas_engine_api_software_xcb.h" +#endif #ifdef BUILD_ENGINE_DIRECTFB #include "evas_engine_api_directfb.h" #endif @@ -222,6 +225,11 @@ evas_output_method_set(Evas *e, int render_method) e->engine.func = &evas_engine_software_x11_func; else #endif +#ifdef BUILD_ENGINE_SOFTWARE_XCB + if (e->output.render_method == RENDER_METHOD_SOFTWARE_XCB) + e->engine.func = &evas_engine_software_xcb_func; + else +#endif #ifdef BUILD_ENGINE_GL_X11 if (e->output.render_method == RENDER_METHOD_GL_X11) e->engine.func = &evas_engine_gl_x11_func; @@ -663,10 +671,13 @@ int evas_render_method_lookup(const char *name) { if (!name) return RENDER_METHOD_INVALID; - + #ifdef BUILD_ENGINE_SOFTWARE_X11 if (!strcmp(name, "software_x11")) return RENDER_METHOD_SOFTWARE_X11; #endif +#ifdef BUILD_ENGINE_SOFTWARE_XCB + if (!strcmp(name, "software_xcb")) return RENDER_METHOD_SOFTWARE_XCB; +#endif #ifdef BUILD_ENGINE_GL_X11 if (!strcmp(name, "gl_x11")) return RENDER_METHOD_GL_X11; #endif @@ -733,6 +744,9 @@ evas_render_method_list(void) #ifdef BUILD_ENGINE_SOFTWARE_X11 methods = evas_list_append(methods, strdup("software_x11")); +#endif +#ifdef BUILD_ENGINE_SOFTWARE_XCB + methods = evas_list_append(methods, strdup("software_xcb")); #endif #ifdef BUILD_ENGINE_GL_X11 methods = evas_list_append(methods, strdup("gl_x11")); diff --git a/legacy/evas/src/lib/engines/Makefile.am b/legacy/evas/src/lib/engines/Makefile.am index a8df89656d..84ba4839de 100644 --- a/legacy/evas/src/lib/engines/Makefile.am +++ b/legacy/evas/src/lib/engines/Makefile.am @@ -3,6 +3,7 @@ MAINTAINERCLEANFILES = Makefile.in SUBDIRS = \ common \ software_x11 \ +software_xcb \ fb \ buffer \ software_win32_gdi \ diff --git a/legacy/evas/src/lib/engines/software_xcb/Makefile.am b/legacy/evas/src/lib/engines/software_xcb/Makefile.am new file mode 100644 index 0000000000..3bc9dfd3e6 --- /dev/null +++ b/legacy/evas/src/lib/engines/software_xcb/Makefile.am @@ -0,0 +1,37 @@ +## 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 = @freetype_cflags@ @xcb_cflags@ \ + -I. \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib/include + +if BUILD_ENGINE_SOFTWARE_XCB + +noinst_LTLIBRARIES = libevas_engine_software_xcb.la +libevas_engine_software_xcb_la_SOURCES = \ +evas_engine.h \ +evas_engine.c \ +evas_outbuf.c \ +evas_xcb_buffer.c \ +evas_xcb_color.c \ +evas_xcb_main.c + +libevas_engine_software_xcb_la_LIBADD = @xcb_libs@ + +libevas_engine_software_xcb_la_DEPENDENCIES = \ +$(top_builddir)/config.h + +endif + +EXTRA_DIST = \ +evas_engine.h \ +evas_engine.c \ +evas_outbuf.c \ +evas_xcb_buffer.c \ +evas_xcb_color.c \ +evas_xcb_main.c diff --git a/legacy/evas/src/lib/engines/software_xcb/evas_engine.c b/legacy/evas/src/lib/engines/software_xcb/evas_engine.c new file mode 100644 index 0000000000..0470b5b646 --- /dev/null +++ b/legacy/evas/src/lib/engines/software_xcb/evas_engine.c @@ -0,0 +1,1277 @@ +#include "evas_common.h" +#include "evas_private.h" +#include "evas_engine.h" +#include "evas_engine_api_software_xcb.h" +#include "Evas.h" +#include "Evas_Engine_Software_Xcb.h" + +static void *evas_engine_software_xcb_info(Evas *e); +static void evas_engine_software_xcb_info_free(Evas *e, void *info); +static void evas_engine_software_xcb_setup(Evas *e, void *info); +static void *evas_engine_software_xcb_output_setup(int w, int h, int rot, XCBConnection *conn, XCBDRAWABLE draw, XCBVISUALTYPE *vis, XCBCOLORMAP cmap, int depth, int debug, int grayscale, int max_colors, XCBDRAWABLE mask, int shape_dither); +static void evas_engine_software_xcb_output_free(void *data); +static void evas_engine_software_xcb_output_resize(void *data, int w, int h); +static void evas_engine_software_xcb_output_tile_size_set(void *data, int w, int h); +static void evas_engine_software_xcb_output_redraws_rect_add(void *data, int x, int y, int w, int h); +static void evas_engine_software_xcb_output_redraws_rect_del(void *data, int x, int y, int w, int h); +static void evas_engine_software_xcb_output_redraws_clear(void *data); +static void *evas_engine_software_xcb_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 evas_engine_software_xcb_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h); +static void evas_engine_software_xcb_output_flush(void *data); +static void *evas_engine_software_xcb_context_new(void *data); +static void evas_engine_software_xcb_context_free(void *data, void *context); +static void evas_engine_software_xcb_context_clip_set(void *data, void *context, int x, int y, int w, int h); +static void evas_engine_software_xcb_context_clip_clip(void *data, void *context, int x, int y, int w, int h); +static void evas_engine_software_xcb_context_clip_unset(void *data, void *context); +static int evas_engine_software_xcb_context_clip_get(void *data, void *context, int *x, int *y, int *w, int *h); +static void evas_engine_software_xcb_context_color_set(void *data, void *context, int r, int g, int b, int a); +static int evas_engine_software_xcb_context_color_get(void *data, void *context, int *r, int *g, int *b, int *a); +static void evas_engine_software_xcb_context_multiplier_set(void *data, void *context, int r, int g, int b, int a); +static void evas_engine_software_xcb_context_multiplier_unset(void *data, void *context); +static int evas_engine_software_xcb_context_multiplier_get(void *data, void *context, int *r, int *g, int *b, int *a); +static void evas_engine_software_xcb_context_cutout_add(void *data, void *context, int x, int y, int w, int h); +static void evas_engine_software_xcb_context_cutout_clear(void *data, void *context); +static void evas_engine_software_xcb_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h); +static void evas_engine_software_xcb_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2); +static void *evas_engine_software_xcb_polygon_point_add(void *data, void *context, void *polygon, int x, int y); +static void *evas_engine_software_xcb_polygon_points_clear(void *data, void *context, void *polygon); +static void evas_engine_software_xcb_polygon_draw(void *data, void *context, void *surface, void *polygon); +static void *evas_engine_software_xcb_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance); +static void *evas_engine_software_xcb_gradient_colors_clear(void *data, void *context, void *gradient); +static void evas_engine_software_xcb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle); +static void *evas_engine_software_xcb_image_load(void *data, char *file, char *key, int *error); +static void *evas_engine_software_xcb_image_new_from_data(void *data, int w, int h, DATA32 *image_data); +static void *evas_engine_software_xcb_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data); +static void evas_engine_software_xcb_image_free(void *data, void *image); +static void evas_engine_software_xcb_image_size_get(void *data, void *image, int *w, int *h); +static void *evas_engine_software_xcb_image_size_set(void *data, void *image, int w, int h); +static void *evas_engine_software_xcb_image_dirty_region(void *data, void *image, int x, int y, int w, int h); +static void *evas_engine_software_xcb_image_data_get(void *data, void *image, int to_write, DATA32 **image_data); +static void *evas_engine_software_xcb_image_data_put(void *data, void *image, DATA32 *image_data); +static void *evas_engine_software_xcb_image_alpha_set(void *data, void *image, int has_alpha); +static int evas_engine_software_xcb_image_alpha_get(void *data, void *image); +static void evas_engine_software_xcb_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 *evas_engine_software_xcb_image_comment_get(void *data, void *image, char *key); +static char *evas_engine_software_xcb_image_format_get(void *data, void *image); +static void evas_engine_software_xcb_image_cache_flush(void *data); +static void evas_engine_software_xcb_image_cache_set(void *data, int bytes); +static int evas_engine_software_xcb_image_cache_get(void *data); +static void *evas_engine_software_xcb_font_load(void *data, char *name, int size); +static void *evas_engine_software_xcb_font_memory_load(void *data, char *name, int size, const void *fdata, int fdata_size); +static void *evas_engine_software_xcb_font_add(void *data, void *font, char *name, int size); +static void *evas_engine_software_xcb_font_memory_add(void *data, void *font, char *name, int size, const void *fdata, int fdata_size); +static void evas_engine_software_xcb_font_free(void *data, void *font); +static int evas_engine_software_xcb_font_ascent_get(void *data, void *font); +static int evas_engine_software_xcb_font_descent_get(void *data, void *font); +static int evas_engine_software_xcb_font_max_ascent_get(void *data, void *font); +static int evas_engine_software_xcb_font_max_descent_get(void *data, void *font); +static void evas_engine_software_xcb_font_string_size_get(void *data, void *font, char *text, int *w, int *h); +static int evas_engine_software_xcb_font_inset_get(void *data, void *font, char *text); +static int evas_engine_software_xcb_font_h_advance_get(void *data, void *font, char *text); +static int evas_engine_software_xcb_font_v_advance_get(void *data, void *font, char *text); +static int evas_engine_software_xcb_font_char_coords_get(void *data, void *font, char *text, int pos, int *cx, int *cy, int *cw, int *ch); +static int evas_engine_software_xcb_font_char_at_coords_get(void *data, void *font, char *text, int x, int y, int *cx, int *cy, int *cw, int *ch); +static void evas_engine_software_xcb_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, char *text); +static void evas_engine_software_xcb_font_cache_flush(void *data); +static void evas_engine_software_xcb_font_cache_set(void *data, int bytes); +static int evas_engine_software_xcb_font_cache_get(void *data); + + +static XCBVISUALTYPE *evas_engine_software_xcb_best_visual_get(XCBConnection *conn, int screen); +static XCBCOLORMAP evas_engine_software_xcb_best_colormap_get(XCBConnection *conn, int screen); +static int evas_engine_software_xcb_best_depth_get(XCBConnection *conn, int screen); +static Evas_Performance *evas_engine_software_xcb_output_perf_new(Evas *e, XCBConnection *conn, XCBVISUALTYPE *vis, XCBCOLORMAP cmap, XCBDRAWABLE draw, int depth); +static Evas_Performance *evas_engine_software_xcb_output_perf_test(Evas *e, XCBConnection *conn, XCBVISUALTYPE *vis, XCBCOLORMAP cmap, XCBDRAWABLE draw, int depth); +static char *evas_engine_software_xcb_output_perf_data(Evas_Performance *perf); +static char *evas_engine_software_xcb_output_perf_key(Evas_Performance *perf); +static void evas_engine_software_xcb_output_perf_free(Evas_Performance *perf); +static void evas_engine_software_xcb_output_perf_build(Evas_Performance *perf, const char *data); +static void evas_engine_software_xcb_output_perf_device_store(Evas_Performance *perf); + +typedef struct _Render_Engine Render_Engine; + +struct _Render_Engine +{ + Tilebuf *tb; + Outbuf *ob; + Tilebuf_Rect *rects; + Evas_Object_List *cur_rect; + int end : 1; +}; + +Evas_Func evas_engine_software_xcb_func = +{ + evas_engine_software_xcb_info, + evas_engine_software_xcb_info_free, + evas_engine_software_xcb_setup, + evas_engine_software_xcb_output_free, + evas_engine_software_xcb_output_resize, + evas_engine_software_xcb_output_tile_size_set, + evas_engine_software_xcb_output_redraws_rect_add, + evas_engine_software_xcb_output_redraws_rect_del, + evas_engine_software_xcb_output_redraws_clear, + evas_engine_software_xcb_output_redraws_next_update_get, + evas_engine_software_xcb_output_redraws_next_update_push, + evas_engine_software_xcb_output_flush, + /* draw context virtual methods */ + evas_engine_software_xcb_context_new, + evas_engine_software_xcb_context_free, + evas_engine_software_xcb_context_clip_set, + evas_engine_software_xcb_context_clip_clip, + evas_engine_software_xcb_context_clip_unset, + evas_engine_software_xcb_context_clip_get, + evas_engine_software_xcb_context_color_set, + evas_engine_software_xcb_context_color_get, + evas_engine_software_xcb_context_multiplier_set, + evas_engine_software_xcb_context_multiplier_unset, + evas_engine_software_xcb_context_multiplier_get, + evas_engine_software_xcb_context_cutout_add, + evas_engine_software_xcb_context_cutout_clear, + /* rectangle draw funcs */ + evas_engine_software_xcb_rectangle_draw, + /* line draw funcs */ + evas_engine_software_xcb_line_draw, + /* polygon draw funcs */ + evas_engine_software_xcb_polygon_point_add, + evas_engine_software_xcb_polygon_points_clear, + evas_engine_software_xcb_polygon_draw, + /* gradient draw funcs */ + evas_engine_software_xcb_gradient_color_add, + evas_engine_software_xcb_gradient_colors_clear, + evas_engine_software_xcb_gradient_draw, + /* image draw funcs */ + evas_engine_software_xcb_image_load, + evas_engine_software_xcb_image_new_from_data, + evas_engine_software_xcb_image_new_from_copied_data, + evas_engine_software_xcb_image_free, + evas_engine_software_xcb_image_size_get, + evas_engine_software_xcb_image_size_set, + evas_engine_software_xcb_image_dirty_region, + evas_engine_software_xcb_image_data_get, + evas_engine_software_xcb_image_data_put, + evas_engine_software_xcb_image_alpha_set, + evas_engine_software_xcb_image_alpha_get, + evas_engine_software_xcb_image_draw, + evas_engine_software_xcb_image_comment_get, + evas_engine_software_xcb_image_format_get, + /* image cache funcs */ + evas_engine_software_xcb_image_cache_flush, + evas_engine_software_xcb_image_cache_set, + evas_engine_software_xcb_image_cache_get, + /* font draw functions */ + evas_engine_software_xcb_font_load, + evas_engine_software_xcb_font_memory_load, + evas_engine_software_xcb_font_add, + evas_engine_software_xcb_font_memory_add, + evas_engine_software_xcb_font_free, + evas_engine_software_xcb_font_ascent_get, + evas_engine_software_xcb_font_descent_get, + evas_engine_software_xcb_font_max_ascent_get, + evas_engine_software_xcb_font_max_descent_get, + evas_engine_software_xcb_font_string_size_get, + evas_engine_software_xcb_font_inset_get, + evas_engine_software_xcb_font_h_advance_get, + evas_engine_software_xcb_font_v_advance_get, + evas_engine_software_xcb_font_char_coords_get, + evas_engine_software_xcb_font_char_at_coords_get, + evas_engine_software_xcb_font_draw, + /* font cache functions */ + evas_engine_software_xcb_font_cache_flush, + evas_engine_software_xcb_font_cache_set, + evas_engine_software_xcb_font_cache_get +}; + +static void * +evas_engine_software_xcb_info(Evas *e) +{ + Evas_Engine_Info_Software_Xcb *info; + + info = calloc(1, sizeof(Evas_Engine_Info_Software_Xcb)); + if (!info) return NULL; + info->magic.magic = rand(); + info->info.debug = 0; + info->info.alloc_grayscale = 0; + info->info.alloc_colors_max = 216; + info->func.best_visual_get = evas_engine_software_xcb_best_visual_get; + info->func.best_colormap_get = evas_engine_software_xcb_best_colormap_get; + info->func.best_depth_get = evas_engine_software_xcb_best_depth_get; + info->func.performance_test = evas_engine_software_xcb_output_perf_test; + info->func.performance_free = evas_engine_software_xcb_output_perf_free; + info->func.performance_data_get = evas_engine_software_xcb_output_perf_data; + info->func.performance_key_get = evas_engine_software_xcb_output_perf_key; + info->func.performance_new = evas_engine_software_xcb_output_perf_new; + info->func.performance_build = evas_engine_software_xcb_output_perf_build; + info->func.performance_device_store = evas_engine_software_xcb_output_perf_device_store; + return info; + e = NULL; +} + +static void +evas_engine_software_xcb_info_free(Evas *e, void *info) +{ + Evas_Engine_Info_Software_Xcb *in; + + in = (Evas_Engine_Info_Software_Xcb *)info; + free(in); +} + +static void +evas_engine_software_xcb_setup(Evas *e, void *in) +{ + Render_Engine *re; + Evas_Engine_Info_Software_Xcb *info; + + info = (Evas_Engine_Info_Software_Xcb *)in; + if (!e->engine.data.output) + e->engine.data.output = + evas_engine_software_xcb_output_setup(e->output.w, + e->output.h, + info->info.rotation, + info->info.conn, + info->info.drawable, + info->info.visual, + info->info.colormap, + info->info.depth, + info->info.debug, + info->info.alloc_grayscale, + info->info.alloc_colors_max, + info->info.mask, + info->info.shape_dither); + if (!e->engine.data.output) return; + if (!e->engine.data.context) + e->engine.data.context = + e->engine.func->context_new(e->engine.data.output); + + re = e->engine.data.output; + evas_software_x11_outbuf_software_xcb_drawable_set(re->ob, info->info.drawable); + evas_software_x11_outbuf_software_xcb_mask_set(re->ob, info->info.mask); + evas_software_x11_outbuf_software_xcb_rotation_set(re->ob, info->info.rotation); +} + +static void * +evas_engine_software_xcb_output_setup(int w, + int h, + int rot, + XCBConnection *conn, + XCBDRAWABLE draw, + XCBVISUALTYPE *vis, + XCBCOLORMAP cmap, + int depth, + int debug, + int grayscale, + int max_colors, + XCBDRAWABLE mask, + int shape_dither) +{ + Render_Engine *re; + Outbuf_Perf *perf; + + re = calloc(1, sizeof(Render_Engine)); + /* if we haven't initialized - init (automatic abort if already done) */ + 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(); + + evas_software_x11_x_software_xcb_init(); + x_software_xcb_color_init(); + evas_software_x11_outbuf_software_xcb_init(); + + /* get any stored performance metrics from device (xserver) */ + perf = evas_software_x11_outbuf_software_xcb_perf_restore_x(conn, draw, vis, cmap, depth); + re->ob = evas_software_x11_outbuf_software_xcb_setup_x(w, h, rot, + OUTBUF_DEPTH_INHERIT, + conn, + draw, + vis, + cmap, + depth, + perf, + grayscale, + max_colors, + mask, shape_dither); + if (!re->ob) + { + evas_software_x11_outbuf_software_xcb_perf_free(perf); + free(re); + return NULL; + } + evas_software_x11_outbuf_software_xcb_debug_set(re->ob, debug); + evas_software_x11_outbuf_software_xcb_set_have_backbuf(re->ob, 0); + re->tb = evas_common_tilebuf_new(w, h); + if (!re->tb) + { + evas_software_x11_outbuf_software_xcb_free(re->ob); + free(re); + return NULL; + } + /* in preliminary tests 16x16 gave highest framerates */ + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + return re; +} + +static void +evas_engine_software_xcb_output_free(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_software_x11_outbuf_software_xcb_free(re->ob); + evas_common_tilebuf_free(re->tb); + if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); + free(re); + + evas_common_font_shutdown(); + evas_common_image_shutdown(); +} + +static void +evas_engine_software_xcb_output_resize(void *data, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_software_x11_outbuf_software_xcb_reconfigure(re->ob, w, h, + evas_software_x11_outbuf_software_xcb_get_rot(re->ob), + OUTBUF_DEPTH_INHERIT); + evas_software_x11_outbuf_software_xcb_set_have_backbuf(re->ob, 0); + 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 +evas_engine_software_xcb_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 +evas_engine_software_xcb_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 +evas_engine_software_xcb_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 +evas_engine_software_xcb_output_redraws_clear(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_clear(re->tb); +} + +static void * +evas_engine_software_xcb_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; + RGBA_Image *surface; + 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; + } + + surface = evas_software_x11_outbuf_software_xcb_new_region_for_update(re->ob, + ux, uy, uw, uh, + cx, cy, cw, ch); + *x = ux; *y = uy; *w = uw; *h = uh; + return surface; +} + +static void +evas_engine_software_xcb_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_software_x11_outbuf_software_xcb_push_updated_region(re->ob, surface, x, y, w, h); + evas_software_x11_outbuf_software_xcb_free_region_for_update(re->ob, surface); + evas_common_cpu_end_opt(); +} + +static void +evas_engine_software_xcb_output_flush(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + XCBSync(re->ob->priv.x.conn, 0); +} + +static void * +evas_engine_software_xcb_context_new(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_draw_context_new(); +} + +static void +evas_engine_software_xcb_context_free(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_free(context); +} + +static void +evas_engine_software_xcb_context_clip_set(void *data, void *context, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_clip(context, x, y, w, h); +} + +static void +evas_engine_software_xcb_context_clip_clip(void *data, void *context, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_clip_clip(context, x, y, w, h); +} + +static void +evas_engine_software_xcb_context_clip_unset(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_unset_clip(context); +} + +static int +evas_engine_software_xcb_context_clip_get(void *data, void *context, int *x, int *y, int *w, int *h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + *x = ((RGBA_Draw_Context *)context)->clip.x; + *y = ((RGBA_Draw_Context *)context)->clip.y; + *w = ((RGBA_Draw_Context *)context)->clip.w; + *h = ((RGBA_Draw_Context *)context)->clip.h; + return ((RGBA_Draw_Context *)context)->clip.use; +} + +static void +evas_engine_software_xcb_context_color_set(void *data, void *context, int r, int g, int b, int a) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_color(context, r, g, b, a); +} + +static int +evas_engine_software_xcb_context_color_get(void *data, void *context, int *r, int *g, int *b, int *a) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + *r = (int)(R_VAL(((RGBA_Draw_Context *)context)->col.col)); + *g = (int)(G_VAL(((RGBA_Draw_Context *)context)->col.col)); + *b = (int)(B_VAL(((RGBA_Draw_Context *)context)->col.col)); + *a = (int)(A_VAL(((RGBA_Draw_Context *)context)->col.col)); + return 1; +} + +static void +evas_engine_software_xcb_context_multiplier_set(void *data, void *context, int r, int g, int b, int a) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_multiplier(context, r, g, b, a); +} + +static void +evas_engine_software_xcb_context_multiplier_unset(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_unset_multiplier(context); +} + +static int +evas_engine_software_xcb_context_multiplier_get(void *data, void *context, int *r, int *g, int *b, int *a) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + *r = (int)(R_VAL(((RGBA_Draw_Context *)context)->mul.col)); + *g = (int)(G_VAL(((RGBA_Draw_Context *)context)->mul.col)); + *b = (int)(B_VAL(((RGBA_Draw_Context *)context)->mul.col)); + *a = (int)(A_VAL(((RGBA_Draw_Context *)context)->mul.col)); + return ((RGBA_Draw_Context *)context)->mul.use; +} + +static void +evas_engine_software_xcb_context_cutout_add(void *data, void *context, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_add_cutout(context, x, y, w, h); +} + +static void +evas_engine_software_xcb_context_cutout_clear(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_clear_cutouts(context); +} + + + + + + +static void +evas_engine_software_xcb_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +#ifdef IMGONLY + return; +#endif + evas_common_rectangle_draw(surface, context, x, y, w, h); + evas_common_cpu_end_opt(); +} + +static void +evas_engine_software_xcb_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +#ifdef IMGONLY + return; +#endif + evas_common_line_draw(surface, context, x1, y1, x2, y2); + evas_common_cpu_end_opt(); +} + +static void * +evas_engine_software_xcb_polygon_point_add(void *data, void *context, void *polygon, int x, int y) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_polygon_point_add(polygon, x, y); + context = NULL; +} + +static void * +evas_engine_software_xcb_polygon_points_clear(void *data, void *context, void *polygon) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_polygon_points_clear(polygon); + context = NULL; +} + +static void +evas_engine_software_xcb_polygon_draw(void *data, void *context, void *surface, void *polygon) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +#ifdef IMGONLY + return; +#endif + evas_common_polygon_draw(surface, context, polygon); + evas_common_cpu_end_opt(); +} + +static void * +evas_engine_software_xcb_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; + if (!gradient) + gradient = evas_common_gradient_new(); + evas_common_gradient_color_add(gradient, r, g, b, a, distance); + return gradient; + context = NULL; +} + +static void * +evas_engine_software_xcb_gradient_colors_clear(void *data, void *context, void *gradient) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + if (gradient) evas_common_gradient_free(gradient); + return NULL; + context = NULL; +} + +static void +evas_engine_software_xcb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +#ifdef IMGONLY + return; +#endif + evas_common_gradient_draw(surface, context, x, y, w, h, gradient, angle); + evas_common_cpu_end_opt(); +} + +static void * +evas_engine_software_xcb_image_load(void *data, char *file, char *key, int *error) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + *error = 0; + return evas_common_load_image_from_file(file, key); +} + +static void * +evas_engine_software_xcb_image_new_from_data(void *data, int w, int h, DATA32 *image_data) +{ + Render_Engine *re; + RGBA_Image *im; + + re = (Render_Engine *)data; + im = evas_common_image_new(); + im->image = evas_common_image_surface_new(im); + if (!im->image) + { + evas_common_image_free(im); + return NULL; + } + im->image->w = w; + im->image->h = h; + im->image->data = image_data; + im->image->no_free = 1; + return im; +} + +static void * +evas_engine_software_xcb_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data) +{ + Render_Engine *re; + RGBA_Image *im; + + re = (Render_Engine *)data; + im = evas_common_image_create(w, h); + if (!im) return NULL; + if (image_data) + memcpy(im->image->data, image_data, w * h * sizeof(DATA32)); + return im; +} + +static void +evas_engine_software_xcb_image_free(void *data, void *image) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_image_unref(image); +} + +static void +evas_engine_software_xcb_image_size_get(void *data, void *image, int *w, int *h) +{ + Render_Engine *re; + RGBA_Image *im; + + re = (Render_Engine *)data; + im = image; + if (w) *w = im->image->w; + if (h) *h = im->image->h; +} + +static void * +evas_engine_software_xcb_image_size_set(void *data, void *image, int w, int h) +{ + Render_Engine *re; + RGBA_Image *im, *im_old; + + re = (Render_Engine *)data; + im_old = image; + im = evas_common_image_create(w, h); + if (!im) return im_old; + if (im_old) + { + evas_common_load_image_data_from_file(im_old); + if (im_old->image->data) + { + evas_common_blit_rectangle(im_old, im, 0, 0, w, h, 0, 0); + evas_common_cpu_end_opt(); + } + evas_common_image_unref(im_old); + } + return im; +} + +static void * +evas_engine_software_xcb_image_dirty_region(void *data, void *image, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_image_dirty(image); + return image; + x = 0; + y = 0; + w = 0; + h = 0; +} + +static void * +evas_engine_software_xcb_image_data_get(void *data, void *image, int to_write, DATA32 **image_data) +{ + Render_Engine *re; + RGBA_Image *im; + + re = (Render_Engine *)data; + im = image; + evas_common_load_image_data_from_file(im); + if (to_write) + { + if (im->references > 1) + { + RGBA_Image *im_new; + + im_new = evas_common_image_create(im->image->w, im->image->h); + if (!im_new) return im; + evas_common_blit_rectangle(im, im_new, 0, 0, im->image->w, im->image->h, 0, 0); + evas_common_cpu_end_opt(); + evas_common_image_unref(im); + im = im_new; + } + else + evas_common_image_dirty(im); + } + *image_data = im->image->data; + return im; +} + +static void * +evas_engine_software_xcb_image_data_put(void *data, void *image, DATA32 *image_data) +{ + Render_Engine *re; + RGBA_Image *im; + + re = (Render_Engine *)data; + im = image; + if (image_data != im->image->data) + { + int w, h; + + w = im->image->w; + h = im->image->h; + evas_common_image_unref(im); + return evas_engine_software_xcb_image_new_from_data(data, w, h, image_data); + } + /* hmmm - but if we wrote... why bother? */ +/* evas_common_image_dirty(im); */ + return im; +} + +static void * +evas_engine_software_xcb_image_alpha_set(void *data, void *image, int has_alpha) +{ + Render_Engine *re; + RGBA_Image *im; + + re = (Render_Engine *)data; + im = image; + if (im->references > 1) + { + RGBA_Image *im_new; + + im_new = evas_common_image_create(im->image->w, im->image->h); + if (!im_new) return im; + evas_common_load_image_data_from_file(im); + evas_common_blit_rectangle(im, im_new, 0, 0, im->image->w, im->image->h, 0, 0); + evas_common_cpu_end_opt(); + evas_common_image_unref(im); + im = im_new; + } + else + evas_common_image_dirty(im); + if (has_alpha) + im->flags |= RGBA_IMAGE_HAS_ALPHA; + else + im->flags &= ~RGBA_IMAGE_HAS_ALPHA; + return im; +} + + +static int +evas_engine_software_xcb_image_alpha_get(void *data, void *image) +{ + Render_Engine *re; + RGBA_Image *im; + + re = (Render_Engine *)data; + im = image; + if (im->flags & RGBA_IMAGE_HAS_ALPHA) return 1; + return 0; +} + +static void +evas_engine_software_xcb_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) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_load_image_data_from_file(image); + if (smooth) + evas_common_scale_rgba_in_to_out_clip_smooth(image, surface, context, + src_x, src_y, src_w, src_h, + dst_x, dst_y, dst_w, dst_h); + else + evas_common_scale_rgba_in_to_out_clip_sample(image, surface, context, + src_x, src_y, src_w, src_h, + dst_x, dst_y, dst_w, dst_h); + evas_common_cpu_end_opt(); +} + +static char * +evas_engine_software_xcb_image_comment_get(void *data, void *image, char *key) +{ + Render_Engine *re; + RGBA_Image *im; + + re = (Render_Engine *)data; + im = image; + return im->info.comment; + key = 0; +} + +static char * +evas_engine_software_xcb_image_format_get(void *data, void *image) +{ + Render_Engine *re; + RGBA_Image *im; + + re = (Render_Engine *)data; + im = image; + if (im->info.format == 1) return "png"; + return NULL; +} + +static void +evas_engine_software_xcb_image_cache_flush(void *data) +{ + Render_Engine *re; + int tmp_size; + + re = (Render_Engine *)data; + tmp_size = evas_common_image_get_cache(); + evas_common_image_set_cache(0); + evas_common_image_set_cache(tmp_size); +} + +static void +evas_engine_software_xcb_image_cache_set(void *data, int bytes) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_image_set_cache(bytes); +} + +static int +evas_engine_software_xcb_image_cache_get(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_image_get_cache(); +} + +static void * +evas_engine_software_xcb_font_load(void *data, char *name, int size) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_load(name, size); +} + +static void * +evas_engine_software_xcb_font_memory_load(void *data, char *name, int size, const void *fdata, int fdata_size) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_memory_load(name, size, fdata, fdata_size); +} + +static void * +evas_engine_software_xcb_font_add(void *data, void *font, char *name, int size) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_add(font, name, size); +} + +static void * +evas_engine_software_xcb_font_memory_add(void *data, void *font, char *name, int size, const void *fdata, int fdata_size) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_memory_add(font, name, size, fdata, fdata_size); +} + +static void +evas_engine_software_xcb_font_free(void *data, void *font) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_font_free(font); +} + +static int +evas_engine_software_xcb_font_ascent_get(void *data, void *font) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_ascent_get(font); +} + +static int +evas_engine_software_xcb_font_descent_get(void *data, void *font) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_descent_get(font); +} + +static int +evas_engine_software_xcb_font_max_ascent_get(void *data, void *font) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_max_ascent_get(font); +} + +static int +evas_engine_software_xcb_font_max_descent_get(void *data, void *font) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_max_descent_get(font); +} + +static void +evas_engine_software_xcb_font_string_size_get(void *data, void *font, char *text, int *w, int *h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_font_query_size(font, text, w, h); +} + +static int +evas_engine_software_xcb_font_inset_get(void *data, void *font, char *text) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_query_inset(font, text); +} + +static int +evas_engine_software_xcb_font_h_advance_get(void *data, void *font, char *text) +{ + Render_Engine *re; + int h, v; + + re = (Render_Engine *)data; + evas_common_font_query_advance(font, text, &h, &v); + return h; +} + +static int +evas_engine_software_xcb_font_v_advance_get(void *data, void *font, char *text) +{ + Render_Engine *re; + int h, v; + + re = (Render_Engine *)data; + evas_common_font_query_advance(font, text, &h, &v); + return v; +} + +static int +evas_engine_software_xcb_font_char_coords_get(void *data, void *font, char *text, int pos, int *cx, int *cy, int *cw, int *ch) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_query_char_coords(font, text, pos, cx, cy, cw, ch); +} + +static int +evas_engine_software_xcb_font_char_at_coords_get(void *data, void *font, char *text, int x, int y, int *cx, int *cy, int *cw, int *ch) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_query_text_at_pos(font, text, x, y, cx, cy, cw, ch); +} + +static void +evas_engine_software_xcb_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; +#ifdef IMGONLY + return; +#endif + if ((w == ow) && (h == oh)) + evas_common_font_draw(surface, context, font, x, y, text); + else + { + /* create output surface size ow x oh and scale to w x h */ + RGBA_Draw_Context *dc, *dc_in; + + dc_in = context; + dc = evas_common_draw_context_new(); + if (dc) + { + RGBA_Image *im; + int inset; + + dc->col.col = dc_in->col.col; + inset = evas_common_font_query_inset( font, text); + im = evas_common_image_create(ow+inset, oh); + if (im) + { + int max_ascent; + int j; + + im->flags |= RGBA_IMAGE_HAS_ALPHA; + j = (ow+inset) * oh; + memset(im->image->data, 0, j * sizeof(DATA32)); + + max_ascent = evas_common_font_max_ascent_get(font); + + evas_common_font_draw(im, dc, font, 0, max_ascent, text); + evas_common_cpu_end_opt(); + evas_common_scale_rgba_in_to_out_clip_smooth(im, surface, context, + inset, 0, ow, oh, + x + ((inset * w) / ow), y - ((max_ascent * h) / oh), + w, h); + evas_common_image_free(im); + } + evas_common_draw_context_free(dc); + } + } + evas_common_cpu_end_opt(); +} + +static void +evas_engine_software_xcb_font_cache_flush(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_font_flush(); +} + +static void +evas_engine_software_xcb_font_cache_set(void *data, int bytes) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_font_cache_set(bytes); +} + +static int +evas_engine_software_xcb_font_cache_get(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_font_cache_get(); +} + + + + + + + + + +/* private engine functions the calling prog can use */ + +/* Convenient function for getting the best visual, colormap and depth */ +static XCBSCREEN * +evas_engine_software_xcb_screen_get(XCBConnection *conn, int screen) +{ + XCBSCREENIter i; + int cur; + + if (!conn) return NULL; + + i = XCBConnSetupSuccessRepRootsIter(XCBGetSetup(conn)); + if (screen > i.rem - 1) return NULL; /* screen must be between 0 and i.rem - 1 */ + for (cur = 0; cur <= screen; XCBSCREENNext(&i), ++cur) {} + + return i.data; +} + +static XCBVISUALTYPE * +evas_engine_software_xcb_best_visual_get(XCBConnection *conn, int screen) +{ + XCBSCREEN *scr; + XCBDEPTH *d; + XCBVISUALTYPEIter iter; + int cur; + + if (!conn) return NULL; + scr = evas_engine_software_xcb_screen_get(conn, screen); + if (!scr) return NULL; + d = XCBSCREENAllowedDepthsIter(scr).data; + if (!d) return NULL; + + iter = XCBDEPTHVisualsIter(d); + for (cur = 0 ; cur < iter.rem ; XCBVISUALTYPENext(&iter), ++cur) + if (scr->root_visual.id == iter.data->visual_id.id) + return iter.data; + + return NULL; +} + +static XCBCOLORMAP +evas_engine_software_xcb_best_colormap_get(XCBConnection *conn, int screen) +{ + XCBSCREEN *scr; + XCBCOLORMAP c; + + c.xid = 0; + if (!conn) return c; + scr = evas_engine_software_xcb_screen_get(conn, screen); + if (!scr) return c; + + return scr->default_colormap; +} + +static int +evas_engine_software_xcb_best_depth_get(XCBConnection *conn, int screen) +{ + XCBSCREEN *scr; + + if (!conn) return 0; + scr = evas_engine_software_xcb_screen_get(conn, screen); + if (!scr) return 0; + + return scr->root_depth; +} + +static Evas_Performance * +evas_engine_software_xcb_output_perf_new(Evas *e, XCBConnection *conn, XCBVISUALTYPE *vis, XCBCOLORMAP cmap, XCBDRAWABLE draw, int depth) +{ + return evas_software_x11_outbuf_software_xcb_perf_new_x(conn, draw, vis, cmap, depth); + e = NULL; +} + +static Evas_Performance * +evas_engine_software_xcb_output_perf_test(Evas *e, XCBConnection *conn, XCBVISUALTYPE *vis, XCBCOLORMAP cmap, XCBDRAWABLE draw, int depth) +{ + return evas_software_x11_outbuf_software_xcb_perf_x(conn, draw, vis, cmap, depth); + e = NULL; +} + +static char * +evas_engine_software_xcb_output_perf_data(Evas_Performance *perf) +{ + return evas_software_x11_outbuf_software_xcb_perf_serialize_x(perf); +} + +static char * +evas_engine_software_xcb_output_perf_key(Evas_Performance *perf) +{ + return evas_software_x11_outbuf_software_xcb_perf_serialize_info_x(perf); +} + +static void +evas_engine_software_xcb_output_perf_free(Evas_Performance *perf) +{ + evas_software_x11_outbuf_software_xcb_perf_free(perf); +} + +static void +evas_engine_software_xcb_output_perf_build(Evas_Performance *perf, const char *data) +{ + evas_software_x11_outbuf_software_xcb_perf_deserialize_x(perf, data); +} + +static void +evas_engine_software_xcb_output_perf_device_store(Evas_Performance *perf) +{ + evas_software_x11_outbuf_software_xcb_perf_store_x(perf); +} diff --git a/legacy/evas/src/lib/engines/software_xcb/evas_engine.h b/legacy/evas/src/lib/engines/software_xcb/evas_engine.h new file mode 100644 index 0000000000..52596176c3 --- /dev/null +++ b/legacy/evas/src/lib/engines/software_xcb/evas_engine.h @@ -0,0 +1,215 @@ +#ifndef EVAS_ENGINE_H +#define EVAS_ENGINE_H + +#include + +typedef struct _Outbuf Outbuf; +typedef struct _Outbuf_Perf Outbuf_Perf; +typedef struct _Xcb_Output_Buffer Xcb_Output_Buffer; + +typedef enum _Outbuf_Depth Outbuf_Depth; + +enum _Outbuf_Depth +{ + OUTBUF_DEPTH_NONE, + OUTBUF_DEPTH_INHERIT, + OUTBUF_DEPTH_RGB_16BPP_565_565_DITHERED, + OUTBUF_DEPTH_RGB_16BPP_555_555_DITHERED, + OUTBUF_DEPTH_RGB_16BPP_444_444_DITHERED, + OUTBUF_DEPTH_RGB_16BPP_565_444_DITHERED, + OUTBUF_DEPTH_RGB_32BPP_888_8888, + OUTBUF_DEPTH_LAST +}; + +struct _Outbuf +{ + Outbuf_Depth depth; + int w, h; + int rot; + Outbuf_Perf *perf; + + struct { + Convert_Pal *pal; + struct { + XCBConnection *conn; + XCBDRAWABLE win; + XCBDRAWABLE mask; + XCBVISUALTYPE *vis; + XCBCOLORMAP cmap; + int depth; + int shm; + XCBGCONTEXT gc; + XCBGCONTEXT gcm; + int swap : 1; + } x; + struct { + DATA32 r, g, b; + } mask; + RGBA_Image *back_buf; + + int mask_dither : 1; + + int debug : 1; + } priv; +}; + +struct _Outbuf_Perf +{ + struct { + XCBConnection *conn; + XCBDRAWABLE root; + + char *display; + char *vendor; + int version; + int revision; + int release; + int w, h; + int screen_count; + int depth; + int screen_num; + } x; + struct{ + char *name; + char *version; + char *machine; + } os; + struct { + char *info; + } cpu; + + int min_shm_image_pixel_count; +}; + +/****/ +/* main */ +void evas_software_x11_x_software_xcb_init (void); + +/* buffer */ +void evas_software_x11_x_software_xcb_write_mask_line (Xcb_Output_Buffer *xcbob, + DATA32 *src, + int w, + int y); +int evas_software_x11_x_software_xcb_can_do_shm (XCBConnection *c); +Xcb_Output_Buffer *evas_software_x11_x_software_xcb_output_buffer_new (XCBConnection *c, + int depth, + int w, + int h, + int try_shm, + void *data); +void evas_software_x11_x_software_xcb_output_buffer_free (Xcb_Output_Buffer *xcbob); +void evas_software_x11_x_software_xcb_output_buffer_paste (Xcb_Output_Buffer *xcbob, + XCBDRAWABLE d, + XCBGCONTEXT gc, + int x, + int y); +DATA8 *evas_software_x11_x_software_xcb_output_buffer_data (Xcb_Output_Buffer *xcbob, + int *bytes_per_line_ret); +int evas_software_x11_x_software_xcb_output_buffer_depth (Xcb_Output_Buffer *xcbob); +int evas_software_x11_x_software_xcb_output_buffer_byte_order(Xcb_Output_Buffer *xcbob); + +/* color */ +void x_software_xcb_color_init (void); +Convert_Pal *evas_software_x11_x_software_xcb_color_allocate (XCBConnection *conn, + XCBCOLORMAP cmap, + XCBVISUALTYPE *vis, + Convert_Pal_Mode colors); +void evas_software_x11_x_software_xcb_color_deallocate (XCBConnection *conn, + XCBCOLORMAP cmap, + XCBVISUALTYPE *vis, + Convert_Pal *pal); + +/* outbuf */ +void evas_software_x11_outbuf_software_xcb_init (void); +void evas_software_x11_outbuf_software_xcb_free (Outbuf *buf); +Outbuf *evas_software_x11_outbuf_software_xcb_setup_x (int w, + int h, + int rot, + Outbuf_Depth depth, + XCBConnection *conn, + XCBDRAWABLE draw, + XCBVISUALTYPE *vis, + XCBCOLORMAP cmap, + int x_depth, + Outbuf_Perf *perf, + int grayscale, + int max_colors, + XCBDRAWABLE mask, + int shape_dither); + +char *evas_software_x11_outbuf_software_xcb_perf_serialize_x (Outbuf_Perf *perf); +void evas_software_x11_outbuf_software_xcb_perf_deserialize_x (Outbuf_Perf *perf, + const char *data); +Outbuf_Perf *evas_software_x11_outbuf_software_xcb_perf_new_x (XCBConnection *conn, + XCBDRAWABLE draw, + XCBVISUALTYPE *vis, + XCBCOLORMAP cmap, + int x_depth); + +char *evas_software_x11_outbuf_software_xcb_perf_serialize_info_x (Outbuf_Perf *perf); +void evas_software_x11_outbuf_software_xcb_perf_store_x (Outbuf_Perf *perf); +Outbuf_Perf *evas_software_x11_outbuf_software_xcb_perf_restore_x (XCBConnection *conn, + XCBDRAWABLE draw, + XCBVISUALTYPE *vis, + XCBCOLORMAP cmap, + int x_depth); +void evas_software_x11_outbuf_software_xcb_perf_free (Outbuf_Perf *perf); +Outbuf_Perf *evas_software_x11_outbuf_software_xcb_perf_x (XCBConnection *conn, + XCBDRAWABLE draw, + XCBVISUALTYPE *vis, + XCBCOLORMAP cmap, + int x_depth); + +void evas_software_x11_outbuf_software_xcb_blit (Outbuf *buf, + int src_x, + int src_y, + int w, + int h, + int dst_x, + int dst_y); +void evas_software_x11_outbuf_software_xcb_update (Outbuf *buf, + int x, + int y, + int w, + int h); +RGBA_Image *evas_software_x11_outbuf_software_xcb_new_region_for_update (Outbuf *buf, + int x, + int y, + int w, + int h, + int *cx, + int *cy, + int *cw, + int *ch); +void evas_software_x11_outbuf_software_xcb_free_region_for_update (Outbuf *buf, + RGBA_Image *update); +void evas_software_x11_outbuf_software_xcb_push_updated_region (Outbuf *buf, + RGBA_Image *update, + int x, + int y, + int w, + int h); +void evas_software_x11_outbuf_software_xcb_reconfigure (Outbuf *buf, + int w, + int h, + int rot, + Outbuf_Depth depth); +int evas_software_x11_outbuf_software_xcb_get_width (Outbuf *buf); +int evas_software_x11_outbuf_software_xcb_get_height (Outbuf *buf); +Outbuf_Depth evas_software_x11_outbuf_software_xcb_get_depth (Outbuf *buf); +int evas_software_x11_outbuf_software_xcb_get_rot (Outbuf *buf); +int evas_software_x11_outbuf_software_xcb_get_have_backbuf (Outbuf *buf); +void evas_software_x11_outbuf_software_xcb_set_have_backbuf (Outbuf *buf, int have_backbuf); +void evas_software_x11_outbuf_software_xcb_drawable_set (Outbuf *buf, XCBDRAWABLE draw); +void evas_software_x11_outbuf_software_xcb_mask_set (Outbuf *buf, XCBDRAWABLE mask); +void evas_software_x11_outbuf_software_xcb_rotation_set (Outbuf *buf, int rot); + +void evas_software_x11_outbuf_software_xcb_debug_set (Outbuf *buf, int debug); +void evas_software_x11_outbuf_software_xcb_debug_show (Outbuf *buf, + XCBDRAWABLE draw, + int x, + int y, + int w, + int h); + +#endif /* EVAS_ENGINE_H */ diff --git a/legacy/evas/src/lib/engines/software_xcb/evas_outbuf.c b/legacy/evas/src/lib/engines/software_xcb/evas_outbuf.c new file mode 100644 index 0000000000..6216fef7a1 --- /dev/null +++ b/legacy/evas/src/lib/engines/software_xcb/evas_outbuf.c @@ -0,0 +1,1504 @@ +#include "evas_common.h" +#include "evas_engine.h" +#include +#include +#include +#include +#include + +static double evas_software_x11_outbuf_software_xcb_get_time(void); + +/* used for performance tester code */ +static double +evas_software_x11_outbuf_software_xcb_get_time(void) +{ + struct timeval timev; + + gettimeofday(&timev, NULL); + return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000); +} + +void +evas_software_x11_outbuf_software_xcb_init(void) +{ +} + +void +evas_software_x11_outbuf_software_xcb_free(Outbuf * buf) +{ + XCBFreeGC(buf->priv.x.conn, buf->priv.x.gc); + if (buf->priv.x.gcm.xid) + XCBFreeGC(buf->priv.x.conn, buf->priv.x.gcm); + if (buf->priv.pal) + evas_software_x11_x_software_xcb_color_deallocate(buf->priv.x.conn, + buf->priv.x.cmap, + buf->priv.x.vis, + buf->priv.pal); + if (buf->priv.back_buf) + evas_common_image_free(buf->priv.back_buf); + evas_software_x11_outbuf_software_xcb_perf_free(buf->perf); + free(buf); +} + +void +evas_software_x11_outbuf_software_xcb_rotation_set(Outbuf *buf, int rot) +{ + buf->rot = rot; +} + +Outbuf * +evas_software_x11_outbuf_software_xcb_setup_x(int w, + int h, + int rot, + Outbuf_Depth depth, + XCBConnection *conn, + XCBDRAWABLE draw, + XCBVISUALTYPE *vis, + XCBCOLORMAP cmap, + int x_depth, + Outbuf_Perf *perf, + int grayscale, + int max_colors, + XCBDRAWABLE mask, + int shape_dither) +{ + Outbuf *buf; + + buf = calloc(1, sizeof(Outbuf)); + if (!buf) + { + free(buf); + return NULL; + } + + buf->w = w; + buf->h = h; + buf->depth = depth; + buf->rot = rot; + + buf->priv.x.conn = conn; + buf->priv.x.vis = vis; + buf->priv.x.cmap = cmap; + buf->priv.x.depth = x_depth; + + buf->priv.mask_dither = shape_dither; + + { + Gfx_Func_Convert conv_func; + Xcb_Output_Buffer *xcbob; + + buf->priv.x.shm = evas_software_x11_x_software_xcb_can_do_shm(buf->priv.x.conn); + xcbob = evas_software_x11_x_software_xcb_output_buffer_new(buf->priv.x.conn, + buf->priv.x.depth, + 1, 1, + buf->priv.x.shm, NULL); + + conv_func = NULL; + if (xcbob) + { +#ifdef WORDS_BIGENDIAN + if (evas_software_x11_x_software_xcb_output_buffer_byte_order(xcbob) == LSBFirst) + buf->priv.x.swap = 1; +#else + if (evas_software_x11_x_software_xcb_output_buffer_byte_order(xcbob) == MSBFirst) + buf->priv.x.swap = 1; +#endif + if ((vis->_class == TrueColor) || (vis->_class == DirectColor)) + { + buf->priv.mask.r = (DATA32) vis->red_mask; + buf->priv.mask.g = (DATA32) vis->green_mask; + buf->priv.mask.b = (DATA32) vis->blue_mask; + if (buf->priv.x.swap) + { + SWAP32(buf->priv.mask.r); + SWAP32(buf->priv.mask.g); + SWAP32(buf->priv.mask.b); + } + } + else if ((vis->_class == PseudoColor) || + (vis->_class == StaticColor) || + (vis->_class == GrayScale) || (vis->_class == StaticGray)) + { + Convert_Pal_Mode pm = PAL_MODE_RGB332; + + if ((vis->_class == GrayScale) || (vis->_class == StaticGray)) + grayscale = 1; + if (grayscale) + { + if (max_colors >= 256) + pm = PAL_MODE_GRAY256; + else if (max_colors >= 64) + pm = PAL_MODE_GRAY64; + else if (max_colors >= 16) + pm = PAL_MODE_GRAY16; + else if (max_colors >= 4) + pm = PAL_MODE_GRAY4; + else + pm = PAL_MODE_MONO; + } + else + { + if (max_colors >= 256) + pm = PAL_MODE_RGB332; + else if (max_colors >= 216) + pm = PAL_MODE_RGB666; + else if (max_colors >= 128) + pm = PAL_MODE_RGB232; + else if (max_colors >= 64) + pm = PAL_MODE_RGB222; + else if (max_colors >= 32) + pm = PAL_MODE_RGB221; + else if (max_colors >= 16) + pm = PAL_MODE_RGB121; + else if (max_colors >= 8) + pm = PAL_MODE_RGB111; + else if (max_colors >= 4) + pm = PAL_MODE_GRAY4; + else + pm = PAL_MODE_MONO; + } + buf->priv.pal = + evas_software_x11_x_software_xcb_color_allocate(conn, + cmap, + vis, + PAL_MODE_RGB666); + if (!buf->priv.pal) + { + free(buf); + return NULL; + } + } + if (buf->priv.pal) + { + if (buf->rot == 0) + conv_func = evas_common_convert_func_get(0, + buf->w, + buf->h, + evas_software_x11_x_software_xcb_output_buffer_depth (xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + buf->priv.pal->colors, + buf->rot); + else if (buf->rot == 270) + conv_func = evas_common_convert_func_get(0, + buf->h, + buf->w, + evas_software_x11_x_software_xcb_output_buffer_depth (xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + buf->priv.pal->colors, + buf->rot); + else if (buf->rot == 90) + conv_func = evas_common_convert_func_get(0, + buf->h, + buf->w, + evas_software_x11_x_software_xcb_output_buffer_depth(xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + buf->priv.pal->colors, + buf->rot); + } + else + { + if (buf->rot == 0) + conv_func = evas_common_convert_func_get(0, + buf->w, + buf->h, + evas_software_x11_x_software_xcb_output_buffer_depth(xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + buf->rot); + else if (buf->rot == 270) + conv_func = evas_common_convert_func_get(0, + buf->h, + buf->w, + evas_software_x11_x_software_xcb_output_buffer_depth(xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + buf->rot); + else if (buf->rot == 90) + conv_func = evas_common_convert_func_get(0, + buf->h, + buf->w, + evas_software_x11_x_software_xcb_output_buffer_depth(xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + buf->rot); + } + evas_software_x11_x_software_xcb_output_buffer_free(xcbob); + if (!conv_func) + { + printf(".[ Evas Error ].\n" + " {\n" + " At depth %i:\n" + " RGB format mask: %08x, %08x, %08x\n" + " Palette mode: %i\n" + " Not supported by and compiled in converters!\n" + " }\n", + buf->priv.x.depth, + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + buf->priv.pal->colors); + } + } + evas_software_x11_outbuf_software_xcb_drawable_set(buf, draw); + evas_software_x11_outbuf_software_xcb_mask_set(buf, mask); + } + +#if 0 + if (buf->priv.x.depth < 24) + buf->priv.back_buf = evas_common_image_create(buf->w, buf->h); +#endif + + buf->perf = perf; + + return buf; +} + +char * +evas_software_x11_outbuf_software_xcb_perf_serialize_x(Outbuf_Perf * perf) +{ + /* take performance results and turn it inot a munged string that can be */ + /* written out somewhere by a program */ + char buf[256]; + + snprintf(buf, sizeof(buf), "%i", perf->min_shm_image_pixel_count); + return strdup(buf); +} + +void +evas_software_x11_outbuf_software_xcb_perf_deserialize_x(Outbuf_Perf *perf, + const char *data) +{ + /* take a munged string that is the result of outbuf_perf_serialize_x() */ + /* and turn it back into a structure and fill the provided perf struct */ + /* with it. the perf struct is assumed to be pristine from */ + /* outbuf_perf_new_x() */ + int val; + + val = 200 * 200; + if (sscanf(data, "%i", &val) != 1) + val = 200 * 200; + if (val < 0) + val = 200 * 200; + perf->min_shm_image_pixel_count = val; + return; +} + +Outbuf_Perf * +evas_software_x11_outbuf_software_xcb_perf_new_x(XCBConnection *conn, + XCBDRAWABLE draw, + XCBVISUALTYPE *vis, + XCBCOLORMAP cmap, + int x_depth) +{ + /* create an "empty" perf struct with just the system & display info */ + Outbuf_Perf *perf; + XCBDRAWABLE root; + struct utsname un; + FILE *f; + + perf = calloc(1, sizeof(Outbuf_Perf)); + + perf->x.conn = conn; + + root.window = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (conn)).data->root; + if (draw.window.xid) + { + XCBGetGeometryRep *geom; + XCBSCREENIter i; + int cur; + + geom = XCBGetGeometryReply (conn, XCBGetGeometry (conn, draw), NULL); + root.window = geom->root; + free (geom); + geom = XCBGetGeometryReply (conn, XCBGetGeometry (conn, root), 0); + perf->x.w = (int)geom->width; + perf->x.h = (int)geom->height; + + perf->x.screen_num = 0; + i = XCBConnSetupSuccessRepRootsIter(XCBGetSetup(conn)); + for (cur = 0; cur < i.rem; XCBSCREENNext(&i), ++cur) + if (i.data->root.xid == geom->root.xid) + { + perf->x.screen_num = cur; + break; + } + free (geom); + } + perf->x.root = root; + + perf->x.display = strdup (":0"); /* FIXME: strdup(DisplayString(disp)); in XCB ? */ + perf->x.vendor = strdup(XCBConnSetupSuccessRepVendor(XCBGetSetup(conn))); + perf->x.version = (int)XCBGetSetup(conn)->protocol_major_version; + perf->x.revision = (int)XCBGetSetup(conn)->protocol_minor_version; + perf->x.release = (int)XCBGetSetup(conn)->release_number; + perf->x.screen_count = XCBConnSetupSuccessRepRootsIter(XCBGetSetup(conn)).rem; + perf->x.depth = x_depth; + + perf->min_shm_image_pixel_count = 200 * 200; /* default hard-coded */ + + if (!uname(&un)) + { + perf->os.name = strdup(un.sysname); + perf->os.version = strdup(un.release); + perf->os.machine = strdup(un.machine); + } + /* for linux */ + f = fopen("/proc/cpuinfo", "r"); + if (f) + { + char buf[16384]; + size_t sz; + + /* read up tothe first 16k of it... shoudl be nice and fast and easy */ + sz = fread(buf, 1, 16380, f); + if (sz > 0) + { + perf->cpu.info = malloc(sz + 1); + strncpy(perf->cpu.info, buf, sz); + perf->cpu.info[sz] = 0; + } + fclose(f); + } + else + { + /* for FreeBSD... maybe */ + f = fopen("/var/run/dmesg.boot", "r"); + /* for NetBSD... maybe */ + if (!f) + f = fopen("/kern/msgbuf", "r"); + if (f) + { + char buf[4096]; + int l; + + l = 0; + while (fgets(buf, sizeof(buf), f)) + { + int len; + + /* to read lines like: */ + /* CPU: AMD-K7(tm) Processor (698.65-MHz 686-class CPU) */ + /* Features=0x81f9ff */ + if ((!strncmp(buf, "CPU: ", 5)) || + (!strncmp(buf, "Features=", 9))) + { + len = strlen(buf); + l += len; + if (!perf->cpu.info) + perf->cpu.info = strdup(buf); + else + { + perf->cpu.info = realloc(perf->cpu.info, l + 1); + if (perf->cpu.info) + strcat(perf->cpu.info, buf); + } + } + } + fclose(f); + } + } + if (!perf->cpu.info) + perf->cpu.info = strdup(""); + return perf; + vis = NULL; + cmap.xid = 0; +} + +char * +evas_software_x11_outbuf_software_xcb_perf_serialize_info_x(Outbuf_Perf * perf) +{ + /* get a seriazed string that is a unique identifier for your */ + /* hardware/x/connection setup. */ + char buf[32768]; + int sum1, sum2, i; + char *p; + + sum1 = 0; + sum2 = 0; + snprintf(buf, sizeof(buf), + "%s|%s|%i|%i|%i|%i|%i|%i|%i|%i|%s|%s|%s|%s", + perf->x.display, perf->x.vendor, perf->x.version, perf->x.revision, + perf->x.release, perf->x.w, perf->x.h, perf->x.screen_count, + perf->x.depth, perf->x.screen_num, + perf->os.name, perf->os.version, perf->os.machine, perf->cpu.info); + p = buf; + i = 0; + while (*p) + { + sum1 += (int)(*p) << (i % 24); + sum2 ^= ((int)(*p) << (i % 24)) * ((int)(*p)); + i++; + p++; + } + snprintf(buf, sizeof(buf), "%08x%08x", sum1, sum2); + return strdup(buf); +} + +void +evas_software_x11_outbuf_software_xcb_perf_store_x(Outbuf_Perf * perf) +{ + /* write performance results to x root property */ + XCBInternAtomRep *rep; + XCBATOM type, format; + char *type_str; + char *str; + + type_str = "__EVAS_PERF_ENGINE_SOFTWARE"; + rep = XCBInternAtomReply(perf->x.conn, + XCBInternAtom(perf->x.conn, + 0, + strlen (type_str), + type_str), + NULL); + type = rep->atom; + format.xid = XA_STRING; + + str = evas_software_x11_outbuf_software_xcb_perf_serialize_x(perf); + XCBChangeProperty(perf->x.conn, PropModeReplace, perf->x.root.window, + type, format, 8, + strlen(str), str); +/* XSync(perf->x.disp, False); */ + free(str); +} + +Outbuf_Perf * +evas_software_x11_outbuf_software_xcb_perf_restore_x(XCBConnection *conn, + XCBDRAWABLE draw, + XCBVISUALTYPE *vis, + XCBCOLORMAP cmap, + int x_depth) +{ + /* read performance results from root window */ + XCBInternAtomRep *type_rep; + XCBGetPropertyCookie cookie; + XCBGetPropertyRep *prop_rep; + char *type_str; + XCBATOM type, format; + Outbuf_Perf *perf; + char *retval; + int retnum; + + perf = evas_software_x11_outbuf_software_xcb_perf_new_x(conn, draw, vis, cmap, x_depth); + + type_str = "__EVAS_PERF_ENGINE_SOFTWARE"; + type_rep = XCBInternAtomReply(conn, + XCBInternAtom(conn, + 0, + strlen (type_str), + type_str), + NULL); + type = type_rep->atom; + format.xid = XA_STRING; + retval = NULL; + + cookie = XCBGetProperty(conn, 0, perf->x.root.window, + type, format, + 0, 16384); + prop_rep = XCBGetPropertyReply(conn, cookie, NULL); + + retval = XCBGetPropertyValue(prop_rep); + retnum = XCBGetPropertyValueLength(prop_rep); + if (retval) + { + if ((prop_rep->format == 8) && + (prop_rep->type.xid == type.xid)) + { + char *s; + + s = malloc(retnum + 1); + strncpy(s, retval, retnum); + s[retnum] = 0; + evas_software_x11_outbuf_software_xcb_perf_deserialize_x(perf, s); + free(s); + } + /* FIXME: doesn't seem to be need (from valgrind) */ +/* free(retval); */ + } + return perf; +} + +void +evas_software_x11_outbuf_software_xcb_perf_free(Outbuf_Perf * perf) +{ + /* free the perf struct */ + free(perf->x.display); + free(perf->x.vendor); + free(perf->os.name); + free(perf->os.version); + free(perf->os.machine); + free(perf->cpu.info); + free(perf); +} + +Outbuf_Perf * +evas_software_x11_outbuf_software_xcb_perf_x(XCBConnection *conn, + XCBDRAWABLE draw, + XCBVISUALTYPE *vis, + XCBCOLORMAP cmap, + int x_depth) +{ + Outbuf_Perf *perf; + XCBDRAWABLE win; + CARD32 mask; + CARD32 value[7]; + int w, h; + int do_shm = 0; + + perf = evas_software_x11_outbuf_software_xcb_perf_new_x(conn, draw, vis, cmap, x_depth); + + mask = CWBackingStore | CWColormap | + CWBackPixmap | CWBorderPixel | + CWBitGravity | CWEventMask | CWOverrideRedirect; + value[0] = Always; + value[1] = cmap.xid; + value[2] = None; + value[3] = 0; + value[4] = ForgetGravity; + value[5] = 0; + value[6] = 1; + w = perf->x.w; + h = perf->x.h; + win.window = XCBWINDOWNew (conn); + XCBCreateWindow (conn, x_depth, + win.window, perf->x.root.window, + 0, 0, + w, h, + 0, + InputOutput, + vis->visual_id, + mask, value); + XCBSync(conn, 0); + XCBMapWindow (conn, win.window); + + do_shm = evas_software_x11_x_software_xcb_can_do_shm(conn); + + /* set it to something ridiculous to start */ + perf->min_shm_image_pixel_count = w * w; + + if (do_shm) + { + Xcb_Output_Buffer *xcbob; + XCBGCONTEXT gc; + CARD32 gcv; + int i; + int max; + int error; + int chosen; + + chosen = 0; + error = 0; + max = w; + if (w > h) + max = h; + gc = XCBGCONTEXTNew (conn); + XCBCreateGC (conn, gc, win, 0, &gcv); + for (i = 16; i < max; i += 16) + { + int l; + double t0, t1, t2; + int loops; + + loops = (h * h * 5) / (i * i); + t0 = evas_software_x11_outbuf_software_xcb_get_time(); + for (l = 0; l < loops; l++) + { + xcbob = evas_software_x11_x_software_xcb_output_buffer_new(conn, + x_depth, + i, i, + do_shm, + NULL); + if (!xcbob) + error = 1; + else + { + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + win, + gc, + 0, 0); + evas_software_x11_x_software_xcb_output_buffer_free(xcbob); + } + } + XCBSync(conn, 0); + t1 = evas_software_x11_outbuf_software_xcb_get_time() - t0; + t0 = evas_software_x11_outbuf_software_xcb_get_time(); + for (l = 0; l < loops; l++) + { + xcbob = evas_software_x11_x_software_xcb_output_buffer_new(conn, + x_depth, + i, i, + 0, + NULL); + if (!xcbob) + error = 1; + else + { + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + win, + gc, + 0, 0); + evas_software_x11_x_software_xcb_output_buffer_free(xcbob); + } + } + XCBSync(conn, 0); + t2 = evas_software_x11_outbuf_software_xcb_get_time() - t0; + if ((!chosen) && (!error)) + { + if ((t1 / t2) < 1.0) + { + perf->min_shm_image_pixel_count = (i - 8) * (i - 8); + chosen = 1; + } + } + } + XCBFreeGC(conn, gc); + } + XCBDestroyWindow(conn, win.window); + return perf; +} + +void +evas_software_x11_outbuf_software_xcb_blit(Outbuf *buf, + int src_x, + int src_y, + int w, + int h, + int dst_x, + int dst_y) +{ + if (buf->priv.back_buf) + { + evas_common_blit_rectangle(buf->priv.back_buf, buf->priv.back_buf, + src_x, src_y, w, h, dst_x, dst_y); + evas_software_x11_outbuf_software_xcb_update(buf, dst_x, dst_y, w, h); + } + else + { + if (buf->priv.x.conn) + { + if (buf->rot == 0) + XCBCopyArea(buf->priv.x.conn, + buf->priv.x.win, buf->priv.x.win, + buf->priv.x.gc, + src_x, src_y, + w, h, + dst_x, dst_y); + else if (buf->rot == 270) + XCBCopyArea(buf->priv.x.conn, + buf->priv.x.win, buf->priv.x.win, + buf->priv.x.gc, + buf->h - src_y - h, src_x, + h, w, + dst_y, dst_x); + else if (buf->rot == 90) + XCBCopyArea(buf->priv.x.conn, + buf->priv.x.win, buf->priv.x.win, + buf->priv.x.gc, + src_y, buf->w - src_x - w, + h, w, + dst_y, dst_x); + } + } +} + +void +evas_software_x11_outbuf_software_xcb_update(Outbuf *buf, int x, int y, int w, int h) +{ + Gfx_Func_Convert conv_func; + DATA8 *data; + Xcb_Output_Buffer *xcbob; + int bpl; + int use_shm; + + if (!(buf->priv.back_buf)) + return; + use_shm = buf->priv.x.shm; + if (buf->perf) + { + if ((w * h) < buf->perf->min_shm_image_pixel_count) + use_shm = 0; + } + else + { + if ((w * h) < (200 * 200)) + use_shm = 0; + } + xcbob = NULL; + if (buf->rot == 0) + xcbob = evas_software_x11_x_software_xcb_output_buffer_new(buf->priv.x.conn, + buf->priv.x.depth, + w, h, + use_shm, + NULL); + else if (buf->rot == 270) + xcbob = evas_software_x11_x_software_xcb_output_buffer_new(buf->priv.x.conn, + buf->priv.x.depth, + h, w, + use_shm, + NULL); + else if (buf->rot == 90) + xcbob = evas_software_x11_x_software_xcb_output_buffer_new(buf->priv.x.conn, + buf->priv.x.depth, + h, w, + use_shm, + NULL); + if (!xcbob) + return; + data = evas_software_x11_x_software_xcb_output_buffer_data(xcbob, &bpl); + conv_func = NULL; + if (buf->priv.pal) + { + if (buf->rot == 0) + conv_func = evas_common_convert_func_get(0, w, h, + evas_software_x11_x_software_xcb_output_buffer_depth(xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + buf->priv.pal->colors, + buf->rot); + else if (buf->rot == 270) + conv_func = evas_common_convert_func_get(0, h, w, + evas_software_x11_x_software_xcb_output_buffer_depth(xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + buf->priv.pal->colors, + buf->rot); + else if (buf->rot == 90) + conv_func = evas_common_convert_func_get(0, h, w, + evas_software_x11_x_software_xcb_output_buffer_depth(xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + buf->priv.pal->colors, + buf->rot); + } + else + { + if (buf->rot == 0) + conv_func = evas_common_convert_func_get(0, w, h, + evas_software_x11_x_software_xcb_output_buffer_depth(xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + buf->rot); + else if (buf->rot == 270) + conv_func = evas_common_convert_func_get(0, h, w, + evas_software_x11_x_software_xcb_output_buffer_depth(xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + buf->rot); + else if (buf->rot == 90) + conv_func = evas_common_convert_func_get(0, h, w, + evas_software_x11_x_software_xcb_output_buffer_depth(xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + buf->rot); + } + if (conv_func) + { + DATA32 *src_data; + + src_data = buf->priv.back_buf->image->data + (y * buf->w) + x; + if (buf->priv.pal) + { + if (buf->rot == 0) + { + conv_func(src_data, data, + buf->w - w, + bpl / ((evas_software_x11_x_software_xcb_output_buffer_depth(xcbob) >> 3)) - w, + w, h, + x, y, + buf->priv.pal->lookup); + if (buf->priv.debug) + evas_software_x11_outbuf_software_xcb_debug_show(buf, + buf->priv.x.win, + x, y, + w, h); + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + buf->priv.x.win, + buf->priv.x.gc, + x, y); + } + else if (buf->rot == 270) + { + conv_func(src_data, data, + buf->w - w, + bpl / ((evas_software_x11_x_software_xcb_output_buffer_depth(xcbob) >> 3)) - h, + h, w, + x, y, + buf->priv.pal->lookup); + if (buf->priv.debug) + evas_software_x11_outbuf_software_xcb_debug_show(buf, + buf->priv.x.win, + x, y, + w, h); + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + buf->priv.x.win, + buf->priv.x.gc, + buf->h - y - h, x); + } + else if (buf->rot == 90) + { + conv_func(src_data, data, + buf->w - w, + bpl / ((evas_software_x11_x_software_xcb_output_buffer_depth(xcbob) >> 3)) - h, + h, w, x, y, buf->priv.pal->lookup); + if (buf->priv.debug) + evas_software_x11_outbuf_software_xcb_debug_show(buf, + buf->priv.x.win, + x, y, + w, h); + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + buf->priv.x.win, + buf->priv.x.gc, + y, buf->w - x - w); + } + } + else + { + if (buf->rot == 0) + { + conv_func(src_data, data, + buf->w - w, + bpl / ((evas_software_x11_x_software_xcb_output_buffer_depth(xcbob) >> 3)) - w, + w, h, + x, y, + NULL); + if (buf->priv.debug) + evas_software_x11_outbuf_software_xcb_debug_show(buf, + buf->priv.x.win, + x, y, + w, h); + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + buf->priv.x.win, + buf->priv.x.gc, + x, y); + } + else if (buf->rot == 270) + { + conv_func(src_data, data, + buf->w - w, + bpl / ((evas_software_x11_x_software_xcb_output_buffer_depth(xcbob) >> 3)) - h, + h, w, + x, y, + NULL); + if (buf->priv.debug) + evas_software_x11_outbuf_software_xcb_debug_show(buf, + buf->priv.x.win, + x, y, + w, h); + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + buf->priv.x.win, + buf->priv.x.gc, + buf->h - y - h, x); + } + else if (buf->rot == 90) + { + conv_func(src_data, data, + buf->w - w, + bpl / ((evas_software_x11_x_software_xcb_output_buffer_depth(xcbob) >> 3)) - h, + h, w, + x, y, + NULL); + if (buf->priv.debug) + evas_software_x11_outbuf_software_xcb_debug_show(buf, + buf->priv.x.win, + x, y, + w, h); + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + buf->priv.x.win, + buf->priv.x.gc, + y, buf->w - x - w); + } + } + } + else + { + evas_software_x11_x_software_xcb_output_buffer_free(xcbob); + return; + } + evas_software_x11_x_software_xcb_output_buffer_free(xcbob); +} + +RGBA_Image * +evas_software_x11_outbuf_software_xcb_new_region_for_update(Outbuf *buf, + int x, + int y, + int w, + int h, + int *cx, + int *cy, + int *cw, + int *ch) +{ + if (buf->priv.back_buf) + { + *cx = x; + *cy = y; + *cw = w; + *ch = h; + return buf->priv.back_buf; + } + else + { + RGBA_Image *im; + + *cx = 0; + *cy = 0; + *cw = w; + *ch = h; + im = evas_common_image_create(w, h); + if (buf->priv.x.mask.window.xid) + { + im->flags |= RGBA_IMAGE_HAS_ALPHA; + memset(im->image->data, 0, w * h * sizeof(DATA32)); + } + return im; + } + return NULL; +} + +void +evas_software_x11_outbuf_software_xcb_free_region_for_update(Outbuf *buf, + RGBA_Image *update) +{ + if (update != buf->priv.back_buf) + evas_common_image_free(update); +} + +void +evas_software_x11_outbuf_software_xcb_push_updated_region(Outbuf *buf, + RGBA_Image *update, + int x, + int y, + int w, + int h) +{ + if (buf->priv.back_buf) + { + if (update != buf->priv.back_buf) + evas_common_blit_rectangle(update, buf->priv.back_buf, 0, 0, w, h, x, y); + evas_software_x11_outbuf_software_xcb_update(buf, x, y, w, h); + } + else + { + Gfx_Func_Convert conv_func; + DATA8 *data; + Xcb_Output_Buffer *xcbob; + int bpl; + int use_shm = 1; + void *orig_data; + int direct_data = 0; + + use_shm = buf->priv.x.shm; + if (buf->perf) + { + if ((w * h) < buf->perf->min_shm_image_pixel_count) + use_shm = 0; + } + else + { + if ((w * h) < (200 * 200)) + use_shm = 0; + } + xcbob = NULL; + orig_data = update->image->data; + /* Punch thru - if our output format is our */ + /* input format - then avoid convert since we used */ + /* the image data directly */ + if ((buf->rot == 0) && + (buf->priv.mask.r == 0xff0000) && + (buf->priv.mask.g == 0x00ff00) && + (buf->priv.mask.b == 0x0000ff) && + (!use_shm) && (w == update->image->w) && (h == update->image->h)) + direct_data = 1; + if (!direct_data) + orig_data = NULL; + if (buf->rot == 0) + xcbob = evas_software_x11_x_software_xcb_output_buffer_new(buf->priv.x.conn, + buf->priv.x.depth, + w, h, + use_shm, orig_data); + else if (buf->rot == 270) + xcbob = evas_software_x11_x_software_xcb_output_buffer_new(buf->priv.x.conn, + buf->priv.x.depth, + h, w, + use_shm, orig_data); + else if (buf->rot == 90) + xcbob = evas_software_x11_x_software_xcb_output_buffer_new(buf->priv.x.conn, + buf->priv.x.depth, + h, w, + use_shm, orig_data); + if (!xcbob) + return; + data = evas_software_x11_x_software_xcb_output_buffer_data(xcbob, &bpl); + conv_func = NULL; + if (buf->priv.pal) + { + if (buf->rot == 0) + conv_func = evas_common_convert_func_get(0, w, h, + evas_software_x11_x_software_xcb_output_buffer_depth (xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + buf->priv.pal->colors, + buf->rot); + else if (buf->rot == 270) + conv_func = evas_common_convert_func_get(0, h, w, + evas_software_x11_x_software_xcb_output_buffer_depth (xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + buf->priv.pal->colors, + buf->rot); + else if (buf->rot == 90) + conv_func = evas_common_convert_func_get(0, h, w, + evas_software_x11_x_software_xcb_output_buffer_depth (xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + buf->priv.pal->colors, + buf->rot); + } + else + { + if (buf->rot == 0) + conv_func = evas_common_convert_func_get(0, w, h, + evas_software_x11_x_software_xcb_output_buffer_depth (xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + buf->rot); + else if (buf->rot == 270) + conv_func = evas_common_convert_func_get(0, h, w, + evas_software_x11_x_software_xcb_output_buffer_depth (xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + buf->rot); + else if (buf->rot == 90) + conv_func = evas_common_convert_func_get(0, h, w, + evas_software_x11_x_software_xcb_output_buffer_depth (xcbob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + buf->rot); + } + if (conv_func) + { + DATA32 *src_data; + Xcb_Output_Buffer *mxcbob = NULL; + + if (buf->priv.x.mask.window.xid) + { + if (buf->rot == 0) + mxcbob = evas_software_x11_x_software_xcb_output_buffer_new(buf->priv.x.conn, + 1, + w, h, + 0, NULL); + else if (buf->rot == 270) + mxcbob = evas_software_x11_x_software_xcb_output_buffer_new(buf->priv.x.conn, + 1, + h, w, + 0, NULL); + else if (buf->rot == 90) + mxcbob = evas_software_x11_x_software_xcb_output_buffer_new(buf->priv.x.conn, + 1, + h, w, + 0, NULL); + } + src_data = update->image->data; + if (buf->priv.pal) + { + if (buf->rot == 0) + { + if (!direct_data) + conv_func(src_data, data, + 0, + bpl / ((evas_software_x11_x_software_xcb_output_buffer_depth(xcbob) >> 3)) - w, + w, h, + x, y, + buf->priv.pal->lookup); + if (buf->priv.debug) + evas_software_x11_outbuf_software_xcb_debug_show(buf, + buf->priv.x.win, + x, y, + w, h); + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + buf->priv.x.win, + buf->priv.x.gc, + x, y); + if (mxcbob) + { + int yy; + + for (yy = 0; yy < h; yy++) + evas_software_x11_x_software_xcb_write_mask_line(mxcbob, + src_data + (yy * w), w, yy); + evas_software_x11_x_software_xcb_output_buffer_paste(mxcbob, + buf->priv.x.mask, + buf->priv.x.gcm, + x, y); + } + } + else if (buf->rot == 270) + { + if (!direct_data) + conv_func(src_data, data, + 0, + bpl / ((evas_software_x11_x_software_xcb_output_buffer_depth(xcbob) >> 3)) - h, + h, w, + x, y, + buf->priv.pal->lookup); + if (buf->priv.debug) + evas_software_x11_outbuf_software_xcb_debug_show(buf, + buf->priv.x.win, + x, y, + w, h); + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + buf->priv.x.win, + buf->priv.x.gc, + buf->h - y - h, x); + if (mxcbob) + { + evas_software_x11_x_software_xcb_output_buffer_paste(mxcbob, + buf->priv.x.mask, + buf->priv.x.gcm, + buf->h - y - h, x); + } + } + else if (buf->rot == 90) + { + if (!direct_data) + conv_func(src_data, data, + 0, + bpl / ((evas_software_x11_x_software_xcb_output_buffer_depth(xcbob) >> 3)) - h, + h, w, + x, y, + buf->priv.pal->lookup); + if (buf->priv.debug) + evas_software_x11_outbuf_software_xcb_debug_show(buf, + buf->priv.x.win, + x, y, + w, h); + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + buf->priv.x.win, + buf->priv.x.gc, + y, buf->w - x - w); + if (mxcbob) + { + evas_software_x11_x_software_xcb_output_buffer_paste(mxcbob, + buf->priv.x.mask, + buf->priv.x.gcm, + y, buf->w - x - w); + } + } + } + else + { + if (buf->rot == 0) + { + if (!direct_data) + conv_func(src_data, data, + 0, + bpl / ((evas_software_x11_x_software_xcb_output_buffer_depth(xcbob) >> 3)) - w, + w, h, + x, y, + NULL); + if (buf->priv.debug) + evas_software_x11_outbuf_software_xcb_debug_show(buf, + buf->priv.x.win, + x, y, + w, h); + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + buf->priv.x.win, + buf->priv.x.gc, + x, y); + if (mxcbob) + { + int yy; + + for (yy = 0; yy < h; yy++) + evas_software_x11_x_software_xcb_write_mask_line(mxcbob, + src_data + (yy * w), + w, yy); + evas_software_x11_x_software_xcb_output_buffer_paste(mxcbob, + buf->priv.x.mask, + buf->priv.x.gcm, + x, y); + } + } + else if (buf->rot == 270) + { + if (!direct_data) + conv_func(src_data, data, + 0, + bpl / ((evas_software_x11_x_software_xcb_output_buffer_depth(xcbob) >> 3)) - h, + h, w, + x, y, + NULL); + if (buf->priv.debug) + evas_software_x11_outbuf_software_xcb_debug_show(buf, + buf->priv.x.win, + x, y, + w, h); + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + buf->priv.x.win, + buf->priv.x.gc, + buf->h - y - h, x); + if (mxcbob) + { + evas_software_x11_x_software_xcb_output_buffer_paste(mxcbob, + buf->priv.x.mask, + buf->priv.x.gcm, + buf->h - y - h, x); + } + } + else if (buf->rot == 90) + { + if (!direct_data) + conv_func(src_data, data, + 0, + bpl / ((evas_software_x11_x_software_xcb_output_buffer_depth(xcbob) >> 3)) - h, + h, w, + x, y, + NULL); + if (buf->priv.debug) + evas_software_x11_outbuf_software_xcb_debug_show(buf, + buf->priv.x.win, + x, y, + w, h); + evas_software_x11_x_software_xcb_output_buffer_paste(xcbob, + buf->priv.x.win, + buf->priv.x.gc, + y, buf->w - x - w); + if (mxcbob) + { + evas_software_x11_x_software_xcb_output_buffer_paste(mxcbob, + buf->priv.x.mask, + buf->priv.x.gcm, + y, buf->w - x - w); + } + } + } + if (mxcbob) + evas_software_x11_x_software_xcb_output_buffer_free(mxcbob); + } + else + { + evas_software_x11_x_software_xcb_output_buffer_free(xcbob); + return; + } + evas_software_x11_x_software_xcb_output_buffer_free(xcbob); + } +} + +void +evas_software_x11_outbuf_software_xcb_reconfigure(Outbuf *buf, + int w, + int h, + int rot, + Outbuf_Depth depth) +{ + if ((w == buf->w) && (h == buf->h) && + (rot == buf->rot) && (depth == buf->depth)) + return; + buf->w = w; + buf->h = h; + buf->rot = rot; + if (buf->priv.back_buf) + { + evas_common_image_free(buf->priv.back_buf); + buf->priv.back_buf = NULL; + } + if (buf->priv.x.conn) + { + if (buf->priv.x.depth < 24) + buf->priv.back_buf = evas_common_image_create(buf->w, buf->h); + } +} + +int +evas_software_x11_outbuf_software_xcb_get_width(Outbuf * buf) +{ + return buf->w; +} + +int +evas_software_x11_outbuf_software_xcb_get_height(Outbuf * buf) +{ + return buf->h; +} + +Outbuf_Depth +evas_software_x11_outbuf_software_xcb_get_depth(Outbuf * buf) +{ + return buf->depth; +} + +int +evas_software_x11_outbuf_software_xcb_get_rot(Outbuf * buf) +{ + return buf->rot; +} + +int +evas_software_x11_outbuf_software_xcb_get_have_backbuf(Outbuf * buf) +{ + if (buf->priv.back_buf) + return 1; + return 0; +} + +void +evas_software_x11_outbuf_software_xcb_set_have_backbuf(Outbuf *buf, + int have_backbuf) +{ + if (buf->priv.back_buf) + { + if (have_backbuf) + return; + evas_common_image_free(buf->priv.back_buf); + buf->priv.back_buf = NULL; + } + else + { + if (!have_backbuf) + return; + if (buf->priv.x.conn) + { + if (buf->priv.x.depth < 24) + buf->priv.back_buf = evas_common_image_create(buf->w, buf->h); + } + } +} + +void +evas_software_x11_outbuf_software_xcb_drawable_set(Outbuf *buf, + XCBDRAWABLE draw) +{ + CARD32 gcv; + + if (buf->priv.x.win.window.xid == draw.window.xid) + return; + + if (buf->priv.x.gc.xid) + { + XCBFreeGC(buf->priv.x.conn, buf->priv.x.gc); + buf->priv.x.gc.xid = 0; + } + + buf->priv.x.win.window = draw.window; + buf->priv.x.gc = XCBGCONTEXTNew(buf->priv.x.conn); + XCBCreateGC(buf->priv.x.conn, buf->priv.x.gc, buf->priv.x.win, 0, &gcv); +} + +void +evas_software_x11_outbuf_software_xcb_mask_set(Outbuf *buf, + XCBDRAWABLE mask) +{ + CARD32 gcv; + + if (buf->priv.x.mask.pixmap.xid == mask.pixmap.xid) + return; + + if (buf->priv.x.gcm.xid) + { + XCBFreeGC(buf->priv.x.conn, buf->priv.x.gcm); + buf->priv.x.gcm.xid = 0; + } + + buf->priv.x.mask.pixmap = mask.pixmap; + if (buf->priv.x.mask.pixmap.xid) { + buf->priv.x.gcm = XCBGCONTEXTNew(buf->priv.x.conn); + XCBCreateGC(buf->priv.x.conn, buf->priv.x.gcm, buf->priv.x.mask, 0, &gcv); + } +} + +void +evas_software_x11_outbuf_software_xcb_debug_set(Outbuf *buf, + int debug) +{ + buf->priv.debug = debug; +} + +void +evas_software_x11_outbuf_software_xcb_debug_show(Outbuf *buf, + XCBDRAWABLE draw, + int x, + int y, + int w, + int h) +{ + int i; + XCBSCREEN *screen; + + { + XCBGetGeometryRep *geom; + XCBDRAWABLE root; + XCBSCREENIter i; + int cur; + + geom = XCBGetGeometryReply (buf->priv.x.conn, XCBGetGeometry (buf->priv.x.conn, draw), 0); + root.window = geom->root; + free (geom); + geom = XCBGetGeometryReply (buf->priv.x.conn, XCBGetGeometry (buf->priv.x.conn, root), 0); + + i = XCBConnSetupSuccessRepRootsIter(XCBGetSetup(buf->priv.x.conn)); + for (cur = 0; cur < i.rem; XCBSCREENNext(&i), ++cur) + if (i.data->root.xid == geom->root.xid) + { + screen = i.data; + break; + } + free (geom); + } + for (i = 0; i < 10; i++) + { + XCBImage *image; + XCBRECTANGLE rect = { x, y, w, h}; + CARD32 mask; + CARD32 value[2]; + + mask = GCForeground | GCGraphicsExposures; + value[0] = screen->black_pixel; + value[1] = 0; /* no graphics exposures */ + XCBChangeGC(buf->priv.x.conn, buf->priv.x.gc, mask, value); + XCBPolyFillRectangle (buf->priv.x.conn, draw, buf->priv.x.gc, 1, &rect); + XCBSync(buf->priv.x.conn, 0); + image = XCBImageGet(buf->priv.x.conn, draw, x, y, w, h, 0xffffffff, ZPixmap); + if (image) + XCBImageDestroy(image); + XCBSync(buf->priv.x.conn, 0); + mask = GCForeground | GCGraphicsExposures; + value[0] = screen->white_pixel; + value[1] = 0; /* no graphics exposures */ + XCBChangeGC(buf->priv.x.conn, buf->priv.x.gc, mask, value); + XCBPolyFillRectangle (buf->priv.x.conn, draw, buf->priv.x.gc, 1, &rect); + XCBSync(buf->priv.x.conn, 0); + image = XCBImageGet(buf->priv.x.conn, draw, x, y, w, h, 0xffffffff, ZPixmap); + if (image) + XCBImageDestroy(image); + XCBSync(buf->priv.x.conn, 0); + } +} diff --git a/legacy/evas/src/lib/engines/software_xcb/evas_xcb_buffer.c b/legacy/evas/src/lib/engines/software_xcb/evas_xcb_buffer.c new file mode 100644 index 0000000000..2e250837b2 --- /dev/null +++ b/legacy/evas/src/lib/engines/software_xcb/evas_xcb_buffer.c @@ -0,0 +1,231 @@ +#include "evas_common.h" +#include "evas_engine.h" + +#include +#include +#include +#include + +struct _Xcb_Output_Buffer +{ + XCBConnection *connection; + XCBImage *image; + XCBShmSegmentInfo *shm_info; + void *data; +}; + +static int _xcb_err = 0; + +void +evas_software_x11_x_software_xcb_write_mask_line(Xcb_Output_Buffer *xcbob, + DATA32 *src, + int w, + int y) +{ + int x; + + for (x = 0; x < w; x++) + { + XCBImagePutPixel(xcbob->image, x, y, A_VAL(&(src[x])) >> 7); + } +} + +int +evas_software_x11_x_software_xcb_can_do_shm(XCBConnection *c) +{ + XCBGetGeometryRep *geom; + XCBDRAWABLE drawable; + int depth; + + drawable.window = XCBConnSetupSuccessRepRootsIter (XCBGetSetup(c)).data->root; + geom = XCBGetGeometryReply (c, XCBGetGeometry(c, drawable), 0); + if(!geom) + return 0; + + depth = geom->depth; + free (geom); + + if (XCBShmInit(c)) + { + Xcb_Output_Buffer *xcbob; + + xcbob = evas_software_x11_x_software_xcb_output_buffer_new(c, + depth, + 16, + 16, + 2, + NULL); + if (!xcbob) + return 0; + evas_software_x11_x_software_xcb_output_buffer_free(xcbob); + return 1; + } + return 0; +} + +/* + * FIXME: no error mechanism + */ + +/* static void */ +/* x_software_x11_output_tmp_x11_err(XCBConnection *c, XErrorEvent * ev) */ +/* { */ +/* _xcb_err = 1; */ +/* return; */ +/* d = NULL; */ +/* ev = NULL; */ +/* } */ + +Xcb_Output_Buffer * +evas_software_x11_x_software_xcb_output_buffer_new(XCBConnection *c, + int depth, + int w, + int h, + int try_shm, + void *data) +{ + Xcb_Output_Buffer *xcbob; + + xcbob = calloc(1, sizeof(Xcb_Output_Buffer)); + if (!xcbob) return NULL; + + xcbob->connection = c; + xcbob->image = NULL; + xcbob->shm_info = NULL; + + if (try_shm > 0) + { + xcbob->shm_info = malloc(sizeof(XCBShmSegmentInfo)); + if (xcbob->shm_info) + { + xcbob->shm_info->shmseg = XCBShmSEGNew(c); + xcbob->image = XCBImageSHMCreate(c, depth, ZPixmap, NULL, w, h); + if (xcbob->image) + { + xcbob->shm_info->shmid = shmget(IPC_PRIVATE, + xcbob->image->bytes_per_line * + xcbob->image->height, + IPC_CREAT | 0777); + if (xcbob->shm_info->shmid >= 0) + { + xcbob->shm_info->shmaddr = xcbob->image->data = + shmat(xcbob->shm_info->shmid, 0, 0); + if (xcbob->shm_info->shmaddr != NULL) + { + /* + * FIXME: no error mechanism + */ + +/* XErrorHandler ph; */ + + XCBSync(c, 0); + _xcb_err = 0; +/* ph = XSetErrorHandler((XErrorHandler) */ +/* x_software_x11_output_tmp_x_err); */ + XCBShmAttach(c, + xcbob->shm_info->shmseg, + xcbob->shm_info->shmid, 0); + XCBSync(c, 0); +/* XSetErrorHandler((XErrorHandler)ph); */ + if (!_xcb_err) + { + return xcbob; + } + } + shmdt(xcbob->shm_info->shmaddr); + shmctl(xcbob->shm_info->shmid, IPC_RMID, 0); + } + if (xcbob->image) XCBImageSHMDestroy(xcbob->image); + xcbob->image = NULL; + } + if (xcbob->shm_info) free(xcbob->shm_info); + xcbob->shm_info = NULL; + } + } + + if (try_shm > 1) return NULL; + + xcbob->image = XCBImageCreate(c, depth, ZPixmap, 0, data, w, h, 32, 0); + if (!xcbob->image) + { + free(xcbob); + return NULL; + } + + xcbob->data = data; + + if (!xcbob->image->data) + { + xcbob->image->data = malloc(xcbob->image->bytes_per_line * xcbob->image->height); + if (!xcbob->image->data) + { + XCBImageDestroy(xcbob->image); + free(xcbob); + return NULL; + } + } + return xcbob; +} + +void +evas_software_x11_x_software_xcb_output_buffer_free(Xcb_Output_Buffer *xcbob) +{ + if (xcbob->shm_info) + { + XCBSync(xcbob->connection, 0); + XCBShmDetach(xcbob->connection, xcbob->shm_info->shmseg); + XCBImageSHMDestroy(xcbob->image); + shmdt(xcbob->shm_info->shmaddr); + shmctl(xcbob->shm_info->shmid, IPC_RMID, 0); + free(xcbob->shm_info); + } + else + { + if (xcbob->data) xcbob->image->data = NULL; + XCBImageDestroy(xcbob->image); + } + free(xcbob); +} + +void +evas_software_x11_x_software_xcb_output_buffer_paste(Xcb_Output_Buffer *xcbob, + XCBDRAWABLE d, + XCBGCONTEXT gc, + int x, + int y) +{ + if (xcbob->shm_info) + { + XCBImageSHMPut(xcbob->connection, d, gc, + xcbob->image, *xcbob->shm_info, + 0, 0, + x, y, + xcbob->image->width, xcbob->image->height, + 0); + XCBSync(xcbob->connection, 0); + } + else + { + XCBImagePut(xcbob->connection, d, gc, xcbob->image, 0, 0, x, y, xcbob->image->width, xcbob->image->height); + } +} + +DATA8 * +evas_software_x11_x_software_xcb_output_buffer_data(Xcb_Output_Buffer *xcbob, + int *bytes_per_line_ret) +{ + if (bytes_per_line_ret) *bytes_per_line_ret = xcbob->image->bytes_per_line; + return xcbob->image->data; +} + +int +evas_software_x11_x_software_xcb_output_buffer_depth(Xcb_Output_Buffer *xcbob) +{ + return xcbob->image->bits_per_pixel; +} + +int +evas_software_x11_x_software_xcb_output_buffer_byte_order(Xcb_Output_Buffer *xcbob) +{ + return xcbob->image->image_byte_order; +} diff --git a/legacy/evas/src/lib/engines/software_xcb/evas_xcb_color.c b/legacy/evas/src/lib/engines/software_xcb/evas_xcb_color.c new file mode 100644 index 0000000000..40ad314d19 --- /dev/null +++ b/legacy/evas/src/lib/engines/software_xcb/evas_xcb_color.c @@ -0,0 +1,359 @@ +#include "evas_common.h" +#include "evas_engine.h" + +#include + +typedef struct _Convert_Pal_Priv Convert_Pal_Priv; + +struct _Convert_Pal_Priv +{ + XCBConnection *conn; + XCBCOLORMAP cmap; + XCBVISUALTYPE *vis; +}; + +typedef DATA8 * (*Xcb_Func_Alloc_Colors) (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); + +static Xcb_Func_Alloc_Colors x_software_xcb_color_alloc[PAL_MODE_LAST + 1]; +static int x_software_xcb_color_count[PAL_MODE_LAST + 1]; +static Evas_List *palettes = NULL; + +static DATA8 * x_software_xcb_color_alloc_rgb(int nr, int ng, int nb, XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); +static DATA8 * x_software_xcb_color_alloc_gray(int ng, XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); + +static DATA8 * x_software_xcb_color_alloc_rgb_332 (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); +static DATA8 * x_software_xcb_color_alloc_rgb_666 (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); +static DATA8 * x_software_xcb_color_alloc_rgb_232 (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); +static DATA8 * x_software_xcb_color_alloc_rgb_222 (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); +static DATA8 * x_software_xcb_color_alloc_rgb_221 (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); +static DATA8 * x_software_xcb_color_alloc_rgb_121 (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); +static DATA8 * x_software_xcb_color_alloc_rgb_111 (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); +static DATA8 * x_software_xcb_color_alloc_gray_256 (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); +static DATA8 * x_software_xcb_color_alloc_gray_64 (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); +static DATA8 * x_software_xcb_color_alloc_gray_16 (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); +static DATA8 * x_software_xcb_color_alloc_gray_4 (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); +static DATA8 * x_software_xcb_color_alloc_mono (XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v); + +static DATA8 * +x_software_xcb_color_alloc_rgb(int nr, int ng, int nb, XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + int r, g, b, i; + DATA8 *color_lut; + int sig_mask = 0; + + for (i = 0; i < v->bits_per_rgb_value; i++) sig_mask |= (0x1 << i); + sig_mask <<= (16 - v->bits_per_rgb_value); + i = 0; + color_lut = malloc((nr) * (ng) * (nb)); + if (!color_lut) return NULL; + for (r = 0; r < (nr); r++) + { + for (g = 0; g < (ng); g++) + { + for (b = 0; b < (nb); b++) + { + XCBCOLORITEM xcl; + XCBCOLORITEM xcl_in; + int val; + XCBAllocColorRep *rep; + + val = (int)((((double)r) / ((nr) - 1)) * 65535); + xcl.red = (unsigned short)(val); + val = (int)((((double)g) / ((ng) - 1)) * 65535); + xcl.green = (unsigned short)(val); + val = (int)((((double)b) / ((nb) - 1)) * 65535); + xcl.blue = (unsigned short)(val); + xcl_in = xcl; + rep = XCBAllocColorReply(conn, + XCBAllocColor(conn, cmap, + xcl.red, xcl.green, xcl.blue), + 0); + /* TODO: XAllocColor tries to approach the color */ + /* in case the allocation fails */ + /* XCB does not that (i think). It should be done */ + /* So if rep == NULL, the other following tests */ + /* should be always satisfied */ + if ((!rep) || + ((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) || + ((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) || + ((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask))) + { + unsigned long pixels[256]; + int j; + + if (i > 0) + { + for(j = 0; j < i; j++) + pixels[j] = (unsigned long)color_lut[j]; + XCBFreeColors(conn, cmap, 0, i, pixels); + } + free(color_lut); + return NULL; + } + color_lut[i] = rep->pixel; + i++; + free(rep); + } + } + } + return color_lut; +} + +static DATA8 * +x_software_xcb_color_alloc_gray(int ng, XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + int g, i; + DATA8 *color_lut; + int sig_mask = 0; + + for (i = 0; i < v->bits_per_rgb_value; i++) sig_mask |= (0x1 << i); + sig_mask <<= (16 - v->bits_per_rgb_value); + i = 0; + color_lut = malloc(ng); + if (!color_lut) return NULL; + for (g = 0; g < (ng); g++) + { + XCBCOLORITEM xcl; + XCBCOLORITEM xcl_in; + int val; + XCBAllocColorRep *rep; + + val = (int)((((double)g) / ((ng) - 1)) * 65535); + xcl.red = (unsigned short)(val); + xcl.green = (unsigned short)(val); + xcl.blue = (unsigned short)(val); + xcl_in = xcl; + rep = XCBAllocColorReply(conn, + XCBAllocColor(conn, cmap, + xcl.red, xcl.green, xcl.blue), + 0); + /* TODO: XAllocColor tries to approach the color */ + /* in case the allocation fails */ + /* XCB does not that (i think). It should be done */ + /* So if rep == NULL, the other following tests */ + /* should be always satisfied */ + if ((!rep) || + ((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) || + ((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) || + ((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask))) + { + unsigned long pixels[256]; + int j; + + if (i > 0) + { + for(j = 0; j < i; j++) + pixels[j] = (unsigned long) color_lut[j]; + XCBFreeColors(conn, cmap, 0, i, pixels); + } + free(color_lut); + return NULL; + } + color_lut[i] = xcl.pixel; + i++; + free(rep); + } + return color_lut; +} + +static DATA8 * +x_software_xcb_color_alloc_rgb_332(XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + return x_software_xcb_color_alloc_rgb(8, 8, 4, conn, cmap, v); +} + +static DATA8 * +x_software_xcb_color_alloc_rgb_666(XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + return x_software_xcb_color_alloc_rgb(6, 6, 6, conn, cmap, v); +} + +static DATA8 * +x_software_xcb_color_alloc_rgb_232(XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + return x_software_xcb_color_alloc_rgb(4, 8, 4, conn, cmap, v); +} + +static DATA8 * +x_software_xcb_color_alloc_rgb_222(XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + return x_software_xcb_color_alloc_rgb(4, 4, 4, conn, cmap, v); +} + +static DATA8 * +x_software_xcb_color_alloc_rgb_221(XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + return x_software_xcb_color_alloc_rgb(4, 4, 2, conn, cmap, v); +} + +static DATA8 * +x_software_xcb_color_alloc_rgb_121(XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + return x_software_xcb_color_alloc_rgb(2, 4, 2, conn, cmap, v); +} + +static DATA8 * +x_software_xcb_color_alloc_rgb_111(XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + return x_software_xcb_color_alloc_rgb(2, 2, 2, conn, cmap, v); +} + +static DATA8 * +x_software_xcb_color_alloc_gray_256(XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + return x_software_xcb_color_alloc_gray(256, conn, cmap, v); +} + +static DATA8 * +x_software_xcb_color_alloc_gray_64(XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + return x_software_xcb_color_alloc_gray(64, conn, cmap, v); +} + +static DATA8 * +x_software_xcb_color_alloc_gray_16(XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + return x_software_xcb_color_alloc_gray(32, conn, cmap, v); +} + +static DATA8 * +x_software_xcb_color_alloc_gray_4(XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + return x_software_xcb_color_alloc_gray(16, conn, cmap, v); +} + +static DATA8 * +x_software_xcb_color_alloc_mono(XCBConnection *conn, XCBCOLORMAP cmap, XCBVISUALTYPE *v) +{ + return x_software_xcb_color_alloc_gray(2, conn, cmap, v); +} + +void +x_software_xcb_color_init(void) +{ + static int initialised = 0; + + if (initialised) return; + x_software_xcb_color_alloc[PAL_MODE_NONE] = NULL; + x_software_xcb_color_count[PAL_MODE_NONE] = 0; + + x_software_xcb_color_alloc[PAL_MODE_MONO] = x_software_xcb_color_alloc_mono; + x_software_xcb_color_count[PAL_MODE_MONO] = 2; + + x_software_xcb_color_alloc[PAL_MODE_GRAY4] = x_software_xcb_color_alloc_gray_4; + x_software_xcb_color_count[PAL_MODE_GRAY4] = 4; + + x_software_xcb_color_alloc[PAL_MODE_GRAY16] = x_software_xcb_color_alloc_gray_16; + x_software_xcb_color_count[PAL_MODE_GRAY16] = 16; + + x_software_xcb_color_alloc[PAL_MODE_GRAY64] = x_software_xcb_color_alloc_gray_64; + x_software_xcb_color_count[PAL_MODE_GRAY64] = 64; + + x_software_xcb_color_alloc[PAL_MODE_GRAY256] = x_software_xcb_color_alloc_gray_256; + x_software_xcb_color_count[PAL_MODE_GRAY256] = 256; + + x_software_xcb_color_alloc[PAL_MODE_RGB111] = x_software_xcb_color_alloc_rgb_111; + x_software_xcb_color_count[PAL_MODE_RGB111] = 2 * 2 * 2; + + x_software_xcb_color_alloc[PAL_MODE_RGB121] = x_software_xcb_color_alloc_rgb_121; + x_software_xcb_color_count[PAL_MODE_RGB121] = 2 * 4 * 2; + + x_software_xcb_color_alloc[PAL_MODE_RGB221] = x_software_xcb_color_alloc_rgb_221; + x_software_xcb_color_count[PAL_MODE_RGB221] = 4 * 4 * 2; + + x_software_xcb_color_alloc[PAL_MODE_RGB222] = x_software_xcb_color_alloc_rgb_222; + x_software_xcb_color_count[PAL_MODE_RGB222] = 4 * 4 * 4; + + x_software_xcb_color_alloc[PAL_MODE_RGB232] = x_software_xcb_color_alloc_rgb_232; + x_software_xcb_color_count[PAL_MODE_RGB232] = 4 * 8 * 4; + + x_software_xcb_color_alloc[PAL_MODE_RGB666] = x_software_xcb_color_alloc_rgb_666; + x_software_xcb_color_count[PAL_MODE_RGB666] = 6 * 6 * 6; + + x_software_xcb_color_alloc[PAL_MODE_RGB332] = x_software_xcb_color_alloc_rgb_332; + x_software_xcb_color_count[PAL_MODE_RGB332] = 8 * 8 * 4; + + x_software_xcb_color_alloc[PAL_MODE_LAST] = NULL; + x_software_xcb_color_count[PAL_MODE_LAST] = 0; + initialised = 1; +} + +Convert_Pal * +evas_software_x11_x_software_xcb_color_allocate(XCBConnection *conn, + XCBCOLORMAP cmap, + XCBVISUALTYPE *vis, + Convert_Pal_Mode colors) +{ + Convert_Pal_Priv *palpriv; + Convert_Pal *pal; + Convert_Pal_Mode c; + Evas_List *l; + + for (l = palettes; l; l = l->next) + { + pal = l->data; + palpriv = pal->data; + if ((conn == palpriv->conn) && + (vis == palpriv->vis) && + (cmap.xid == palpriv->cmap.xid)) + { + pal->references++; + return pal; + } + } + pal = calloc(1, sizeof(struct _Convert_Pal)); + if (!pal) return NULL; + for (c = colors; c > PAL_MODE_NONE; c--) + { + if (x_software_xcb_color_alloc[c]) + { + pal->lookup = (x_software_xcb_color_alloc[c])(conn, cmap, vis); + if (pal->lookup) break; + } + } + pal->references = 1; + pal->colors = c; + pal->count = x_software_xcb_color_count[c]; + palpriv = calloc(1, sizeof(Convert_Pal_Priv)); + pal->data = palpriv; + if (!palpriv) + { + if (pal->lookup) free(pal->lookup); + free(pal); + return NULL; + } + palpriv->conn = conn; + palpriv->vis = vis; + palpriv->cmap = cmap; + if (pal->colors == PAL_MODE_NONE) + { + if (pal->lookup) free(pal->lookup); + free(pal); + return NULL; + } + palettes = evas_list_append(palettes, pal); + return pal; +} + +void +evas_software_x11_x_software_xcb_color_deallocate(XCBConnection *conn, + XCBCOLORMAP cmap, + XCBVISUALTYPE *vis, + Convert_Pal *pal) +{ + unsigned long pixels[256]; + int j; + + pal->references--; + if (pal->references > 0) return; + if (pal->lookup) + { + for(j = 0; j < pal->count; j++) + pixels[j] = (unsigned long) pal->lookup[j]; + XCBFreeColors(conn, cmap, 0, pal->count, pixels); + free(pal->lookup); + } + free(pal->data); + palettes = evas_list_remove(palettes, pal); + free(pal); +} diff --git a/legacy/evas/src/lib/engines/software_xcb/evas_xcb_main.c b/legacy/evas/src/lib/engines/software_xcb/evas_xcb_main.c new file mode 100644 index 0000000000..3ecbd16388 --- /dev/null +++ b/legacy/evas/src/lib/engines/software_xcb/evas_xcb_main.c @@ -0,0 +1,9 @@ +#include "evas_common.h" +#include "evas_engine.h" + +#include + +void +evas_software_x11_x_software_xcb_init(void) +{ +} diff --git a/legacy/evas/src/lib/include/Makefile.am b/legacy/evas/src/lib/include/Makefile.am index 43219e6972..0278126a6d 100644 --- a/legacy/evas/src/lib/include/Makefile.am +++ b/legacy/evas/src/lib/include/Makefile.am @@ -3,6 +3,7 @@ MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = \ evas_common.h \ evas_engine_api_software_x11.h \ +evas_engine_api_software_xcb.h \ evas_engine_api_directfb.h \ evas_engine_api_fb.h \ evas_engine_api_buffer.h \ diff --git a/legacy/evas/src/lib/include/evas_engine_api_software_xcb.h b/legacy/evas/src/lib/include/evas_engine_api_software_xcb.h new file mode 100644 index 0000000000..b27447a30d --- /dev/null +++ b/legacy/evas/src/lib/include/evas_engine_api_software_xcb.h @@ -0,0 +1,7 @@ +#ifndef EVAS_ENGINE_SOFTWARE_XCB_H +#define EVAS_ENGINE_SOFTWARE_XCB_H +#include + +extern Evas_Func evas_engine_software_xcb_func; + +#endif /* EVAS_ENGINE_SOFTWARE_XCB_H */ diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index 6a9d4382e0..7ff60952f6 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -17,6 +17,7 @@ #define RENDER_METHOD_SOFTWARE_QTOPIA 0x00000006 #define RENDER_METHOD_GL_X11 0x00000007 #define RENDER_METHOD_CAIRO_X11 0x00000008 +#define RENDER_METHOD_SOFTWARE_XCB 0x00000009 #define RENDER_METHOD_INVALID 0x00000000