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.

390 lines
9.9KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-9 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. // (This file gets included by juce_win32_NativeCode.cpp, rather than being
  19. // compiled on its own).
  20. #if JUCE_INCLUDED_FILE
  21. #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
  22. extern HWND juce_messageWindowHandle;
  23. #endif
  24. //==============================================================================
  25. CriticalSection::CriticalSection() throw()
  26. {
  27. // (just to check the MS haven't changed this structure and broken things...)
  28. #if _MSC_VER >= 1400
  29. static_jassert (sizeof (CRITICAL_SECTION) <= sizeof (internal));
  30. #else
  31. static_jassert (sizeof (CRITICAL_SECTION) <= 24);
  32. #endif
  33. InitializeCriticalSection ((CRITICAL_SECTION*) internal);
  34. }
  35. CriticalSection::~CriticalSection() throw()
  36. {
  37. DeleteCriticalSection ((CRITICAL_SECTION*) internal);
  38. }
  39. void CriticalSection::enter() const throw()
  40. {
  41. EnterCriticalSection ((CRITICAL_SECTION*) internal);
  42. }
  43. bool CriticalSection::tryEnter() const throw()
  44. {
  45. return TryEnterCriticalSection ((CRITICAL_SECTION*) internal) != FALSE;
  46. }
  47. void CriticalSection::exit() const throw()
  48. {
  49. LeaveCriticalSection ((CRITICAL_SECTION*) internal);
  50. }
  51. //==============================================================================
  52. WaitableEvent::WaitableEvent() throw()
  53. : internal (CreateEvent (0, FALSE, FALSE, 0))
  54. {
  55. }
  56. WaitableEvent::~WaitableEvent() throw()
  57. {
  58. CloseHandle (internal);
  59. }
  60. bool WaitableEvent::wait (const int timeOutMillisecs) const throw()
  61. {
  62. return WaitForSingleObject (internal, timeOutMillisecs) == WAIT_OBJECT_0;
  63. }
  64. void WaitableEvent::signal() const throw()
  65. {
  66. SetEvent (internal);
  67. }
  68. void WaitableEvent::reset() const throw()
  69. {
  70. ResetEvent (internal);
  71. }
  72. //==============================================================================
  73. void JUCE_API juce_threadEntryPoint (void*);
  74. static unsigned int __stdcall threadEntryProc (void* userData) throw()
  75. {
  76. #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
  77. AttachThreadInput (GetWindowThreadProcessId (juce_messageWindowHandle, 0),
  78. GetCurrentThreadId(), TRUE);
  79. #endif
  80. juce_threadEntryPoint (userData);
  81. _endthreadex (0);
  82. return 0;
  83. }
  84. void juce_CloseThreadHandle (void* handle) throw()
  85. {
  86. CloseHandle ((HANDLE) handle);
  87. }
  88. void* juce_createThread (void* userData) throw()
  89. {
  90. unsigned int threadId;
  91. return (void*) _beginthreadex (0, 0,
  92. &threadEntryProc,
  93. userData,
  94. 0, &threadId);
  95. }
  96. void juce_killThread (void* handle) throw()
  97. {
  98. if (handle != 0)
  99. {
  100. #ifdef JUCE_DEBUG
  101. OutputDebugString (_T("** Warning - Forced thread termination **\n"));
  102. #endif
  103. TerminateThread (handle, 0);
  104. }
  105. }
  106. void juce_setCurrentThreadName (const String& name) throw()
  107. {
  108. #if defined (JUCE_DEBUG) && JUCE_MSVC
  109. struct
  110. {
  111. DWORD dwType;
  112. LPCSTR szName;
  113. DWORD dwThreadID;
  114. DWORD dwFlags;
  115. } info;
  116. info.dwType = 0x1000;
  117. info.szName = name;
  118. info.dwThreadID = GetCurrentThreadId();
  119. info.dwFlags = 0;
  120. #define MS_VC_EXCEPTION 0x406d1388
  121. __try
  122. {
  123. RaiseException (MS_VC_EXCEPTION, 0, sizeof (info) / sizeof (ULONG_PTR), (ULONG_PTR*) &info);
  124. }
  125. __except (EXCEPTION_CONTINUE_EXECUTION)
  126. {}
  127. #else
  128. (void) name;
  129. #endif
  130. }
  131. Thread::ThreadID Thread::getCurrentThreadId() throw()
  132. {
  133. return (ThreadID) (pointer_sized_int) GetCurrentThreadId();
  134. }
  135. // priority 1 to 10 where 5=normal, 1=low
  136. bool juce_setThreadPriority (void* threadHandle, int priority) throw()
  137. {
  138. int pri = THREAD_PRIORITY_TIME_CRITICAL;
  139. if (priority < 1)
  140. pri = THREAD_PRIORITY_IDLE;
  141. else if (priority < 2)
  142. pri = THREAD_PRIORITY_LOWEST;
  143. else if (priority < 5)
  144. pri = THREAD_PRIORITY_BELOW_NORMAL;
  145. else if (priority < 7)
  146. pri = THREAD_PRIORITY_NORMAL;
  147. else if (priority < 9)
  148. pri = THREAD_PRIORITY_ABOVE_NORMAL;
  149. else if (priority < 10)
  150. pri = THREAD_PRIORITY_HIGHEST;
  151. if (threadHandle == 0)
  152. threadHandle = GetCurrentThread();
  153. return SetThreadPriority (threadHandle, pri) != FALSE;
  154. }
  155. void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) throw()
  156. {
  157. SetThreadAffinityMask (GetCurrentThread(), affinityMask);
  158. }
  159. static HANDLE sleepEvent = 0;
  160. void juce_initialiseThreadEvents() throw()
  161. {
  162. if (sleepEvent == 0)
  163. #ifdef JUCE_DEBUG
  164. sleepEvent = CreateEvent (0, 0, 0, _T("Juce Sleep Event"));
  165. #else
  166. sleepEvent = CreateEvent (0, 0, 0, 0);
  167. #endif
  168. }
  169. void Thread::yield() throw()
  170. {
  171. Sleep (0);
  172. }
  173. void JUCE_CALLTYPE Thread::sleep (const int millisecs) throw()
  174. {
  175. if (millisecs >= 10)
  176. {
  177. Sleep (millisecs);
  178. }
  179. else
  180. {
  181. jassert (sleepEvent != 0);
  182. // unlike Sleep() this is guaranteed to return to the current thread after
  183. // the time expires, so we'll use this for short waits, which are more likely
  184. // to need to be accurate
  185. WaitForSingleObject (sleepEvent, millisecs);
  186. }
  187. }
  188. //==============================================================================
  189. static int lastProcessPriority = -1;
  190. // called by WindowDriver because Windows does wierd things to process priority
  191. // when you swap apps, and this forces an update when the app is brought to the front.
  192. void juce_repeatLastProcessPriority() throw()
  193. {
  194. if (lastProcessPriority >= 0) // (avoid changing this if it's not been explicitly set by the app..)
  195. {
  196. DWORD p;
  197. switch (lastProcessPriority)
  198. {
  199. case Process::LowPriority:
  200. p = IDLE_PRIORITY_CLASS;
  201. break;
  202. case Process::NormalPriority:
  203. p = NORMAL_PRIORITY_CLASS;
  204. break;
  205. case Process::HighPriority:
  206. p = HIGH_PRIORITY_CLASS;
  207. break;
  208. case Process::RealtimePriority:
  209. p = REALTIME_PRIORITY_CLASS;
  210. break;
  211. default:
  212. jassertfalse // bad priority value
  213. return;
  214. }
  215. SetPriorityClass (GetCurrentProcess(), p);
  216. }
  217. }
  218. void Process::setPriority (ProcessPriority prior)
  219. {
  220. if (lastProcessPriority != (int) prior)
  221. {
  222. lastProcessPriority = (int) prior;
  223. juce_repeatLastProcessPriority();
  224. }
  225. }
  226. bool JUCE_API JUCE_CALLTYPE juce_isRunningUnderDebugger() throw()
  227. {
  228. return IsDebuggerPresent() != FALSE;
  229. }
  230. bool JUCE_CALLTYPE Process::isRunningUnderDebugger() throw()
  231. {
  232. return juce_isRunningUnderDebugger();
  233. }
  234. //==============================================================================
  235. void Process::raisePrivilege()
  236. {
  237. jassertfalse // xxx not implemented
  238. }
  239. void Process::lowerPrivilege()
  240. {
  241. jassertfalse // xxx not implemented
  242. }
  243. void Process::terminate()
  244. {
  245. #if defined (JUCE_DEBUG) && JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS
  246. _CrtDumpMemoryLeaks();
  247. #endif
  248. // bullet in the head in case there's a problem shutting down..
  249. ExitProcess (0);
  250. }
  251. //==============================================================================
  252. void* PlatformUtilities::loadDynamicLibrary (const String& name)
  253. {
  254. void* result = 0;
  255. JUCE_TRY
  256. {
  257. result = (void*) LoadLibrary (name);
  258. }
  259. JUCE_CATCH_ALL
  260. return result;
  261. }
  262. void PlatformUtilities::freeDynamicLibrary (void* h)
  263. {
  264. JUCE_TRY
  265. {
  266. if (h != 0)
  267. FreeLibrary ((HMODULE) h);
  268. }
  269. JUCE_CATCH_ALL
  270. }
  271. void* PlatformUtilities::getProcedureEntryPoint (void* h, const String& name)
  272. {
  273. return (h != 0) ? (void*) GetProcAddress ((HMODULE) h, name)
  274. : 0;
  275. }
  276. //==============================================================================
  277. InterProcessLock::InterProcessLock (const String& name_) throw()
  278. : internal (0),
  279. name (name_),
  280. reentrancyLevel (0)
  281. {
  282. }
  283. InterProcessLock::~InterProcessLock() throw()
  284. {
  285. exit();
  286. }
  287. bool InterProcessLock::enter (const int timeOutMillisecs) throw()
  288. {
  289. if (reentrancyLevel++ == 0)
  290. {
  291. internal = CreateMutex (0, TRUE, name);
  292. if (internal != 0 && GetLastError() == ERROR_ALREADY_EXISTS)
  293. {
  294. if (timeOutMillisecs == 0
  295. || WaitForSingleObject (internal, (timeOutMillisecs < 0) ? INFINITE : timeOutMillisecs)
  296. == WAIT_TIMEOUT)
  297. {
  298. ReleaseMutex (internal);
  299. CloseHandle (internal);
  300. internal = 0;
  301. }
  302. }
  303. }
  304. return (internal != 0);
  305. }
  306. void InterProcessLock::exit() throw()
  307. {
  308. if (--reentrancyLevel == 0 && internal != 0)
  309. {
  310. ReleaseMutex (internal);
  311. CloseHandle (internal);
  312. internal = 0;
  313. }
  314. }
  315. #endif