- add sources.
[platform/framework/web/crosswalk.git] / src / ui / views / widget / desktop_aura / desktop_drag_drop_client_aurax11.h
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_AURAX11_H_
6 #define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_AURAX11_H_
7
8 #include <set>
9 #include <X11/Xlib.h>
10
11 #include "base/compiler_specific.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "ui/aura/client/drag_drop_client.h"
15 #include "ui/aura/window_observer.h"
16 #include "ui/base/cursor/cursor.h"
17 #include "ui/gfx/point.h"
18 #include "ui/gfx/x/x11_atom_cache.h"
19 #include "ui/views/views_export.h"
20 #include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h"
21 #include "ui/views/widget/desktop_aura/x11_whole_screen_move_loop_delegate.h"
22
23 namespace aura {
24 namespace client {
25 class DragDropDelegate;
26 }
27 }
28
29 namespace gfx {
30 class Point;
31 }
32
33 namespace ui {
34 class DragSource;
35 class DropTargetEvent;
36 class OSExchangeData;
37 class OSExchangeDataProviderAuraX11;
38 class SelectionFormatMap;
39 }
40
41 namespace views {
42 class DesktopNativeCursorManager;
43
44 // Implements drag and drop on X11 for aura. On one side, this class takes raw
45 // X11 events forwarded from DesktopRootWindowHostLinux, while on the other, it
46 // handles the views drag events.
47 class VIEWS_EXPORT DesktopDragDropClientAuraX11
48     : public aura::client::DragDropClient,
49       public aura::WindowObserver,
50       public X11WholeScreenMoveLoopDelegate {
51  public:
52   DesktopDragDropClientAuraX11(
53       aura::Window* root_window,
54       views::DesktopNativeCursorManager* cursor_manager,
55       Display* xdisplay,
56       ::Window xwindow);
57   virtual ~DesktopDragDropClientAuraX11();
58
59   // We maintain a mapping of live DesktopDragDropClientAuraX11 objects to
60   // their ::Windows. We do this so that we're able to short circuit sending
61   // X11 messages to windows in our process.
62   static DesktopDragDropClientAuraX11* GetForWindow(::Window window);
63
64   // These methods handle the various X11 client messages from the platform.
65   void OnXdndEnter(const XClientMessageEvent& event);
66   void OnXdndLeave(const XClientMessageEvent& event);
67   void OnXdndPosition(const XClientMessageEvent& event);
68   void OnXdndStatus(const XClientMessageEvent& event);
69   void OnXdndFinished(const XClientMessageEvent& event);
70   void OnXdndDrop(const XClientMessageEvent& event);
71
72   // Called when XSelection data has been copied to our process.
73   void OnSelectionNotify(const XSelectionEvent& xselection);
74
75   // Overridden from aura::client::DragDropClient:
76   virtual int StartDragAndDrop(
77       const ui::OSExchangeData& data,
78       aura::Window* root_window,
79       aura::Window* source_window,
80       const gfx::Point& root_location,
81       int operation,
82       ui::DragDropTypes::DragEventSource source) OVERRIDE;
83   virtual void DragUpdate(aura::Window* target,
84                           const ui::LocatedEvent& event) OVERRIDE;
85   virtual void Drop(aura::Window* target,
86                     const ui::LocatedEvent& event) OVERRIDE;
87   virtual void DragCancel() OVERRIDE;
88   virtual bool IsDragDropInProgress() OVERRIDE;
89
90   // Overridden from aura::WindowObserver:
91   virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
92
93   // Overridden from X11WholeScreenMoveLoopDelegate:
94   virtual void OnMouseMovement(XMotionEvent* event) OVERRIDE;
95   virtual void OnMouseReleased() OVERRIDE;
96   virtual void OnMoveLoopEnded() OVERRIDE;
97
98  private:
99   typedef std::map< ::Window, std::pair<gfx::Point, unsigned long> >
100       NextPositionMap;
101
102   // When we receive an position x11 message, we need to translate that into
103   // the underlying aura::Window representation, as moves internal to the X11
104   // window can cause internal drag leave and enter messages.
105   void DragTranslate(const gfx::Point& root_window_location,
106                      scoped_ptr<ui::OSExchangeData>* data,
107                      scoped_ptr<ui::DropTargetEvent>* event,
108                      aura::client::DragDropDelegate** delegate);
109
110   // Called when we need to notify the current aura::Window that we're no
111   // longer dragging over it.
112   void NotifyDragLeave();
113
114   // Converts our bitfield of actions into an Atom that represents what action
115   // we're most likely to take on drop.
116   ::Atom DragOperationToAtom(int drag_operation);
117
118   // Converts a single action atom to a drag operation.
119   int AtomToDragOperation(::Atom atom);
120
121   // During the blocking StartDragAndDrop() call, this converts the views-style
122   // |drag_operation_| bitfield into a vector of Atoms to offer to other
123   // processes.
124   std::vector< ::Atom> GetOfferedDragOperations();
125
126   // This returns a representation of the data we're offering in this
127   // drag. This is done to bypass an asynchronous roundtrip with the X11
128   // server.
129   ui::SelectionFormatMap GetFormatMap() const;
130
131   // Handling XdndPosition can be paused while waiting for more data; this is
132   // called either synchronously from OnXdndPosition, or asynchronously after
133   // we've received data requested from the other window.
134   void CompleteXdndPosition(::Window source_window,
135                             const gfx::Point& screen_point);
136
137   void SendXdndEnter(::Window dest_window);
138   void SendXdndLeave(::Window dest_window);
139   void SendXdndPosition(::Window dest_window,
140                         const gfx::Point& screen_point,
141                         unsigned long time);
142   void SendXdndDrop(::Window dest_window);
143
144   // Sends |xev| to |xid|, optionally short circuiting the round trip to the X
145   // server.
146   void SendXClientEvent(::Window xid, XEvent* xev);
147
148   // A nested message loop that notifies this object of events through the
149   // X11WholeScreenMoveLoopDelegate interface.
150   X11WholeScreenMoveLoop move_loop_;
151
152   aura::Window* root_window_;
153
154   Display* xdisplay_;
155   ::Window xwindow_;
156
157   ui::X11AtomCache atom_cache_;
158
159   // Target side information.
160   class X11DragContext;
161   scoped_ptr<X11DragContext> target_current_context_;
162
163   // The Aura window that is currently under the cursor. We need to manually
164   // keep track of this because Windows will only call our drag enter method
165   // once when the user enters the associated X Window. But inside that X
166   // Window there could be multiple aura windows, so we need to generate drag
167   // enter events for them.
168   aura::Window* target_window_;
169
170   // Because Xdnd messages don't contain the position in messages other than
171   // the XdndPosition message, we must manually keep track of the last position
172   // change.
173   gfx::Point target_window_location_;
174   gfx::Point target_window_root_location_;
175
176   // In the Xdnd protocol, we aren't supposed to send another XdndPosition
177   // message until we have received a confirming XdndStatus message.
178   std::set< ::Window> waiting_on_status_;
179
180   // If we would send an XdndPosition message while we're waiting for an
181   // XdndStatus response, we need to cache the latest details we'd send.
182   NextPositionMap next_position_message_;
183
184   // Source side information.
185   ui::OSExchangeDataProviderAuraX11 const* source_provider_;
186   ::Window source_current_window_;
187
188   bool drag_drop_in_progress_;
189
190   // The operation bitfield as requested by StartDragAndDrop.
191   int drag_operation_;
192
193   // The operation performed. Is initialized to None at the start of
194   // StartDragAndDrop(), and is set only during the asynchronous XdndFinished
195   // message.
196   int resulting_operation_;
197
198   // This window will be receiving a drop as soon as we receive an XdndStatus
199   // from it.
200   std::set< ::Window> pending_drop_;
201
202   // We offer the other window a list of possible operations,
203   // XdndActionsList. This is the requested action from the other window. This
204   // is None if we haven't sent out an XdndPosition message yet, haven't yet
205   // received an XdndStatus or if the other window has told us that there's no
206   // action that we can agree on.
207   //
208   // This is a map instead of a simple variable because of the case where we
209   // put an XdndLeave in the queue at roughly the same time that the other
210   // window responds to an XdndStatus.
211   std::map< ::Window, ::Atom> negotiated_operation_;
212
213   // We use these cursors while dragging.
214   gfx::NativeCursor grab_cursor_;
215   gfx::NativeCursor copy_grab_cursor_;
216   gfx::NativeCursor move_grab_cursor_;
217
218   static std::map< ::Window, DesktopDragDropClientAuraX11*> g_live_client_map;
219
220   DISALLOW_COPY_AND_ASSIGN(DesktopDragDropClientAuraX11);
221 };
222
223 }  // namespace views
224
225 #endif  // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_AURAX11_H_