Ecore_X: Add start of XResource handling for xcb backend (NB: Nowhere
authordevilhorns <devilhorns@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 26 Jul 2011 05:54:01 +0000 (05:54 +0000)
committerdevilhorns <devilhorns@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 26 Jul 2011 05:54:01 +0000 (05:54 +0000)
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: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@61724 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

configure.ac
src/lib/ecore_x/xcb/Makefile.am
src/lib/ecore_x/xcb/ecore_xcb.c
src/lib/ecore_x/xcb/ecore_xcb_cursor.c
src/lib/ecore_x/xcb/ecore_xcb_private.h
src/lib/ecore_x/xcb/ecore_xcb_render.c
src/lib/ecore_x/xcb/ecore_xcb_resource.c [new file with mode: 0644]

index fd8a328..e8eefce 100644 (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}"
index 7e48f36..bcdd6b2 100644 (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
 
index bb5e4c9..9db47c8 100644 (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;
 }
 
 /**
index f71d595..e374a08 100644 (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) 
index 5330de2..926e13b 100644 (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
index 059d9a3..212e5c5 100644 (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;
-}
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 (file)
index 0000000..77a7ece
--- /dev/null
@@ -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;
+}