1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef UI_BASE_X_SELECTION_OWNER_H_ 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UI_BASE_X_SELECTION_OWNER_H_ 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector> 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/basictypes.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/callback.h" 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/ref_counted_memory.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/time/time.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/timer/timer.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/ui_base_export.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/base/x/selection_utils.h" 1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/x/x11_atom_cache.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/gfx/x/x11_types.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace ui { 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Owns a specific X11 selection on an X window. 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The selection owner object keeps track of which xwindow is the current 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// owner, and when its |xwindow_|, offers different data types to other 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// processes. 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class UI_BASE_EXPORT SelectionOwner { 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SelectionOwner(XDisplay* xdisplay, 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch XID xwindow, 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch XAtom selection_name); 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~SelectionOwner(); 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Returns the current selection data. Useful for fast paths. 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SelectionFormatMap& selection_format_map() { return format_map_; } 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Appends a list of types we're offering to |targets|. 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void RetrieveTargets(std::vector<XAtom>* targets); 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Attempts to take ownership of the selection. If we're successful, present 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |data| to other windows. 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void TakeOwnershipOfSelection(const SelectionFormatMap& data); 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Clears our internal format map and clears the selection owner, whether we 4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // own the selection or not. 4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) void ClearSelectionOwner(); 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // It is our owner's responsibility to plumb X11 events on |xwindow_| to us. 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void OnSelectionRequest(const XEvent& event); 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void OnSelectionClear(const XEvent& event); 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Returns true if SelectionOwner can process the XPropertyEvent event, 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |event|. 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool CanDispatchPropertyEvent(const XEvent& event); 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void OnPropertyEvent(const XEvent& event); 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Holds state related to an incremental data transfer. 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) struct IncrementalTransfer { 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) IncrementalTransfer(XID window, 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) XAtom target, 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) XAtom property, 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const scoped_refptr<base::RefCountedMemory>& data, 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int offset, 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::TimeTicks timeout, 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int foreign_window_manager_id); 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ~IncrementalTransfer(); 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Parameters from the XSelectionRequest. The data is transferred over 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |property| on |window|. 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) XID window; 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) XAtom target; 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) XAtom property; 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The data to be transferred. 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<base::RefCountedMemory> data; 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The offset from the beginning of |data| of the first byte to be 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // transferred in the next chunk. 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t offset; 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Time when the transfer should be aborted because the selection requestor 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // is taking too long to notify us that we can send the next chunk. 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::TimeTicks timeout; 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Used to unselect PropertyChangeMask on |window| when we are done with 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the data transfer. 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int foreign_window_manager_id; 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }; 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Attempts to convert the selection to |target|. If the conversion is 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // successful, true is returned and the result is stored in the |property| 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // of |requestor|. 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool ProcessTarget(XAtom target, XID requestor, XAtom property); 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Sends the next chunk of data for given the incremental data transfer. 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void ProcessIncrementalTransfer(IncrementalTransfer* transfer); 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Aborts any incremental data transfers which have timed out. 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void AbortStaleIncrementalTransfers(); 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Called when the transfer at |it| has completed to do cleanup. 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void CompleteIncrementalTransfer( 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<IncrementalTransfer>::iterator it); 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Returns the incremental data transfer, if any, which was waiting for 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |event|. 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<IncrementalTransfer>::iterator FindIncrementalTransferForEvent( 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const XEvent& event); 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Our X11 state. 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch XDisplay* x_display_; 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch XID x_window_; 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The X11 selection that this instance communicates on. 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch XAtom selection_name_; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The maximum size of data we can put in XChangeProperty(). 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t max_request_size_; 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The data we are currently serving. 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SelectionFormatMap format_map_; 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<IncrementalTransfer> incremental_transfers_; 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Used to abort stale incremental data transfers. 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::RepeatingTimer<SelectionOwner> incremental_transfer_abort_timer_; 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) X11AtomCache atom_cache_; 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SelectionOwner); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace ui 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // UI_BASE_X_SELECTION_OWNER_H_ 138