Ecore X: Added Xfixes selection notification support.
authortasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 8 Aug 2011 14:36:02 +0000 (14:36 +0000)
committertasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 8 Aug 2011 14:36:02 +0000 (14:36 +0000)
Now we can get notifications for changes in X selection. This is very useful
for text editors that want to disable their "paste" button when there's
nothing to paste.

git-svn-id: http://svn.enlightenment.org/svn/e/trunk/ecore@62205 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/ecore_x/Ecore_X.h
src/lib/ecore_x/xcb/ecore_xcb_events.c
src/lib/ecore_x/xcb/ecore_xcb_xfixes.c
src/lib/ecore_x/xlib/ecore_x.c
src/lib/ecore_x/xlib/ecore_x_events.c
src/lib/ecore_x/xlib/ecore_x_fixes.c

index c6b1634..05f7e9f 100644 (file)
@@ -371,6 +371,7 @@ typedef struct _Ecore_X_Event_Window_Mapping      Ecore_X_Event_Window_Mapping;
 typedef struct _Ecore_X_Event_Selection_Clear     Ecore_X_Event_Selection_Clear;
 typedef struct _Ecore_X_Event_Selection_Request   Ecore_X_Event_Selection_Request;
 typedef struct _Ecore_X_Event_Selection_Notify    Ecore_X_Event_Selection_Notify;
+typedef struct _Ecore_X_Event_Fixes_Selection_Notify    Ecore_X_Event_Fixes_Selection_Notify;
 typedef struct _Ecore_X_Selection_Data            Ecore_X_Selection_Data;
 typedef struct _Ecore_X_Selection_Data_Files      Ecore_X_Selection_Data_Files;
 typedef struct _Ecore_X_Selection_Data_Text       Ecore_X_Selection_Data_Text;
@@ -617,6 +618,24 @@ struct _Ecore_X_Event_Selection_Request
    Ecore_X_Atom   property;
 };
 
+typedef enum
+{
+   ECORE_X_OWNER_CHANGE_REASON_NEW_OWNER,
+   ECORE_X_OWNER_CHANGE_REASON_DESTROY,
+   ECORE_X_OWNER_CHANGE_REASON_CLOSE
+} Ecore_X_Owner_Change_Reason;
+
+struct _Ecore_X_Event_Fixes_Selection_Notify
+{
+   Ecore_X_Window    win;
+   Ecore_X_Window    owner;
+   Ecore_X_Time      time;
+   Ecore_X_Time      selection_time;
+   Ecore_X_Selection selection;
+   Ecore_X_Atom      atom;
+   Ecore_X_Owner_Change_Reason reason;
+};
+
 struct _Ecore_X_Event_Selection_Notify
 {
    Ecore_X_Window    win;
@@ -898,6 +917,7 @@ EAPI extern int ECORE_X_EVENT_MAPPING_CHANGE;
 EAPI extern int ECORE_X_EVENT_SELECTION_CLEAR;
 EAPI extern int ECORE_X_EVENT_SELECTION_REQUEST;
 EAPI extern int ECORE_X_EVENT_SELECTION_NOTIFY;
+EAPI extern int ECORE_X_EVENT_FIXES_SELECTION_NOTIFY;
 EAPI extern int ECORE_X_EVENT_CLIENT_MESSAGE;
 EAPI extern int ECORE_X_EVENT_WINDOW_SHAPE;
 EAPI extern int ECORE_X_EVENT_SCREENSAVER_NOTIFY;
@@ -3002,6 +3022,16 @@ EAPI void                   ecore_x_region_picture_clip_set(Ecore_X_Region  regi
                                                             int             x_origin,
                                                             int             y_origin);
 
+/**
+ * xfixes selection notification request.
+ *
+ * This lets you choose which selections you want to get notifications for.
+ * @param selection the selection atom.
+ * @return EINA_TRUE on success, EINA_FALSE otherwise.
+ * @since 1.1.0
+ */
+EAPI Eina_Bool              ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection);
+
 /* XComposite Extension Support */
 EAPI Eina_Bool              ecore_x_composite_query(void);
 EAPI void                   ecore_x_composite_redirect_window(Ecore_X_Window                win,
index 4186a2c..c6b2e32 100644 (file)
@@ -130,6 +130,7 @@ EAPI int ECORE_X_EVENT_MAPPING_CHANGE = 0;
 EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0;
 EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
 EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
+EAPI int ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = 0;
 EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
 EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
 EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;
@@ -2059,14 +2060,37 @@ _ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event)
 static void 
 _ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event __UNUSED__) 
 {
-//   xcb_xfixes_selection_notify_event_t *ev;
+   Ecore_X_Event_Fixes_Selection_Notify *e;
+   Ecore_X_Atom sel;
+   xcb_xfixes_selection_notify_event_t *ev;
 
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
-//   ev = (xcb_xfixes_selection_notify_event_t *)event;
+   ev = (xcb_xfixes_selection_notify_event_t *)event;
+
+   e = calloc(1, sizeof(*e));
+   if (!e)
+      return;
+
+   e->win = ev->window;
+   e->owner = ev->owner;
+   e->time = ev->timestamp;
+   e->selection_time = ev->selection_timestamp;
+   e->atom = sel = ev->selection;
+   if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
+      e->selection = ECORE_X_SELECTION_PRIMARY;
+   else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
+      e->selection = ECORE_X_SELECTION_SECONDARY;
+   else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+      e->selection = ECORE_X_SELECTION_CLIPBOARD;
+   else
+      e->selection = ECORE_X_SELECTION_OTHER;
+   e->reason = ev->subtype;
+
+   ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL);
+} /* _ecore_x_event_handle_fixes_selection_notify */
 
