From ed44634dfa5ebab986402f4562c0000332046f94 Mon Sep 17 00:00:00 2001 From: devilhorns Date: Tue, 26 Jul 2011 05:54:01 +0000 Subject: [PATCH] Ecore_X: Add start of XResource handling for xcb backend (NB: Nowhere near finished yet). Add working OpenGL for XCB engine. NB: wrt Opengl...Raster, this is the env var/dlsym version you requested this morning ;) NB: Basically what happens is, if you know you do not ever want/use opengl, you can export ECORE_X_NO_XLIB env variable, and ecore_x will use pure xcb to establish it's X connection. However, if you do use OpenGL and this env var is not exported, then ecore_x(cb) will use XOpenDisplay to init the connection. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/ecore@61724 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- configure.ac | 31 +++++++++- src/lib/ecore_x/xcb/Makefile.am | 6 +- src/lib/ecore_x/xcb/ecore_xcb.c | 98 ++++++++++++++++++++++++++++---- src/lib/ecore_x/xcb/ecore_xcb_cursor.c | 49 ++++++++++++++++ src/lib/ecore_x/xcb/ecore_xcb_private.h | 3 + src/lib/ecore_x/xcb/ecore_xcb_render.c | 19 +------ src/lib/ecore_x/xcb/ecore_xcb_resource.c | 87 ++++++++++++++++++++++++++++ 7 files changed, 260 insertions(+), 33 deletions(-) create mode 100644 src/lib/ecore_x/xcb/ecore_xcb_resource.c diff --git a/configure.ac b/configure.ac index fd8a328..e8eefce 100644 --- a/configure.ac +++ b/configure.ac @@ -241,6 +241,30 @@ requirements_ecore_win32="" requirements_ecore_wince="" requirements_ecore_imf_xim="" +AC_CHECK_DECL([MAXHOSTNAMELEN],[FOUND_MAXHOSTNAMELEN=yes]) + +if test x$FOUND_MAXHOSTNAMELEN != xyes ; then + AC_MSG_CHECKING([for header that defines MAXHOSTNAMELEN]) + + FOUND_MAXHOSTNAMELEN='not found' + + AC_COMPILE_IFELSE( + AC_LANG_PROGRAM([#include ], + [int h = MAXHOSTNAMELEN;]), + [FOUND_MAXHOSTNAMELEN='sys/param.h' + AC_DEFINE(NEED_SYS_PARAM_H,1, + [Define to 1 if you need to define MAXHOSTNAMELEN])]) + + AC_COMPILE_IFELSE( + AC_LANG_PROGRAM([#include ], + [int h = MAXHOSTNAMELEN;]), + [FOUND_MAXHOSTNAMELEN='netdb.h' + AC_DEFINE(NEED_NETDB_H,1, + [Define to 1 if you need to define MAXHOSTNAMELEN])]) + + AC_MSG_RESULT([$FOUND_MAXHOSTNAMELEN]) +fi + ### Additional options to configure want_glib_integration_always=no @@ -759,6 +783,7 @@ if test "x$want_ecore_x_xcb" = "xyes" ; then fi fi +## x11-xcb PKG_CHECK_MODULES(XCB, xcb xcb-shm xcb-icccm xcb-image xcb-keysyms pixman-1, [ have_ecore_x_xcb="yes" requirements_ecore_x="xcb xcb-shm xcb-icccm xcb-image xcb-keysyms pixman-1 ${requirements_ecore_x}" ], @@ -1451,19 +1476,19 @@ fi ECORE_EVAS_CHECK_MODULE([opengl-x11], [${want_ecore_evas_opengl_x11}], [OpenGL Xlib], - [${have_ecore_x_xlib}]) + [${have_ecore_x}]) have_ecore_evas_opengl_xlib="no" have_ecore_evas_opengl_xcb="no" if test "x${have_ecore_evas_opengl_x11}" = "xyes" -o "x${have_ecore_evas_opengl_x11}" = "xstatic" ; then have_ecore_evas_opengl_xlib=`${PKG_CONFIG} --variable=Xlib evas-opengl-x11` - if test "x${have_ecore_evas_opengl_xlib}" = "xyes" -a "x${have_ecore_x}" = "xyes" ; then + if test "x${have_ecore_evas_opengl_xlib}" = "xyes" ; then AC_DEFINE(BUILD_ECORE_EVAS_OPENGL_XLIB, 1, [OpenGL Xlib rendering backend]) fi # opengl does not work with xcb (yet) have_ecore_evas_opengl_xcb=`${PKG_CONFIG} --variable=XCB evas-opengl-x11` - if test "x${have_ecore_evas_opengl_xcb}" = "xyes" -a "x${have_ecore_x}" = "xyes" ; then + if test "x${have_ecore_evas_opengl_xcb}" = "xyes" -a "x${have_ecore_x_xcb}" = "xyes" ; then PKG_CHECK_MODULES(XCB_X11, x11-xcb, [ have_ecore_x_opengl_xcb="yes" requirements_ecore_x="x11-xcb ${requirements_ecore_x}" diff --git a/src/lib/ecore_x/xcb/Makefile.am b/src/lib/ecore_x/xcb/Makefile.am index 7e48f36..bcdd6b2 100644 --- a/src/lib/ecore_x/xcb/Makefile.am +++ b/src/lib/ecore_x/xcb/Makefile.am @@ -66,7 +66,8 @@ libecore_x_xcb_la_SOURCES = \ ecore_xcb_xinerama.c \ ecore_xcb_error.c \ ecore_xcb_xtest.c \ - ecore_xcb_vsync.c + ecore_xcb_vsync.c \ + ecore_xcb_resource.c libecore_x_xcb_la_LIBADD = \ @XCB_DAMAGE_LIBS@ \ @@ -87,7 +88,8 @@ libecore_x_xcb_la_LIBADD = \ @XCB_LIBS@ \ $(top_builddir)/src/lib/ecore/libecore.la \ $(top_builddir)/src/lib/ecore_input/libecore_input.la \ - @EINA_LIBS@ + @EINA_LIBS@ \ + @dlopen_libs@ endif diff --git a/src/lib/ecore_x/xcb/ecore_xcb.c b/src/lib/ecore_x/xcb/ecore_xcb.c index bb5e4c9..9db47c8 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb.c +++ b/src/lib/ecore_x/xcb/ecore_xcb.c @@ -1,4 +1,6 @@ #include "ecore_xcb_private.h" +#include +#include /* local function prototypes */ static int _ecore_xcb_shutdown(Eina_Bool close_display); @@ -38,6 +40,7 @@ double _ecore_xcb_double_click_time = 0.25; EAPI int ecore_x_init(const char *name) { + char *gl = NULL; uint32_t mask, list[1]; /* check if we have initialized already */ @@ -77,18 +80,83 @@ ecore_x_init(const char *name) eina_log_domain_unregister(_ecore_xcb_log_dom); _ecore_xcb_log_dom = -1; ecore_shutdown(); -// eina_shutdown(); return --_ecore_xcb_init_count; } - /* try to connect to the display server */ - _ecore_xcb_conn = xcb_connect(name, NULL); - - /* connect this way for opengl - _ecore_xcb_display = XOpenDisplay(name); - _ecore_xcb_conn = XGetXCBConnection(_ecore_xcb_display); - XSetEventQueueOwner(_ecore_xcb_display, XCBOwnsEventQueue); + /* check for env var which says we are not going to use GL @ all + * + * NB: This is done because if someone wants a 'pure' xcb implementation + * of ecore_x, all they need do is export this variable in the environment + * and ecore_x will not use xlib stuff at all. + * + * The upside is you can get pure xcb-based ecore_x (w/ all the speed), but + * there is a down-side here in that you cannot get OpenGL without XLib :( */ + if ((gl = getenv("ECORE_X_NO_XLIB"))) + { + /* we found the env var that says 'Yes, we are not ever gonna try + * OpenGL so it is safe to not use XLib at all' */ + + /* try to connect to the display server */ + _ecore_xcb_conn = xcb_connect(name, NULL); + } + else + { + /* env var was not specified, so we will assume that the user + * may want opengl @ some point. connect this way for opengl to work */ + + /* want to dlopen here to avoid actual library linkage */ + void *libxcb, *libxlib; + Display *(*_real_display)(const char *display); + xcb_connection_t *(*_real_connection)(Display *dpy); + void (*_real_queue)(Display *dpy, enum XEventQueueOwner owner); + + libxlib = dlopen("libX11.so", (RTLD_LAZY | RTLD_GLOBAL)); + if (!libxlib) + libxlib = dlopen("libX11.so.6", (RTLD_LAZY | RTLD_GLOBAL)); + if (!libxlib) + libxlib = dlopen("libX11.so.6.3.0", (RTLD_LAZY | RTLD_GLOBAL)); + if (!libxlib) + { + ERR("Could not dlsym to libX11"); + /* unregister log domain */ + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; + ecore_shutdown(); + return --_ecore_xcb_init_count; + } + + libxcb = dlopen("libX11-xcb.so", (RTLD_LAZY | RTLD_GLOBAL)); + if (!libxcb) + libxcb = dlopen("libX11-xcb.so.1", (RTLD_LAZY | RTLD_GLOBAL)); + if (!libxcb) + libxcb = dlopen("libX11-xcb.so.1.0.0", (RTLD_LAZY | RTLD_GLOBAL)); + if (!libxcb) + { + ERR("Could not dlsym to libX11-xcb"); + /* unregister log domain */ + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; + ecore_shutdown(); + return --_ecore_xcb_init_count; + } + + _real_display = dlsym(libxlib, "XOpenDisplay"); + if (_real_display) DBG("Have Real Display Symd"); + _real_connection = dlsym(libxcb, "XGetXCBConnection"); + if (_real_connection) DBG("Have Real Connection Symd"); + _real_queue = dlsym(libxcb, "XSetEventQueueOwner"); + if (_real_queue) DBG("Have Real Queue Symd"); + + if (_real_display) + { + _ecore_xcb_display = _real_display(name); + if (_real_connection) + _ecore_xcb_conn = _real_connection(_ecore_xcb_display); + if (_real_queue) + _real_queue(_ecore_xcb_display, XCBOwnsEventQueue); + } + } if (xcb_connection_has_error(_ecore_xcb_conn)) { @@ -97,7 +165,6 @@ ecore_x_init(const char *name) _ecore_xcb_log_dom = -1; ecore_event_shutdown(); ecore_shutdown(); -// eina_shutdown(); return --_ecore_xcb_init_count; } @@ -170,8 +237,6 @@ ecore_x_init(const char *name) /* setup dnd */ _ecore_xcb_dnd_init(); - // FIXME: XIM support - return _ecore_xcb_init_count; } @@ -936,9 +1001,18 @@ ecore_x_dpi_get(void) EAPI Ecore_X_Display * ecore_x_display_get(void) { + char *gl = NULL; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - return (Ecore_X_Display *)_ecore_xcb_conn; + /* if we have the 'dont use xlib' env var, then we are not using + * XLib and thus cannot return a real XDisplay. + * + * NB: This may break EFL in some places and needs lots of testing !!! */ + if ((gl = getenv("ECORE_X_NO_XLIB"))) + return (Ecore_X_Display *)_ecore_xcb_conn; + else /* we can safely return an XDisplay var */ + return (Ecore_X_Display *)_ecore_xcb_display; } /** diff --git a/src/lib/ecore_x/xcb/ecore_xcb_cursor.c b/src/lib/ecore_x/xcb/ecore_xcb_cursor.c index f71d595..e374a08 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_cursor.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_cursor.c @@ -9,6 +9,9 @@ /* local function prototypes */ static xcb_image_t *_ecore_xcb_cursor_image_create(int w, int h, int *pixels); static Ecore_X_Cursor _ecore_xcb_cursor_image_load_cursor(Ecore_X_Window win, int w, int h, int hot_x, int hot_y, int *pixels, xcb_image_t *img); +static void _ecore_xcb_cursor_default_size_get(void); +static void _ecore_xcb_cursor_dpi_size_get(void); +static void _ecore_xcb_cursor_guess_size(void); #ifdef ECORE_XCB_CURSOR static Ecore_X_Cursor _ecore_xcb_cursor_image_load_argb_cursor(Ecore_X_Window win, int w, int h, int hot_x, int hot_y, xcb_image_t *img); static xcb_render_pictforminfo_t *_ecore_xcb_cursor_find_image_format(void); @@ -38,6 +41,21 @@ _ecore_xcb_cursor_finalize(void) #ifdef ECORE_XCB_CURSOR _ecore_xcb_cursor = _ecore_xcb_render_argb_get(); + + /* try to grab cursor size from XDefaults */ + _ecore_xcb_cursor_default_size_get(); + + /* if that failed, try to get it from xft dpi setting */ + if (_ecore_xcb_cursor_size == 0) + _ecore_xcb_cursor_dpi_size_get(); + + /* If that fails, try to guess from display size */ + if (_ecore_xcb_cursor_size == 0) + _ecore_xcb_cursor_guess_size(); + + /* NB: Would normally add theme stuff here, but E cursor does not support + * xcursor themes. Delay parsing that stuff out until such time if/when the + * user selects to use X Cursor, rather than E cursor */ #endif } @@ -311,6 +329,37 @@ _ecore_xcb_cursor_image_load_cursor(Ecore_X_Window win, int w, int h, int hot_x, return cursor; } +static void +_ecore_xcb_cursor_default_size_get(void) +{ + char *v = NULL; + + v = getenv("XCURSOR_SIZE"); + if (!v) + v = _ecore_xcb_resource_get_string("Xcursor", "size"); + if (v) _ecore_xcb_cursor_size = ((atoi(v) * 16) / 72); +} + +static void +_ecore_xcb_cursor_dpi_size_get(void) +{ + int v = 0; + + v = _ecore_xcb_resource_get_int("Xft", "dpi"); + if (v) _ecore_xcb_cursor_size = ((v * 16) / 72); +} + +static void +_ecore_xcb_cursor_guess_size(void) +{ + int w = 0, h = 0, s = 0; + + ecore_x_screen_size_get(_ecore_xcb_screen, &w, &h); + if (h < w) s = h; + else s = w; + _ecore_xcb_cursor_size = (s / 48); +} + #ifdef ECORE_XCB_CURSOR static Ecore_X_Cursor _ecore_xcb_cursor_image_load_argb_cursor(Ecore_X_Window win, int w, int h, int hot_x, int hot_y, xcb_image_t *img) diff --git a/src/lib/ecore_x/xcb/ecore_xcb_private.h b/src/lib/ecore_x/xcb/ecore_xcb_private.h index 5330de2..926e13b 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_private.h +++ b/src/lib/ecore_x/xcb/ecore_xcb_private.h @@ -334,4 +334,7 @@ Ecore_X_Window_State _ecore_xcb_netwm_window_state_get(Ecore_X_Atom atom); int _ecore_xcb_error_handle(xcb_generic_error_t *err); int _ecore_xcb_io_error_handle(xcb_generic_error_t *err); +char *_ecore_xcb_resource_get_string(const char *prog, const char *name); +int _ecore_xcb_resource_get_int(const char *prog, const char *name); + #endif diff --git a/src/lib/ecore_x/xcb/ecore_xcb_render.c b/src/lib/ecore_x/xcb/ecore_xcb_render.c index 059d9a3..212e5c5 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_render.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_render.c @@ -1,5 +1,5 @@ #include "ecore_xcb_private.h" -#include +#include // for isupper/tolower #ifdef ECORE_XCB_RENDER # include # include @@ -7,7 +7,6 @@ /* local function prototypes */ static Eina_Bool _ecore_xcb_render_parse_boolean(char *v); -static char *_ecore_xcb_render_get_resource(const char *prog __UNUSED__, const char *name __UNUSED__); /* local variables */ static Eina_Bool _render_avail = EINA_FALSE; @@ -58,10 +57,7 @@ _ecore_xcb_render_finalize(void) _render_argb = EINA_TRUE; v = getenv("XCURSOR_CORE"); if (!v) - { - // TODO: check xgetdefault when xcb supports resources - v = _ecore_xcb_render_get_resource("Xcursor", "core"); - } + v = _ecore_xcb_resource_get_string("Xcursor", "core"); if ((v) && (_ecore_xcb_render_parse_boolean(v))) _render_argb = EINA_FALSE; } @@ -71,10 +67,7 @@ _ecore_xcb_render_finalize(void) _render_anim = EINA_TRUE; v = getenv("XCURSOR_ANIM"); if (!v) - { - // TODO: check xgetdefault when xcb supports resources - v = _ecore_xcb_render_get_resource("Xcursor", "anim"); - } + v = _ecore_xcb_resource_get_string("Xcursor", "anim"); if ((v) && (_ecore_xcb_render_parse_boolean(v))) _render_anim = EINA_FALSE; } @@ -221,9 +214,3 @@ _ecore_xcb_render_parse_boolean(char *v) } return EINA_FALSE; } - -static char * -_ecore_xcb_render_get_resource(const char *prog __UNUSED__, const char *name __UNUSED__) -{ - return NULL; -} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_resource.c b/src/lib/ecore_x/xcb/ecore_xcb_resource.c new file mode 100644 index 0000000..77a7ece --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_resource.c @@ -0,0 +1,87 @@ +/* NB: Reference GetDflt.c, Xresource.h, Xrm.c, Quarks.c */ + +#include "ecore_xcb_private.h" +#include +#ifdef NEED_SYS_PARAM_H +# include +#endif +#ifdef NEED_NETDB_H +# include +#endif + +/* local structs */ +typedef struct _Ecore_Xcb_Resource_Value +{ + unsigned int size; + void *addr; +} Ecore_Xcb_Resource_Value; + +/* local function prototypes */ +static char *_ecore_xcb_resource_get(const char *prog, const char *name); +static int _ecore_xcb_resource_string_to_name(const char *str); +static int _ecore_xcb_resource_string_to_class(const char *str); +static Eina_Bool _ecore_xcb_resource_fetch(int *names, int *klasses, int *type, Ecore_Xcb_Resource_Value value); + +char * +_ecore_xcb_resource_get_string(const char *prog, const char *name) +{ + char *ret = NULL; + + ret = _ecore_xcb_resource_get(prog, name); + return NULL; +// return ret; +} + +int +_ecore_xcb_resource_get_int(const char *prog, const char *name) +{ + char *ret = NULL; + + ret = _ecore_xcb_resource_get(prog, name); + return 0; +// return atoi(ret); +} + +/* local functions */ +static char * +_ecore_xcb_resource_get(const char *prog, const char *name) +{ + char *prog_name = NULL; + int names[3], klasses[3]; + int type; + Ecore_Xcb_Resource_Value value; + + prog_name = strrchr(prog, '/'); + if (prog_name) + prog_name++; + else + prog_name = (char *)prog; + + names[0] = _ecore_xcb_resource_string_to_name(prog_name); + names[1] = _ecore_xcb_resource_string_to_name(name); + names[2] = 0; + klasses[0] = _ecore_xcb_resource_string_to_class("Program"); + klasses[1] = _ecore_xcb_resource_string_to_class("Name"); + klasses[2] = 0; + + _ecore_xcb_resource_fetch(names, klasses, &type, value); + return (value.addr); +} + +static int +_ecore_xcb_resource_string_to_name(const char *str) +{ + return 0; +} + +static int +_ecore_xcb_resource_string_to_class(const char *str) +{ + return 0; +} + +static Eina_Bool +_ecore_xcb_resource_fetch(int *names, int *klasses, int *type, Ecore_Xcb_Resource_Value value) +{ + return EINA_FALSE; +} -- 2.7.4