Ecore_X(cb): Enable code for using xprint to get window root list
authordevilhorns <devilhorns@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 22 Aug 2011 20:10:53 +0000 (20:10 +0000)
committerdevilhorns <devilhorns@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 22 Aug 2011 20:10:53 +0000 (20:10 +0000)
(like xlib has). Remove some fixme's (implement error checking for a
few functions).

NB: While this code makes ecore_x_window_root_list work like the xlib
version does (ability to use xprint to get list), I highly recommend
building ecore without xprint support (--disable-ecore-x-xprint)
because this seems like a lot of work to go through to get the window
root list. Building without xprint support provides a faster code path.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@62696 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/ecore_x/xcb/ecore_xcb.c
src/lib/ecore_x/xcb/ecore_xcb_window.c

index 46afe78..b1b198f 100644 (file)
@@ -691,13 +691,23 @@ ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y)
 EAPI Eina_Bool 
 ecore_x_pointer_control_set(int accel_num, int accel_denom, int threshold) 
 {
+   xcb_void_cookie_t vcookie;
+   xcb_generic_error_t *err;
+
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
-   /* FIXME: Check request for success */
-   /* xcb_change_pointer_control_checked */
-   /* xcb_request_check */
-   xcb_change_pointer_control(_ecore_xcb_conn, 
-                              accel_num, accel_denom, threshold, 1, 1);
+   vcookie = 
+     xcb_change_pointer_control_checked(_ecore_xcb_conn, 
+                                        accel_num, accel_denom, threshold, 
+                                        1, 1);
+   err = xcb_request_check(_ecore_xcb_conn, vcookie);
+   if (err) 
+     {
+        _ecore_xcb_error_handle(err);
+        free(err);
+        return EINA_FALSE;
+     }
+
    return EINA_TRUE;
 }
 
@@ -845,12 +855,21 @@ ecore_x_pointer_ungrab(void)
 EAPI Eina_Bool 
 ecore_x_pointer_warp(Ecore_X_Window win, int x, int y) 
 {
+   xcb_void_cookie_t vcookie;
+   xcb_generic_error_t *err;
+
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
-   /* FIXME: Check Return */
-   /* xcb_warp_pointer_checked */
-   /* xcb_request_check */
-   xcb_warp_pointer(_ecore_xcb_conn, XCB_NONE, win, 0, 0, 0, 0, x, y);
+   vcookie = 
+     xcb_warp_pointer_checked(_ecore_xcb_conn, XCB_NONE, win, 0, 0, 0, 0, x, y);
+   err = xcb_request_check(_ecore_xcb_conn, vcookie);
+   if (err) 
+     {
+        _ecore_xcb_error_handle(err);
+        free(err);
+        return EINA_FALSE;
+     }
+
    return EINA_TRUE;
 }
 
@@ -1366,7 +1385,7 @@ _ecore_xcb_fd_handle(void *data, Ecore_Fd_Handler *hdlr __UNUSED__)
           {
              /* trap mouse motion events and filter out all but the last one. 
               * we do this because handling every one is fairly cpu intensive 
-              * (especially on under-powered devices.
+              * (especially on under-powered devices).
               * 
               * NB: I've tested this extensively and have found no ill effects, 
               * but if someone notices something, please report it */
@@ -1416,7 +1435,7 @@ _ecore_xcb_fd_handle_buff(void *data, Ecore_Fd_Handler *hdlr __UNUSED__)
           }
         /* trap mouse motion events and filter out all but the last one. 
          * we do this because handling every one is fairly cpu intensive 
-         * (especially on under-powered devices.
+         * (especially on under-powered devices).
          * 
          * NB: I've tested this extensively and have found no ill effects, 
          * but if someone notices something, please report it */
index fca30c2..78af012 100644 (file)
@@ -5,12 +5,16 @@
 #ifdef ECORE_XCB_SHAPE
 # include <xcb/shape.h>
 #endif
+#ifdef ECORE_XCB_XPRINT
+#include <xcb/xprint.h>
+#endif
 
 /* local function prototypes */
 static Ecore_X_Window _ecore_xcb_window_argb_internal_new(Ecore_X_Window parent, int x, int y, int w, int h, uint8_t override_redirect, uint8_t save_under);
 static Ecore_X_Window _ecore_xcb_window_at_xy_get(Ecore_X_Window base, int bx, int by, int x, int y, Ecore_X_Window *skip, int skip_num);
 static int _ecore_xcb_window_modifiers_get(unsigned int state);
 static xcb_visualtype_t *_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id);
