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.

191 lines
5.3KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. BEGIN_JUCE_NAMESPACE
  19. //==============================================================================
  20. class MouseCursor::SharedCursorHandle
  21. {
  22. public:
  23. explicit SharedCursorHandle (const MouseCursor::StandardCursorType type)
  24. : handle (createStandardMouseCursor (type)),
  25. refCount (1),
  26. standardType (type),
  27. isStandard (true)
  28. {
  29. }
  30. SharedCursorHandle (const Image& image, const int hotSpotX, const int hotSpotY)
  31. : handle (createMouseCursorFromImage (image, hotSpotX, hotSpotY)),
  32. refCount (1),
  33. standardType (MouseCursor::NormalCursor),
  34. isStandard (false)
  35. {
  36. }
  37. ~SharedCursorHandle()
  38. {
  39. deleteMouseCursor (handle, isStandard);
  40. }
  41. static SharedCursorHandle* createStandard (const MouseCursor::StandardCursorType type)
  42. {
  43. const SpinLock::ScopedLockType sl (lock);
  44. for (int i = 0; i < getCursors().size(); ++i)
  45. {
  46. SharedCursorHandle* const sc = getCursors().getUnchecked(i);
  47. if (sc->standardType == type)
  48. return sc->retain();
  49. }
  50. SharedCursorHandle* const sc = new SharedCursorHandle (type);
  51. getCursors().add (sc);
  52. return sc;
  53. }
  54. SharedCursorHandle* retain() noexcept
  55. {
  56. ++refCount;
  57. return this;
  58. }
  59. void release()
  60. {
  61. if (--refCount == 0)
  62. {
  63. if (isStandard)
  64. {
  65. const SpinLock::ScopedLockType sl (lock);
  66. getCursors().removeValue (this);
  67. }
  68. delete this;
  69. }
  70. }
  71. void* getHandle() const noexcept { return handle; }
  72. private:
  73. //==============================================================================
  74. void* const handle;
  75. Atomic <int> refCount;
  76. const MouseCursor::StandardCursorType standardType;
  77. const bool isStandard;
  78. static SpinLock lock;
  79. static Array <SharedCursorHandle*>& getCursors()
  80. {
  81. static Array <SharedCursorHandle*> cursors;
  82. return cursors;
  83. }
  84. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedCursorHandle);
  85. };
  86. SpinLock MouseCursor::SharedCursorHandle::lock;
  87. //==============================================================================
  88. MouseCursor::MouseCursor()
  89. : cursorHandle (nullptr)
  90. {
  91. }
  92. MouseCursor::MouseCursor (const StandardCursorType type)
  93. : cursorHandle (type != MouseCursor::NormalCursor ? SharedCursorHandle::createStandard (type) : 0)
  94. {
  95. }
  96. MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY)
  97. : cursorHandle (new SharedCursorHandle (image, hotSpotX, hotSpotY))
  98. {
  99. }
  100. MouseCursor::MouseCursor (const MouseCursor& other)
  101. : cursorHandle (other.cursorHandle == nullptr ? nullptr : other.cursorHandle->retain())
  102. {
  103. }
  104. MouseCursor::~MouseCursor()
  105. {
  106. if (cursorHandle != nullptr)
  107. cursorHandle->release();
  108. }
  109. MouseCursor& MouseCursor::operator= (const MouseCursor& other)
  110. {
  111. if (other.cursorHandle != nullptr)
  112. other.cursorHandle->retain();
  113. if (cursorHandle != nullptr)
  114. cursorHandle->release();
  115. cursorHandle = other.cursorHandle;
  116. return *this;
  117. }
  118. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  119. MouseCursor::MouseCursor (MouseCursor&& other) noexcept
  120. : cursorHandle (other.cursorHandle)
  121. {
  122. other.cursorHandle = nullptr;
  123. }
  124. MouseCursor& MouseCursor::operator= (MouseCursor&& other) noexcept
  125. {
  126. std::swap (cursorHandle, other.cursorHandle);
  127. return *this;
  128. }
  129. #endif
  130. bool MouseCursor::operator== (const MouseCursor& other) const noexcept
  131. {
  132. return getHandle() == other.getHandle();
  133. }
  134. bool MouseCursor::operator!= (const MouseCursor& other) const noexcept
  135. {
  136. return getHandle() != other.getHandle();
  137. }
  138. void* MouseCursor::getHandle() const noexcept
  139. {
  140. return cursorHandle != nullptr ? cursorHandle->getHandle() : nullptr;
  141. }
  142. void MouseCursor::showWaitCursor()
  143. {
  144. Desktop::getInstance().getMainMouseSource().showMouseCursor (MouseCursor::WaitCursor);
  145. }
  146. void MouseCursor::hideWaitCursor()
  147. {
  148. Desktop::getInstance().getMainMouseSource().revealCursor();
  149. }
  150. END_JUCE_NAMESPACE