comparison DPF-Prymula-audioplugins/dpf/dgl/src/pugl.cpp @ 3:84e66ea83026

DPF-Prymula-audioplugins-0.231015-2
author prymula <prymula76@outlook.com>
date Mon, 16 Oct 2023 21:53:34 +0200
parents
children
comparison
equal deleted inserted replaced
2:cf2cb71d31dd 3:84e66ea83026
1 /*
2 * DISTRHO Plugin Framework (DPF)
3 * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any purpose with
6 * or without fee is hereby granted, provided that the above copyright notice and this
7 * permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include "pugl.hpp"
18
19 // --------------------------------------------------------------------------------------------------------------------
20 // include base headers
21
22 #ifdef DGL_CAIRO
23 # include <cairo.h>
24 #endif
25 #ifdef DGL_OPENGL
26 # include "../OpenGL-include.hpp"
27 #endif
28 #ifdef DGL_VULKAN
29 # include <vulkan/vulkan_core.h>
30 #endif
31
32 /* we will include all header files used in pugl in their C++ friendly form, then pugl stuff in custom namespace */
33 #include <cassert>
34 #include <cmath>
35 #include <cstdlib>
36 #include <cstdio>
37 #include <cstring>
38 #include <ctime>
39
40 #if defined(DISTRHO_OS_HAIKU)
41 # include <Application.h>
42 # include <Window.h>
43 # ifdef DGL_OPENGL
44 # include <GL/gl.h>
45 # include <opengl/GLView.h>
46 # endif
47 #elif defined(DISTRHO_OS_MAC)
48 # import <Cocoa/Cocoa.h>
49 # include <dlfcn.h>
50 # include <mach/mach_time.h>
51 # ifdef DGL_CAIRO
52 # include <cairo-quartz.h>
53 # endif
54 # ifdef DGL_VULKAN
55 # import <QuartzCore/CAMetalLayer.h>
56 # include <vulkan/vulkan_macos.h>
57 # endif
58 #elif defined(DISTRHO_OS_WASM)
59 # include <emscripten/emscripten.h>
60 # include <emscripten/html5.h>
61 # ifdef DGL_OPENGL
62 # include <EGL/egl.h>
63 # endif
64 #elif defined(DISTRHO_OS_WINDOWS)
65 # include <wctype.h>
66 # include <winsock2.h>
67 # include <windows.h>
68 # include <windowsx.h>
69 # ifdef DGL_CAIRO
70 # include <cairo-win32.h>
71 # endif
72 # ifdef DGL_OPENGL
73 # include <GL/gl.h>
74 # endif
75 # ifdef DGL_VULKAN
76 # include <vulkan/vulkan.h>
77 # include <vulkan/vulkan_win32.h>
78 # endif
79 #elif defined(HAVE_X11)
80 # include <dlfcn.h>
81 # include <limits.h>
82 # include <unistd.h>
83 # include <sys/select.h>
84 // # include <sys/time.h>
85 # include <X11/X.h>
86 # include <X11/Xatom.h>
87 # include <X11/Xlib.h>
88 # include <X11/Xresource.h>
89 # include <X11/Xutil.h>
90 # include <X11/keysym.h>
91 # ifdef HAVE_XCURSOR
92 # include <X11/Xcursor/Xcursor.h>
93 // # include <X11/cursorfont.h>
94 # endif
95 # ifdef HAVE_XRANDR
96 # include <X11/extensions/Xrandr.h>
97 # endif
98 # ifdef HAVE_XSYNC
99 # include <X11/extensions/sync.h>
100 # include <X11/extensions/syncconst.h>
101 # endif
102 # ifdef DGL_CAIRO
103 # include <cairo-xlib.h>
104 # endif
105 # ifdef DGL_OPENGL
106 # include <GL/glx.h>
107 # endif
108 # ifdef DGL_VULKAN
109 # include <vulkan/vulkan_xlib.h>
110 # endif
111 #endif
112
113 #ifndef DGL_FILE_BROWSER_DISABLED
114 # define FILE_BROWSER_DIALOG_DGL_NAMESPACE
115 # define FILE_BROWSER_DIALOG_NAMESPACE DGL_NAMESPACE
116 # define DGL_FILE_BROWSER_DIALOG_HPP_INCLUDED
117 START_NAMESPACE_DGL
118 # include "../../distrho/extra/FileBrowserDialogImpl.hpp"
119 END_NAMESPACE_DGL
120 # include "../../distrho/extra/FileBrowserDialogImpl.cpp"
121 #endif
122
123 #ifndef DISTRHO_OS_MAC
124 START_NAMESPACE_DGL
125 #endif
126
127 // --------------------------------------------------------------------------------------------------------------------
128
129 #if defined(DISTRHO_OS_HAIKU)
130 # include "pugl-extra/haiku.cpp"
131 # include "pugl-extra/haiku_stub.cpp"
132 # ifdef DGL_OPENGL
133 # include "pugl-extra/haiku_gl.cpp"
134 # endif
135 #elif defined(DISTRHO_OS_MAC)
136 # ifndef DISTRHO_MACOS_NAMESPACE_MACRO
137 # define DISTRHO_MACOS_NAMESPACE_MACRO_HELPER(NS, SEP, INTERFACE) NS ## SEP ## INTERFACE
138 # define DISTRHO_MACOS_NAMESPACE_MACRO(NS, INTERFACE) DISTRHO_MACOS_NAMESPACE_MACRO_HELPER(NS, _, INTERFACE)
139 # define PuglCairoView DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglCairoView)
140 # define PuglOpenGLView DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglOpenGLView)
141 # define PuglStubView DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglStubView)
142 # define PuglVulkanView DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglVulkanView)
143 # define PuglWindow DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWindow)
144 # define PuglWindowDelegate DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWindowDelegate)
145 # define PuglWrapperView DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWrapperView)
146 # endif
147 # pragma clang diagnostic push
148 # pragma clang diagnostic ignored "-Wdeprecated-declarations"
149 # import "pugl-upstream/src/mac.m"
150 # import "pugl-upstream/src/mac_stub.m"
151 # ifdef DGL_CAIRO
152 # import "pugl-upstream/src/mac_cairo.m"
153 # endif
154 # ifdef DGL_OPENGL
155 # import "pugl-upstream/src/mac_gl.m"
156 # endif
157 # ifdef DGL_VULKAN
158 # import "pugl-upstream/src/mac_vulkan.m"
159 # endif
160 # pragma clang diagnostic pop
161 #elif defined(DISTRHO_OS_WASM)
162 # include "pugl-extra/wasm.c"
163 # include "pugl-extra/wasm_stub.c"
164 # ifdef DGL_OPENGL
165 # include "pugl-extra/wasm_gl.c"
166 # endif
167 #elif defined(DISTRHO_OS_WINDOWS)
168 # include "pugl-upstream/src/win.c"
169 # include "pugl-upstream/src/win_stub.c"
170 # ifdef DGL_CAIRO
171 # include "pugl-upstream/src/win_cairo.c"
172 # endif
173 # ifdef DGL_OPENGL
174 # include "pugl-upstream/src/win_gl.c"
175 # endif
176 # ifdef DGL_VULKAN
177 # include "pugl-upstream/src/win_vulkan.c"
178 # endif
179 #elif defined(HAVE_X11)
180 # include "pugl-upstream/src/x11.c"
181 # include "pugl-upstream/src/x11_stub.c"
182 # ifdef DGL_CAIRO
183 # include "pugl-upstream/src/x11_cairo.c"
184 # endif
185 # ifdef DGL_OPENGL
186 # include "pugl-upstream/src/x11_gl.c"
187 # endif
188 # ifdef DGL_VULKAN
189 # include "pugl-upstream/src/x11_vulkan.c"
190 # endif
191 #endif
192
193 #include "pugl-upstream/src/common.c"
194 #include "pugl-upstream/src/internal.c"
195
196 // --------------------------------------------------------------------------------------------------------------------
197 // DGL specific, expose backend enter
198
199 bool puglBackendEnter(PuglView* const view)
200 {
201 return view->backend->enter(view, nullptr) == PUGL_SUCCESS;
202 }
203
204 // --------------------------------------------------------------------------------------------------------------------
205 // DGL specific, expose backend leave
206
207 bool puglBackendLeave(PuglView* const view)
208 {
209 return view->backend->leave(view, nullptr) == PUGL_SUCCESS;
210 }
211
212 // --------------------------------------------------------------------------------------------------------------------
213 // DGL specific, assigns backend that matches current DGL build
214
215 void puglSetMatchingBackendForCurrentBuild(PuglView* const view)
216 {
217 #ifdef DGL_CAIRO
218 puglSetBackend(view, puglCairoBackend());
219 #endif
220 #ifdef DGL_OPENGL
221 puglSetBackend(view, puglGlBackend());
222 #endif
223 #ifdef DGL_VULKAN
224 puglSetBackend(view, puglVulkanBackend());
225 #endif
226
227 if (view->backend != nullptr)
228 {
229 #ifdef DGL_OPENGL
230 #if defined(DGL_USE_GLES2)
231 puglSetViewHint(view, PUGL_USE_COMPAT_PROFILE, PUGL_FALSE);
232 puglSetViewHint(view, PUGL_CONTEXT_VERSION_MAJOR, 2);
233 #elif defined(DGL_USE_OPENGL3)
234 puglSetViewHint(view, PUGL_USE_COMPAT_PROFILE, PUGL_FALSE);
235 puglSetViewHint(view, PUGL_CONTEXT_VERSION_MAJOR, 3);
236 #else
237 puglSetViewHint(view, PUGL_USE_COMPAT_PROFILE, PUGL_TRUE);
238 puglSetViewHint(view, PUGL_CONTEXT_VERSION_MAJOR, 2);
239 #endif
240 #endif
241 }
242 else
243 {
244 puglSetBackend(view, puglStubBackend());
245 }
246 }
247
248 // --------------------------------------------------------------------------------------------------------------------
249 // bring view window into the foreground, aka "raise" window
250
251 void puglRaiseWindow(PuglView* const view)
252 {
253 #if defined(DISTRHO_OS_HAIKU)
254 #elif defined(DISTRHO_OS_MAC)
255 if (NSWindow* const window = view->impl->window ? view->impl->window
256 : [view->impl->wrapperView window])
257 [window orderFrontRegardless];
258 #elif defined(DISTRHO_OS_WASM)
259 // nothing
260 #elif defined(DISTRHO_OS_WINDOWS)
261 SetForegroundWindow(view->impl->hwnd);
262 SetActiveWindow(view->impl->hwnd);
263 #elif defined(HAVE_X11)
264 XRaiseWindow(view->world->impl->display, view->impl->win);
265 #endif
266 }
267
268 // --------------------------------------------------------------------------------------------------------------------
269 // get scale factor from parent window if possible, fallback to puglGetScaleFactor
270
271 double puglGetScaleFactorFromParent(const PuglView* const view)
272 {
273 const PuglNativeView parent = view->parent ? view->parent : view->transientParent ? view->transientParent : 0;
274 #if defined(DISTRHO_OS_HAIKU)
275 // TODO
276 return 1.0;
277 #elif defined(DISTRHO_OS_MAC)
278 // some of these can return 0 as backingScaleFactor, pick the most relevant valid one
279 const NSWindow* possibleWindows[] = {
280 parent != 0 ? [(NSView*)parent window] : nullptr,
281 view->impl->window,
282 [view->impl->wrapperView window]
283 };
284 for (size_t i=0; i<ARRAY_SIZE(possibleWindows); ++i)
285 {
286 if (possibleWindows[i] == nullptr)
287 continue;
288 if (const double scaleFactor = [[possibleWindows[i] screen] backingScaleFactor])
289 return scaleFactor;
290 }
291 return [[NSScreen mainScreen] backingScaleFactor];
292 #elif defined(DISTRHO_OS_WINDOWS)
293 const HWND hwnd = parent != 0 ? (HWND)parent : view->impl->hwnd;
294 return puglWinGetViewScaleFactor(hwnd);
295 #else
296 return puglGetScaleFactor(view);
297 // unused
298 (void)parent;
299 #endif
300 }
301
302 // --------------------------------------------------------------------------------------------------------------------
303 // Combined puglSetSizeHint using PUGL_MIN_SIZE and PUGL_FIXED_ASPECT
304
305 PuglStatus puglSetGeometryConstraints(PuglView* const view, const uint width, const uint height, const bool aspect)
306 {
307 view->sizeHints[PUGL_MIN_SIZE].width = width;
308 view->sizeHints[PUGL_MIN_SIZE].height = height;
309
310 if (aspect)
311 {
312 view->sizeHints[PUGL_FIXED_ASPECT].width = width;
313 view->sizeHints[PUGL_FIXED_ASPECT].height = height;
314 }
315
316 #if defined(DISTRHO_OS_HAIKU)
317 #elif defined(DISTRHO_OS_MAC)
318 if (view->impl->window)
319 {
320 PuglStatus status;
321
322 if ((status = updateSizeHint(view, PUGL_MIN_SIZE)) != PUGL_SUCCESS)
323 return status;
324
325 if (aspect && (status = updateSizeHint(view, PUGL_FIXED_ASPECT)) != PUGL_SUCCESS)
326 return status;
327 }
328 #elif defined(DISTRHO_OS_WASM)
329 // nothing
330 #elif defined(DISTRHO_OS_WINDOWS)
331 // nothing
332 #elif defined(HAVE_X11)
333 if (const PuglStatus status = updateSizeHints(view))
334 return status;
335
336 XFlush(view->world->impl->display);
337 #endif
338
339 return PUGL_SUCCESS;
340 }
341
342 // --------------------------------------------------------------------------------------------------------------------
343 // set view as resizable (or not) during runtime
344
345 void puglSetResizable(PuglView* const view, const bool resizable)
346 {
347 puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE);
348
349 #if defined(DISTRHO_OS_HAIKU)
350 #elif defined(DISTRHO_OS_MAC)
351 if (PuglWindow* const window = view->impl->window)
352 {
353 const uint style = (NSClosableWindowMask | NSTitledWindowMask | NSMiniaturizableWindowMask)
354 | (resizable ? NSResizableWindowMask : 0x0);
355 [window setStyleMask:style];
356 }
357 // FIXME use [view setAutoresizingMask:NSViewNotSizable] ?
358 #elif defined(DISTRHO_OS_WASM)
359 // nothing
360 #elif defined(DISTRHO_OS_WINDOWS)
361 if (const HWND hwnd = view->impl->hwnd)
362 {
363 const uint winFlags = resizable ? GetWindowLong(hwnd, GWL_STYLE) | (WS_SIZEBOX | WS_MAXIMIZEBOX)
364 : GetWindowLong(hwnd, GWL_STYLE) & ~(WS_SIZEBOX | WS_MAXIMIZEBOX);
365 SetWindowLong(hwnd, GWL_STYLE, winFlags);
366 }
367 #elif defined(HAVE_X11)
368 updateSizeHints(view);
369 #endif
370 }
371
372 // --------------------------------------------------------------------------------------------------------------------
373 // set window size while also changing default
374
375 PuglStatus puglSetSizeAndDefault(PuglView* view, uint width, uint height)
376 {
377 if (width > INT16_MAX || height > INT16_MAX)
378 return PUGL_BAD_PARAMETER;
379
380 view->sizeHints[PUGL_DEFAULT_SIZE].width = view->frame.width = static_cast<PuglSpan>(width);
381 view->sizeHints[PUGL_DEFAULT_SIZE].height = view->frame.height = static_cast<PuglSpan>(height);
382
383 #if defined(DISTRHO_OS_HAIKU)
384 #elif defined(DISTRHO_OS_MAC)
385 // mostly matches upstream pugl, simplified
386 PuglInternals* const impl = view->impl;
387
388 const PuglRect frame = view->frame;
389 const NSRect framePx = rectToNsRect(frame);
390 const NSRect framePt = nsRectToPoints(view, framePx);
391
392 if (PuglWindow* const window = view->impl->window)
393 {
394 const NSRect screenPt = rectToScreen(viewScreen(view), framePt);
395 const NSRect winFrame = [window frameRectForContentRect:screenPt];
396 [window setFrame:winFrame display:NO];
397 }
398
399 const NSSize sizePx = NSMakeSize(frame.width, frame.height);
400 const NSSize sizePt = [impl->drawView convertSizeFromBacking:sizePx];
401 [impl->wrapperView setFrameSize:sizePt];
402 [impl->drawView setFrameSize:sizePt];
403 #elif defined(DISTRHO_OS_WASM)
404 d_stdout("className is %s", view->world->className);
405 emscripten_set_canvas_element_size(view->world->className, width, height);
406 #elif defined(DISTRHO_OS_WINDOWS)
407 // matches upstream pugl, except we re-enter context after resize
408 if (const HWND hwnd = view->impl->hwnd)
409 {
410 const RECT rect = adjustedWindowRect(view, view->frame.x, view->frame.y,
411 static_cast<long>(width), static_cast<long>(height));
412
413 if (!SetWindowPos(hwnd, HWND_TOP, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
414 SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE))
415 return PUGL_UNKNOWN_ERROR;
416
417 // make sure to return context back to ourselves
418 puglBackendEnter(view);
419 }
420 #elif defined(HAVE_X11)
421 // matches upstream pugl, all in one
422 if (const Window window = view->impl->win)
423 {
424 Display* const display = view->world->impl->display;
425
426 if (! XResizeWindow(display, window, width, height))
427 return PUGL_UNKNOWN_ERROR;
428
429 if (const PuglStatus status = updateSizeHints(view))
430 return status;
431
432 XFlush(display);
433 }
434 #endif
435
436 return PUGL_SUCCESS;
437 }
438
439 // --------------------------------------------------------------------------------------------------------------------
440 // DGL specific, build-specific drawing prepare
441
442 void puglOnDisplayPrepare(PuglView*)
443 {
444 #ifdef DGL_OPENGL
445 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
446 #ifndef DGL_USE_OPENGL3
447 glLoadIdentity();
448 #endif
449 #endif
450 }
451
452 // --------------------------------------------------------------------------------------------------------------------
453 // DGL specific, build-specific fallback resize
454
455 void puglFallbackOnResize(PuglView* const view)
456 {
457 #ifdef DGL_OPENGL
458 glEnable(GL_BLEND);
459 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
460 #ifdef DGL_USE_OPENGL3
461 glViewport(0, 0, static_cast<GLsizei>(view->frame.width), static_cast<GLsizei>(view->frame.height));
462 #else
463 glMatrixMode(GL_PROJECTION);
464 glLoadIdentity();
465 glOrtho(0.0, static_cast<GLdouble>(view->frame.width), static_cast<GLdouble>(view->frame.height), 0.0, 0.0, 1.0);
466 glViewport(0, 0, static_cast<GLsizei>(view->frame.width), static_cast<GLsizei>(view->frame.height));
467 glMatrixMode(GL_MODELVIEW);
468 glLoadIdentity();
469 #endif
470 #else
471 return;
472 // unused
473 (void)view;
474 #endif
475 }
476
477 // --------------------------------------------------------------------------------------------------------------------
478
479 #if defined(DISTRHO_OS_HAIKU)
480
481 // --------------------------------------------------------------------------------------------------------------------
482
483 #elif defined(DISTRHO_OS_MAC)
484
485 // --------------------------------------------------------------------------------------------------------------------
486 // macOS specific, add another view's window as child
487
488 PuglStatus
489 puglMacOSAddChildWindow(PuglView* const view, PuglView* const child)
490 {
491 if (NSWindow* const viewWindow = view->impl->window ? view->impl->window
492 : [view->impl->wrapperView window])
493 {
494 if (NSWindow* const childWindow = child->impl->window ? child->impl->window
495 : [child->impl->wrapperView window])
496 {
497 [viewWindow addChildWindow:childWindow ordered:NSWindowAbove];
498 return PUGL_SUCCESS;
499 }
500 }
501
502 return PUGL_FAILURE;
503 }
504
505 // --------------------------------------------------------------------------------------------------------------------
506 // macOS specific, remove another view's window as child
507
508 PuglStatus
509 puglMacOSRemoveChildWindow(PuglView* const view, PuglView* const child)
510 {
511 if (NSWindow* const viewWindow = view->impl->window ? view->impl->window
512 : [view->impl->wrapperView window])
513 {
514 if (NSWindow* const childWindow = child->impl->window ? child->impl->window
515 : [child->impl->wrapperView window])
516 {
517 [viewWindow removeChildWindow:childWindow];
518 return PUGL_SUCCESS;
519 }
520 }
521
522 return PUGL_FAILURE;
523 }
524
525 // --------------------------------------------------------------------------------------------------------------------
526 // macOS specific, center view based on parent coordinates (if there is one)
527
528 void puglMacOSShowCentered(PuglView* const view)
529 {
530 if (puglShow(view) != PUGL_SUCCESS)
531 return;
532
533 if (view->transientParent != 0)
534 {
535 NSWindow* const transientWindow = [(NSView*)view->transientParent window];
536 DISTRHO_SAFE_ASSERT_RETURN(transientWindow != nullptr,);
537
538 const NSRect ourFrame = [view->impl->window frame];
539 const NSRect transientFrame = [transientWindow frame];
540
541 const int x = transientFrame.origin.x + (transientFrame.size.width - ourFrame.size.width) / 2;
542 const int y = transientFrame.origin.y + (transientFrame.size.height - ourFrame.size.height) / 2;
543
544 [view->impl->window setFrameTopLeftPoint:NSMakePoint(x, y)];
545 }
546 else
547 {
548 [view->impl->window center];
549 }
550 }
551
552 // --------------------------------------------------------------------------------------------------------------------
553
554 #elif defined(DISTRHO_OS_WINDOWS)
555
556 // --------------------------------------------------------------------------------------------------------------------
557 // win32 specific, call ShowWindow with SW_RESTORE
558
559 void puglWin32RestoreWindow(PuglView* const view)
560 {
561 PuglInternals* impl = view->impl;
562 DISTRHO_SAFE_ASSERT_RETURN(impl->hwnd != nullptr,);
563
564 ShowWindow(impl->hwnd, SW_RESTORE);
565 SetFocus(impl->hwnd);
566 }
567
568 // --------------------------------------------------------------------------------------------------------------------
569 // win32 specific, center view based on parent coordinates (if there is one)
570
571 void puglWin32ShowCentered(PuglView* const view)
572 {
573 PuglInternals* impl = view->impl;
574 DISTRHO_SAFE_ASSERT_RETURN(impl->hwnd != nullptr,);
575
576 RECT rectChild, rectParent;
577
578 if (view->transientParent != 0 &&
579 GetWindowRect(impl->hwnd, &rectChild) &&
580 GetWindowRect((HWND)view->transientParent, &rectParent))
581 {
582 SetWindowPos(impl->hwnd, HWND_TOP,
583 rectParent.left + (rectParent.right-rectParent.left)/2 - (rectChild.right-rectChild.left)/2,
584 rectParent.top + (rectParent.bottom-rectParent.top)/2 - (rectChild.bottom-rectChild.top)/2,
585 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE);
586 }
587 else
588 {
589 #ifdef DGL_WINDOWS_ICON_ID
590 WNDCLASSEX wClass;
591 std::memset(&wClass, 0, sizeof(wClass));
592
593 const HINSTANCE hInstance = GetModuleHandle(nullptr);
594
595 if (GetClassInfoEx(hInstance, view->world->className, &wClass))
596 wClass.hIcon = LoadIcon(nullptr, MAKEINTRESOURCE(DGL_WINDOWS_ICON_ID));
597
598 SetClassLongPtr(impl->hwnd, GCLP_HICON, (LONG_PTR) LoadIcon(hInstance, MAKEINTRESOURCE(DGL_WINDOWS_ICON_ID)));
599 #endif
600
601 MONITORINFO mInfo;
602 std::memset(&mInfo, 0, sizeof(mInfo));
603 mInfo.cbSize = sizeof(mInfo);
604
605 if (GetMonitorInfo(MonitorFromWindow(impl->hwnd, MONITOR_DEFAULTTOPRIMARY), &mInfo))
606 SetWindowPos(impl->hwnd, HWND_TOP,
607 mInfo.rcWork.left + (mInfo.rcWork.right - mInfo.rcWork.left - view->frame.width) / 2,
608 mInfo.rcWork.top + (mInfo.rcWork.bottom - mInfo.rcWork.top - view->frame.height) / 2,
609 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE);
610 else
611 ShowWindow(impl->hwnd, SW_NORMAL);
612 }
613
614 SetFocus(impl->hwnd);
615 }
616
617 // --------------------------------------------------------------------------------------------------------------------
618
619 #elif defined(DISTRHO_OS_WASM)
620
621 // nothing here yet
622
623 // --------------------------------------------------------------------------------------------------------------------
624
625 #elif defined(HAVE_X11)
626
627 PuglStatus puglX11UpdateWithoutExposures(PuglWorld* const world)
628 {
629 const bool wasDispatchingEvents = world->impl->dispatchingEvents;
630 world->impl->dispatchingEvents = true;
631 PuglStatus st = PUGL_SUCCESS;
632
633 const double startTime = puglGetTime(world);
634 const double endTime = startTime + 0.03;
635
636 for (double t = startTime; !st && t < endTime; t = puglGetTime(world))
637 {
638 pollX11Socket(world, endTime - t);
639 st = dispatchX11Events(world);
640 }
641
642 world->impl->dispatchingEvents = wasDispatchingEvents;
643 return st;
644 }
645
646 // --------------------------------------------------------------------------------------------------------------------
647 // X11 specific, set dialog window type and pid hints
648
649 void puglX11SetWindowTypeAndPID(const PuglView* const view, const bool isStandalone)
650 {
651 const PuglInternals* const impl = view->impl;
652 Display* const display = view->world->impl->display;
653
654 const pid_t pid = getpid();
655 const Atom _nwp = XInternAtom(display, "_NET_WM_PID", False);
656 XChangeProperty(display, impl->win, _nwp, XA_CARDINAL, 32, PropModeReplace, (const uchar*)&pid, 1);
657
658 const Atom _wt = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
659
660 Atom _wts[2];
661 int numAtoms = 0;
662
663 if (! isStandalone)
664 _wts[numAtoms++] = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
665
666 _wts[numAtoms++] = XInternAtom(display, "_NET_WM_WINDOW_TYPE_NORMAL", False);
667
668 XChangeProperty(display, impl->win, _wt, XA_ATOM, 32, PropModeReplace, (const uchar*)&_wts, numAtoms);
669 }
670
671 // --------------------------------------------------------------------------------------------------------------------
672
673 #endif // HAVE_X11
674
675 #ifndef DISTRHO_OS_MAC
676 END_NAMESPACE_DGL
677 #endif