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.



SVN revision: 61724
This commit is contained in:
Christopher Michael 2011-07-26 05:54:01 +00:00
parent 27395e85cf
commit 37b122117e
7 changed files with 260 additions and 33 deletions

View File

@ -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 <sys/param.h>],
[int h = MAXHOSTNAMELEN;]),
[FOUND_MAXHOSTNAMELEN='sys/param.h'
AC_DEFINE(NEED_SYS_PARAM_H,1,
[Define to 1 if you need <sys/param.h> to define MAXHOSTNAMELEN])])
AC_COMPILE_IFELSE(
AC_LANG_PROGRAM([#include <netdb.h>],
[int h = MAXHOSTNAMELEN;]),
[FOUND_MAXHOSTNAMELEN='netdb.h'
AC_DEFINE(NEED_NETDB_H,1,
[Define to 1 if you need <netdb.h> 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}"

View File

@ -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

View File

@ -1,4 +1,6 @@
#include "ecore_xcb_private.h"
#include <X11/Xlib-xcb.h>
#include <dlfcn.h>
/* 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;
}
/**

View File

@ -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)

View File

@ -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

View File

@ -1,5 +1,5 @@
#include "ecore_xcb_private.h"
#include <ctype.h>
#include <ctype.h> // for isupper/tolower
#ifdef ECORE_XCB_RENDER
# include <xcb/render.h>
# include <xcb/xcb_renderutil.h>
@ -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;
}

View File

@ -0,0 +1,87 @@
/* NB: Reference GetDflt.c, Xresource.h, Xrm.c, Quarks.c */
#include "ecore_xcb_private.h"
#include <ctype.h>
#ifdef NEED_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef NEED_NETDB_H
# include <netdb.h>
#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;
}