+static xcb_screen_t *_ecore_xcb_window_screen_of_display(int screen);
 
 /* local variables */
 static int ignore_num = 0;
@@ -1069,8 +1073,6 @@ ecore_x_window_manage(Ecore_X_Window win)
    ecore_x_flush(); // needed
 //   ecore_x_sync(); // needed
 
-   /* FIXME: XLib uses XSelectInput */
-   /* FIXME: Add error handler trap */
    list = (XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | 
            XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_RESIZE_REDIRECT | 
            XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | 
@@ -1265,20 +1267,102 @@ ecore_x_window_root_list(int *num_ret)
    xcb_screen_iterator_t iter;
    const xcb_setup_t *setup;
    uint8_t i, num;
-   Ecore_X_Window *roots;
+   Ecore_X_Window *roots = NULL;
+#ifdef ECORE_XCB_XPRINT
+   const xcb_query_extension_reply_t *ext_reply;
+#endif
 
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
    if (!num_ret) return NULL;
+   *num_ret = 0;
 
-   /* FIXME: Use xprint if available. Reference xlib */
    setup = xcb_get_setup(_ecore_xcb_conn);
-   iter = xcb_setup_roots_iterator(setup);
    num = setup->roots_len;
+
+#ifdef ECORE_XCB_XPRINT
+   ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_x_print_id);
+   if ((ext_reply) && (ext_reply->present)) 
+     {
+        xcb_x_print_print_query_screens_cookie_t cookie;
+        xcb_x_print_print_query_screens_reply_t *reply;
+
+        cookie = xcb_x_print_print_query_screens_unchecked(_ecore_xcb_conn);
+        reply = 
+          xcb_x_print_print_query_screens_reply(_ecore_xcb_conn, cookie, NULL);
+        if (reply) 
+          {
+             xcb_window_t *screens;
+             int psnum = 0, overlap = 0, j = 0, k = 0;
+
+             psnum = xcb_x_print_print_query_screens_roots_length(reply);
+             screens = xcb_x_print_print_query_screens_roots(reply);
+             for (i = 0; i < num; i++) 
+               {
+                  for (j = 0; j < psnum; j++) 
+                    {
+                       if ((_ecore_xcb_window_screen_of_display(i))->root == 
+                           screens[j]) 
+                         {
+                            overlap++;
+                         }
+                    }
+               }
+             if (!(roots = malloc((num - overlap) 
+                                  * sizeof(Ecore_X_Window)))) return NULL;
+             for (i = 0; i < num; i++) 
+               {
+                  Eina_Bool is_print = EINA_FALSE;
+
+                  for (j = 0; j < psnum; j++) 
+                    {
+                       if ((_ecore_xcb_window_screen_of_display(i))->root == 
+                           screens[j]) 
+                         {
+                            is_print = EINA_TRUE;
+                            break;
+                         }
+                    }
+                  if (!is_print) 
+                    {
+                       xcb_screen_t *s;
+
+                       s = _ecore_xcb_window_screen_of_display(i);
+                       if (s) 
+                         {
+                            roots[k] = s->root;
+                            k++;
+                         }
+                    }
+               }
+             *num_ret = k;
+          }
+        else 
+          {
+             /* Fallback to default method */
+             iter = xcb_setup_roots_iterator(setup);
+             if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
+             *num_ret = num;
+             for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
+               roots[i] = iter.data->root;
+          }
+     }
+   else 
+     {
+        /* Fallback to default method */
+        iter = xcb_setup_roots_iterator(setup);
+        if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
+        *num_ret = num;
+        for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
+          roots[i] = iter.data->root;
+     }
+#else
+   iter = xcb_setup_roots_iterator(setup);
    if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
    *num_ret = num;
    for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
      roots[i] = iter.data->root;
+#endif
 
    return roots;
 }
@@ -1937,3 +2021,16 @@ _ecore_xcb_window_find_visual_by_id(xcb_visualid_t id)
      }
    return 0;
 }
+
+static xcb_screen_t *
+_ecore_xcb_window_screen_of_display(int screen) 
+{
+   xcb_screen_iterator_t iter;
+
+   iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
+   for (; iter.rem; --screen, xcb_screen_next(&iter))
+     if (screen == 0)
+       return iter.data;
+
+   return NULL;
+}