The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

357 lines
13KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. //==============================================================================
  21. namespace XWindowSystemUtilities
  22. {
  23. //==============================================================================
  24. /** A handy struct that uses XLockDisplay and XUnlockDisplay to lock the X server
  25. using RAII.
  26. @tags{GUI}
  27. */
  28. struct ScopedXLock
  29. {
  30. ScopedXLock();
  31. ~ScopedXLock();
  32. };
  33. //==============================================================================
  34. /** Gets a specified window property and stores its associated data, freeing it
  35. on deletion.
  36. @tags{GUI}
  37. */
  38. struct GetXProperty
  39. {
  40. GetXProperty (::Display* display, ::Window windowH, Atom property,
  41. long offset, long length, bool shouldDelete, Atom requestedType);
  42. ~GetXProperty();
  43. bool success = false;
  44. unsigned char* data = nullptr;
  45. unsigned long numItems = 0, bytesLeft = 0;
  46. Atom actualType;
  47. int actualFormat = -1;
  48. };
  49. //==============================================================================
  50. /** Initialises and stores some atoms for the display.
  51. @tags{GUI}
  52. */
  53. struct Atoms
  54. {
  55. enum ProtocolItems
  56. {
  57. TAKE_FOCUS = 0,
  58. DELETE_WINDOW = 1,
  59. PING = 2
  60. };
  61. Atoms() = default;
  62. explicit Atoms (::Display*);
  63. static Atom getIfExists (::Display*, const char* name);
  64. static Atom getCreating (::Display*, const char* name);
  65. static String getName (::Display*, Atom);
  66. static bool isMimeTypeFile (::Display*, Atom);
  67. static constexpr unsigned long DndVersion = 3;
  68. Atom protocols, protocolList[3], changeState, state, userTime, activeWin, pid, windowType, windowState, windowStateHidden,
  69. XdndAware, XdndEnter, XdndLeave, XdndPosition, XdndStatus, XdndDrop, XdndFinished, XdndSelection,
  70. XdndTypeList, XdndActionList, XdndActionDescription, XdndActionCopy, XdndActionPrivate,
  71. XembedMsgType, XembedInfo, allowedActions[5], allowedMimeTypes[4], utf8String, clipboard, targets;
  72. };
  73. //==============================================================================
  74. /** Represents a setting according to the XSETTINGS specification.
  75. @tags{GUI}
  76. */
  77. struct XSetting
  78. {
  79. enum class Type
  80. {
  81. integer,
  82. string,
  83. colour,
  84. invalid
  85. };
  86. XSetting() = default;
  87. XSetting (const String& n, int v) : name (n), type (Type::integer), integerValue (v) {}
  88. XSetting (const String& n, const String& v) : name (n), type (Type::string), stringValue (v) {}
  89. XSetting (const String& n, const Colour& v) : name (n), type (Type::colour), colourValue (v) {}
  90. bool isValid() const noexcept { return type != Type::invalid; }
  91. String name;
  92. Type type = Type::invalid;
  93. int integerValue = -1;
  94. String stringValue;
  95. Colour colourValue;
  96. };
  97. /** Parses and stores the X11 settings for a display according to the XSETTINGS
  98. specification.
  99. @tags{GUI}
  100. */
  101. class XSettings
  102. {
  103. public:
  104. static std::unique_ptr<XSettings> createXSettings (::Display*);
  105. //==============================================================================
  106. void update();
  107. ::Window getSettingsWindow() const noexcept { return settingsWindow; }
  108. XSetting getSetting (const String& settingName) const;
  109. //==============================================================================
  110. struct Listener
  111. {
  112. virtual ~Listener() = default;
  113. virtual void settingChanged (const XSetting& settingThatHasChanged) = 0;
  114. };
  115. void addListener (Listener* listenerToAdd) { listeners.add (listenerToAdd); }
  116. void removeListener (Listener* listenerToRemove) { listeners.remove (listenerToRemove); }
  117. private:
  118. ::Display* display = nullptr;
  119. ::Window settingsWindow = None;
  120. Atom settingsAtom;
  121. int lastUpdateSerial = -1;
  122. std::unordered_map<String, XSetting> settings;
  123. ListenerList<Listener> listeners;
  124. XSettings (::Display*, Atom, ::Window);
  125. //==============================================================================
  126. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XSettings)
  127. };
  128. }
  129. //==============================================================================
  130. class LinuxComponentPeer;
  131. class XWindowSystem : public DeletedAtShutdown
  132. {
  133. public:
  134. //==============================================================================
  135. ::Window createWindow (::Window parentWindow, LinuxComponentPeer*) const;
  136. void destroyWindow (::Window);
  137. void setTitle (::Window, const String&) const;
  138. void setIcon (::Window , const Image&) const;
  139. void setVisible (::Window, bool shouldBeVisible) const;
  140. void setBounds (::Window, Rectangle<int>, bool fullScreen) const;
  141. void updateConstraints (::Window) const;
  142. ComponentPeer::OptionalBorderSize getBorderSize (::Window) const;
  143. Rectangle<int> getWindowBounds (::Window, ::Window parentWindow);
  144. Point<int> getPhysicalParentScreenPosition() const;
  145. bool contains (::Window, Point<int> localPos) const;
  146. void setMinimised (::Window, bool shouldBeMinimised) const;
  147. bool isMinimised (::Window) const;
  148. void setMaximised (::Window, bool shouldBeMinimised) const;
  149. void toFront (::Window, bool makeActive) const;
  150. void toBehind (::Window, ::Window otherWindow) const;
  151. bool isFocused (::Window) const;
  152. bool grabFocus (::Window) const;
  153. bool canUseSemiTransparentWindows() const;
  154. bool canUseARGBImages() const;
  155. bool isDarkModeActive() const;
  156. int getNumPaintsPendingForWindow (::Window);
  157. void processPendingPaintsForWindow (::Window);
  158. void addPendingPaintForWindow (::Window);
  159. void removePendingPaintForWindow (::Window);
  160. Image createImage (bool isSemiTransparentWindow, int width, int height, bool argb) const;
  161. void blitToWindow (::Window, Image, Rectangle<int> destinationRect, Rectangle<int> totalRect) const;
  162. void setScreenSaverEnabled (bool enabled) const;
  163. Point<float> getCurrentMousePosition() const;
  164. void setMousePosition (Point<float> pos) const;
  165. Cursor createCustomMouseCursorInfo (const Image&, Point<int> hotspot) const;
  166. void deleteMouseCursor (Cursor cursorHandle) const;
  167. Cursor createStandardMouseCursor (MouseCursor::StandardCursorType) const;
  168. void showCursor (::Window, Cursor cursorHandle) const;
  169. bool isKeyCurrentlyDown (int keyCode) const;
  170. ModifierKeys getNativeRealtimeModifiers() const;
  171. Array<Displays::Display> findDisplays (float masterScale) const;
  172. ::Window createKeyProxy (::Window);
  173. void deleteKeyProxy (::Window) const;
  174. bool externalDragFileInit (LinuxComponentPeer*, const StringArray& files, bool canMove, std::function<void()>&& callback) const;
  175. bool externalDragTextInit (LinuxComponentPeer*, const String& text, std::function<void()>&& callback) const;
  176. void copyTextToClipboard (const String&);
  177. String getTextFromClipboard() const;
  178. String getLocalClipboardContent() const noexcept { return localClipboardContent; }
  179. ::Display* getDisplay() const noexcept { return display; }
  180. const XWindowSystemUtilities::Atoms& getAtoms() const noexcept { return atoms; }
  181. XWindowSystemUtilities::XSettings* getXSettings() const noexcept { return xSettings.get(); }
  182. bool isX11Available() const noexcept { return xIsAvailable; }
  183. void startHostManagedResize (::Window window,
  184. Point<int> mouseDown,
  185. ResizableBorderComponent::Zone zone);
  186. static String getWindowScalingFactorSettingName() { return "Gdk/WindowScalingFactor"; }
  187. static String getThemeNameSettingName() { return "Net/ThemeName"; }
  188. //==============================================================================
  189. void handleWindowMessage (LinuxComponentPeer*, XEvent&) const;
  190. bool isParentWindowOf (::Window, ::Window possibleChild) const;
  191. //==============================================================================
  192. JUCE_DECLARE_SINGLETON (XWindowSystem, false)
  193. private:
  194. XWindowSystem();
  195. ~XWindowSystem();
  196. //==============================================================================
  197. struct VisualAndDepth
  198. {
  199. Visual* visual;
  200. int depth;
  201. };
  202. struct DisplayVisuals
  203. {
  204. explicit DisplayVisuals (::Display*);
  205. VisualAndDepth getBestVisualForWindow (bool) const;
  206. bool isValid() const noexcept;
  207. Visual* visual16Bit = nullptr;
  208. Visual* visual24Bit = nullptr;
  209. Visual* visual32Bit = nullptr;
  210. };
  211. bool initialiseXDisplay();
  212. void destroyXDisplay();
  213. //==============================================================================
  214. ::Window getFocusWindow (::Window) const;
  215. bool isFrontWindow (::Window) const;
  216. //==============================================================================
  217. void xchangeProperty (::Window, Atom, Atom, int, const void*, int) const;
  218. void removeWindowDecorations (::Window) const;
  219. void addWindowButtons (::Window, int) const;
  220. void setWindowType (::Window, int) const;
  221. void initialisePointerMap();
  222. void deleteIconPixmaps (::Window) const;
  223. void updateModifierMappings() const;
  224. long getUserTime (::Window) const;
  225. bool isHidden (Window) const;
  226. bool isIconic (Window) const;
  227. void initialiseXSettings();
  228. //==============================================================================
  229. void handleKeyPressEvent (LinuxComponentPeer*, XKeyEvent&) const;
  230. void handleKeyReleaseEvent (LinuxComponentPeer*, const XKeyEvent&) const;
  231. void handleWheelEvent (LinuxComponentPeer*, const XButtonPressedEvent&, float) const;
  232. void handleButtonPressEvent (LinuxComponentPeer*, const XButtonPressedEvent&, int) const;
  233. void handleButtonPressEvent (LinuxComponentPeer*, const XButtonPressedEvent&) const;
  234. void handleButtonReleaseEvent (LinuxComponentPeer*, const XButtonReleasedEvent&) const;
  235. void handleMotionNotifyEvent (LinuxComponentPeer*, const XPointerMovedEvent&) const;
  236. void handleEnterNotifyEvent (LinuxComponentPeer*, const XEnterWindowEvent&) const;
  237. void handleLeaveNotifyEvent (LinuxComponentPeer*, const XLeaveWindowEvent&) const;
  238. void handleFocusInEvent (LinuxComponentPeer*) const;
  239. void handleFocusOutEvent (LinuxComponentPeer*) const;
  240. void handleExposeEvent (LinuxComponentPeer*, XExposeEvent&) const;
  241. void handleConfigureNotifyEvent (LinuxComponentPeer*, XConfigureEvent&) const;
  242. void handleGravityNotify (LinuxComponentPeer*) const;
  243. void propertyNotifyEvent (LinuxComponentPeer*, const XPropertyEvent&) const;
  244. void handleMappingNotify (XMappingEvent&) const;
  245. void handleClientMessageEvent (LinuxComponentPeer*, XClientMessageEvent&, XEvent&) const;
  246. void handleXEmbedMessage (LinuxComponentPeer*, XClientMessageEvent&) const;
  247. void dismissBlockingModals (LinuxComponentPeer*) const;
  248. void dismissBlockingModals (LinuxComponentPeer*, const XConfigureEvent&) const;
  249. void updateConstraints (::Window, ComponentPeer&) const;
  250. ::Window findTopLevelWindowOf (::Window) const;
  251. static void windowMessageReceive (XEvent&);
  252. //==============================================================================
  253. bool xIsAvailable = false;
  254. XWindowSystemUtilities::Atoms atoms;
  255. ::Display* display = nullptr;
  256. std::unique_ptr<DisplayVisuals> displayVisuals;
  257. std::unique_ptr<XWindowSystemUtilities::XSettings> xSettings;
  258. #if JUCE_USE_XSHM
  259. std::map<::Window, int> shmPaintsPendingMap;
  260. #endif
  261. int shmCompletionEvent = 0;
  262. int pointerMap[5] = {};
  263. String localClipboardContent;
  264. Point<int> parentScreenPosition;
  265. //==============================================================================
  266. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XWindowSystem)
  267. };
  268. } // namespace juce