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.

186 lines
5.2KB

  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. class MouseCursor::SharedCursorHandle
  19. {
  20. public:
  21. explicit SharedCursorHandle (const MouseCursor::StandardCursorType type)
  22. : handle (createStandardMouseCursor (type)),
  23. refCount (1),
  24. standardType (type),
  25. isStandard (true)
  26. {
  27. }
  28. SharedCursorHandle (const Image& image, const int hotSpotX, const int hotSpotY)
  29. : handle (createMouseCursorFromImage (image, hotSpotX, hotSpotY)),
  30. refCount (1),
  31. standardType (MouseCursor::NormalCursor),
  32. isStandard (false)
  33. {
  34. }
  35. ~SharedCursorHandle()
  36. {
  37. deleteMouseCursor (handle, isStandard);
  38. }
  39. static SharedCursorHandle* createStandard (const MouseCursor::StandardCursorType type)
  40. {
  41. const SpinLock::ScopedLockType sl (lock);
  42. for (int i = 0; i < getCursors().size(); ++i)
  43. {
  44. SharedCursorHandle* const sc = getCursors().getUnchecked(i);
  45. if (sc->standardType == type)
  46. return sc->retain();
  47. }
  48. SharedCursorHandle* const sc = new SharedCursorHandle (type);
  49. getCursors().add (sc);
  50. return sc;
  51. }
  52. SharedCursorHandle* retain() noexcept
  53. {
  54. ++refCount;
  55. return this;
  56. }
  57. void release()
  58. {
  59. if (--refCount == 0)
  60. {
  61. if (isStandard)
  62. {
  63. const SpinLock::ScopedLockType sl (lock);
  64. getCursors().removeFirstMatchingValue (this);
  65. }
  66. delete this;
  67. }
  68. }
  69. void* getHandle() const noexcept { return handle; }
  70. private:
  71. //==============================================================================
  72. void* const handle;
  73. Atomic <int> refCount;
  74. const MouseCursor::StandardCursorType standardType;
  75. const bool isStandard;
  76. static SpinLock lock;
  77. static Array <SharedCursorHandle*>& getCursors()
  78. {
  79. static Array <SharedCursorHandle*> cursors;
  80. return cursors;
  81. }
  82. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedCursorHandle);
  83. };
  84. SpinLock MouseCursor::SharedCursorHandle::lock;
  85. //==============================================================================
  86. MouseCursor::MouseCursor()
  87. : cursorHandle (nullptr)
  88. {
  89. }
  90. MouseCursor::MouseCursor (const StandardCursorType type)
  91. : cursorHandle (type != MouseCursor::NormalCursor ? SharedCursorHandle::createStandard (type) : 0)
  92. {
  93. }
  94. MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY)
  95. : cursorHandle (new SharedCursorHandle (image, hotSpotX, hotSpotY))
  96. {
  97. }
  98. MouseCursor::MouseCursor (const MouseCursor& other)
  99. : cursorHandle (other.cursorHandle == nullptr ? nullptr : other.cursorHandle->retain())
  100. {
  101. }
  102. MouseCursor::~MouseCursor()
  103. {
  104. if (cursorHandle != nullptr)
  105. cursorHandle->release();
  106. }
  107. MouseCursor& MouseCursor::operator= (const MouseCursor& other)
  108. {
  109. if (other.cursorHandle != nullptr)
  110. other.cursorHandle->retain();
  111. if (cursorHandle != nullptr)
  112. cursorHandle->release();
  113. cursorHandle = other.cursorHandle;
  114. return *this;
  115. }
  116. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  117. MouseCursor::MouseCursor (MouseCursor&& other) noexcept
  118. : cursorHandle (other.cursorHandle)
  119. {
  120. other.cursorHandle = nullptr;
  121. }
  122. MouseCursor& MouseCursor::operator= (MouseCursor&& other) noexcept
  123. {
  124. std::swap (cursorHandle, other.cursorHandle);
  125. return *this;
  126. }
  127. #endif
  128. bool MouseCursor::operator== (const MouseCursor& other) const noexcept
  129. {
  130. return getHandle() == other.getHandle();
  131. }
  132. bool MouseCursor::operator!= (const MouseCursor& other) const noexcept
  133. {
  134. return getHandle() != other.getHandle();
  135. }
  136. void* MouseCursor::getHandle() const noexcept
  137. {
  138. return cursorHandle != nullptr ? cursorHandle->getHandle() : nullptr;
  139. }
  140. void MouseCursor::showWaitCursor()
  141. {
  142. Desktop::getInstance().getMainMouseSource().showMouseCursor (MouseCursor::WaitCursor);
  143. }
  144. void MouseCursor::hideWaitCursor()
  145. {
  146. Desktop::getInstance().getMainMouseSource().revealCursor();
  147. }