-//   FIXME: TBD
 }
 
 static void 
index c4648ea..46e62d3 100644 (file)
@@ -47,7 +47,10 @@ _ecore_xcb_xfixes_finalize(void)
         if (reply) 
           {
              if (reply->major_version >= 3) 
-               _xfixes_avail = EINA_TRUE;
+               {
+                  _xfixes_avail = EINA_TRUE;
+                  ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = ecore_event_type_new();
+               }
              free(reply);
           }
 
@@ -57,6 +60,25 @@ _ecore_xcb_xfixes_finalize(void)
 #endif
 }
 
+EAPI Eina_Bool
+ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection)
+{
+#ifdef ECORE_XCB_XFIXES
+   if (_xfixes_avail)
+     {
+        xcb_xfixes_select_selection_input_checked(_ecore_xcb_conn,
+              /* FIXME: We need a way to know the root window. */
+              NULL,
+              selection,
+              XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
+              XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
+              XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE);
+        return EINA_TRUE;
+     }
+#endif
+   return EINA_FALSE;
+}
+
 Eina_Bool 
 _ecore_xcb_xfixes_avail_get(void) 
 {
index 3198466..6d12ce1 100644 (file)
@@ -91,6 +91,7 @@ EAPI int ECORE_X_EVENT_MAPPING_CHANGE = 0;
 EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0;
 EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
 EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
+EAPI int ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = 0;
 EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
 EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
 EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;
index c48d2b8..73df6b3 100644 (file)
@@ -2107,9 +2107,34 @@ _ecore_x_event_handle_randr_notify(XEvent *xevent)
 void
 _ecore_x_event_handle_fixes_selection_notify(XEvent *event)
 {
+   XFixesSelectionNotifyEvent *notify_event =
+      (XFixesSelectionNotifyEvent *) event;
+   Ecore_X_Event_Fixes_Selection_Notify *e;
+   Ecore_X_Atom sel;
+
    _ecore_x_last_event_mouse_move = 0;
    /* Nothing here yet */
-   event = NULL;
+
+   e = calloc(1, sizeof(*e));
+   if (!e)
+      return;
+
+   e->win = notify_event->window;
+   e->owner = notify_event->owner;
+   e->time = notify_event->timestamp;
+   e->selection_time = notify_event->selection_timestamp;
+   e->atom = sel = notify_event->selection;
+   if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
+      e->selection = ECORE_X_SELECTION_PRIMARY;
+   else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
+      e->selection = ECORE_X_SELECTION_SECONDARY;
+   else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+      e->selection = ECORE_X_SELECTION_CLIPBOARD;
+   else
+      e->selection = ECORE_X_SELECTION_OTHER;
+   e->reason = notify_event->subtype;
+
+   ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL);
 } /* _ecore_x_event_handle_fixes_selection_notify */
 
 #endif /* ifdef ECORE_XFIXES */
index 6fae184..7bed783 100644 (file)
@@ -21,7 +21,11 @@ _ecore_x_fixes_init(void)
 
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
    if (XFixesQueryVersion(_ecore_x_disp, &_fixes_major, &_fixes_minor))
-      _fixes_available = 1;
+     {
+        _fixes_available = 1;
+
+        ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = ecore_event_type_new();
+     }
    else
       _fixes_available = 0;
 
@@ -80,6 +84,24 @@ _ecore_x_rectangle_x_to_ecore(XRectangle *xrect, int num)
 
 #endif /* ifdef ECORE_XFIXES */
 
+EAPI Eina_Bool
+ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection)
+{
+#ifdef ECORE_XFIXES
+   if (_fixes_available)
+     {
+        XFixesSelectSelectionInput (_ecore_x_disp,
+              DefaultRootWindow(_ecore_x_disp),
+              selection,
+              XFixesSetSelectionOwnerNotifyMask |
+              XFixesSelectionWindowDestroyNotifyMask |
+              XFixesSelectionClientCloseNotifyMask);
+        return EINA_TRUE;
+     }
+#endif
+   return EINA_FALSE;
+}
+
 EAPI Ecore_X_Region
 ecore_x_region_new(Ecore_X_Rectangle *rects, int num)
 {