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.

344 lines
13KB

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