BsLinuxDropTarget.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. #include <X11/X.h>
  6. #include <X11/Xlib.h>
  7. namespace bs
  8. {
  9. /** Handles X11 drag and drop functionality. */
  10. class LinuxDragAndDrop
  11. {
  12. /** Possible states of the DND manager. */
  13. enum class State
  14. {
  15. Inactive,
  16. Entered,
  17. Active
  18. };
  19. /** Type of drag and drop operation. */
  20. enum class DragAndDropOpType
  21. {
  22. Enter,
  23. DragOver,
  24. Drop,
  25. Leave
  26. };
  27. /** Structure describing a drag and drop operation. */
  28. struct DragAndDropOp
  29. {
  30. DragAndDropOp(DragAndDropOpType type, DropTarget* target)
  31. :type(type), target(target)
  32. { }
  33. DragAndDropOp(DragAndDropOpType type, DropTarget* target, const Vector2I& pos)
  34. :type(type), target(target), position(pos)
  35. { }
  36. DragAndDropOp(DragAndDropOpType type, DropTarget* target, const Vector2I& pos,
  37. const Vector<Path>& fileList)
  38. :type(type), target(target), position(pos), fileList(fileList)
  39. { }
  40. DragAndDropOpType type;
  41. DropTarget* target;
  42. Vector2I position;
  43. Vector<Path> fileList;
  44. };
  45. /** Represents a single registered drop area. */
  46. struct DropArea
  47. {
  48. DropArea(DropTarget* target, const Rect2I& area)
  49. :target(target), area(area)
  50. { }
  51. DropTarget* target;
  52. Rect2I area;
  53. };
  54. /** Type of operations that can happen to a DropArea. */
  55. enum class DropAreaOpType
  56. {
  57. Register, /**< New DropArea is being registered. */
  58. Unregister, /**< DropArea is being unregistered. */
  59. Update /**< DropArea was updated. */
  60. };
  61. /** Operation that in some way modifies a DropArea. */
  62. struct DropAreaOp
  63. {
  64. DropAreaOp(DropTarget* target, DropAreaOpType type, const Rect2I& area = Rect2I::EMPTY)
  65. :target(target), area(area), type(type)
  66. { }
  67. DropTarget* target;
  68. Rect2I area;
  69. DropAreaOpType type;
  70. };
  71. public:
  72. /**
  73. * Initializes the drag and drop system. Must be called before any other drag and drop methods are called.
  74. *
  75. * @note Core thread only.
  76. */
  77. static void startUp(::Display* xDisplay);
  78. /**
  79. * Shuts down the drag and drop system. Should be called after no more calls to the system are expected.
  80. *
  81. * @note Core thread only.
  82. */
  83. static void shutDown();
  84. /**
  85. * Triggers any drag and drop events.
  86. *
  87. * @note Sim thread only.
  88. */
  89. static void update();
  90. /**
  91. * Marks an X11 window as drag and drop aware (being able to accept and send drag and drop events).
  92. *
  93. * @note Core thread only.
  94. */
  95. static void makeDNDAware(::Window xWindow);
  96. /**
  97. * Registers a new drop target Any further events processed will take this target into account, trigger its event
  98. * and populate its data if a drop occurs.
  99. *
  100. * @note Thread safe.
  101. */
  102. static void registerDropTarget(DropTarget* target);
  103. /**
  104. * Updates information about previous registered DropTarget. Call this when drop target area changes.
  105. *
  106. * @note Thread safe.
  107. */
  108. static void updateDropTarget(DropTarget* target);
  109. /**
  110. * Unregisters a drop target. Its events will no longer be triggered.
  111. *
  112. * @note Thread safe.
  113. */
  114. static void unregisterDropTarget(DropTarget* target);
  115. /**
  116. * Processes X11 ClientMessage event and handles any messages relating to drag and drop. Returns true if a message
  117. * was handled, or false if it needs to be handled by the caller.
  118. *
  119. * @note Core thread only.
  120. */
  121. static bool handleClientMessage(XClientMessageEvent& event);
  122. /**
  123. * Processes X11 SelectionNotify event and handles it if it relates to drag and drop. Returns true if the event was
  124. * handled, or false otherwise.
  125. *
  126. * @note Core thread only.
  127. */
  128. static bool handleSelectionNotify(XSelectionEvent& event);
  129. private:
  130. static ::Display* sXDisplay;
  131. static bool sDragActive;
  132. static Vector<DropArea> sDropAreas;
  133. static Mutex sMutex;
  134. static INT32 sDNDVersion;
  135. static Atom sDNDType;
  136. static ::Window sDNDSource;
  137. static Vector2I sDragPosition;
  138. static Vector<DragAndDropOp> sQueuedOperations;
  139. static Vector<DropAreaOp> sQueuedAreaOperations;
  140. // Awareness
  141. static Atom sXdndAware;
  142. // Selection handling
  143. static Atom sXdndSelection;
  144. // Client messages
  145. static Atom sXdndEnter;
  146. static Atom sXdndLeave;
  147. static Atom sXdndPosition;
  148. static Atom sXdndStatus;
  149. static Atom sXdndDrop;
  150. static Atom sXdndFinished;
  151. // Actions
  152. static Atom sXdndActionCopy;
  153. // Type list
  154. static Atom sXdndTypeList;
  155. // Other
  156. static Atom sPRIMARY;
  157. };
  158. }