comparison DPF-Prymula-audioplugins/dpf/dgl/src/pugl-extra/haiku.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 // Copyright 2012-2022 David Robillard <d@drobilla.net>
2 // Copyright 2021-2022 Filipe Coelho <falktx@falktx.com>
3 // SPDX-License-Identifier: ISC
4
5 #include "haiku.h"
6
7 #include "../pugl-upstream/src/internal.h"
8
9 class PuglHaikuView : public BView
10 {
11 PuglView* const view;
12
13 public:
14 PuglHaikuView(PuglView* const v)
15 : BView(NULL, B_FULL_UPDATE_ON_RESIZE|B_FRAME_EVENTS|B_NAVIGABLE|B_INPUT_METHOD_AWARE),
16 view(v) {}
17
18 protected:
19 void GetPreferredSize(float* width, float* height) override
20 {
21 d_stdout("%s %i", __func__, __LINE__);
22 if (width != nullptr)
23 *width = view->frame.width;
24 if (height != nullptr)
25 *height = view->frame.height;
26 d_stdout("%s %i", __func__, __LINE__);
27 }
28 };
29
30 class PuglHaikuWindow : public BWindow
31 {
32 PuglView* const view;
33
34 public:
35 PuglHaikuWindow(PuglView* const v)
36 : BWindow(BRect(1.0f), "DPF-Window", B_TITLED_WINDOW, 0x0),
37 view(v) {}
38
39 // protected:
40 // bool QuitRequested() override
41 // {
42 // d_stdout("%s %i", __func__, __LINE__);
43 // if (puglView->closeFunc) {
44 // puglView->closeFunc(puglView);
45 // puglView->redisplay = false;
46 // }
47 // needsQuit = false;
48 // d_stdout("%s %i", __func__, __LINE__);
49 // return true;
50 // }
51 };
52
53 BApplication* s_app = NULL;
54
55 PuglWorldInternals*
56 puglInitWorldInternals(const PuglWorldType type, const PuglWorldFlags flags)
57 {
58 if (!s_app) {
59 status_t status;
60 s_app = new BApplication("application/x-vnd.pugl-application", &status);
61
62 if (status != B_OK) {
63 delete s_app;
64 return NULL;
65 }
66 }
67
68 PuglWorldInternals* impl =
69 (PuglWorldInternals*)calloc(1, sizeof(PuglWorldInternals));
70
71 impl->app = s_app;
72 return impl;
73 }
74
75 void*
76 puglGetNativeWorld(PuglWorld* const world)
77 {
78 return world->impl->app;
79 }
80
81 PuglInternals*
82 puglInitViewInternals(PuglWorld* const world)
83 {
84 PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));
85
86 return impl;
87 }
88
89 PuglStatus
90 puglRealize(PuglView* const view)
91 {
92 PuglInternals* const impl = view->impl;
93 PuglStatus st = PUGL_SUCCESS;
94
95 // Ensure that we're unrealized and that a reasonable backend has been set
96 if (impl->view) {
97 return PUGL_FAILURE;
98 }
99 if (!view->backend || !view->backend->configure) {
100 return PUGL_BAD_BACKEND;
101 }
102
103 // Set the size to the default if it has not already been set
104 if (view->frame.width <= 0.0 || view->frame.height <= 0.0) {
105 const PuglViewSize defaultSize = view->sizeHints[PUGL_DEFAULT_SIZE];
106 if (!defaultSize.width || !defaultSize.height) {
107 return PUGL_BAD_CONFIGURATION;
108 }
109
110 view->frame.width = defaultSize.width;
111 view->frame.height = defaultSize.height;
112 }
113
114 // Center top-level windows if a position has not been set
115 if (!view->parent && !view->frame.x && !view->frame.y) {
116 // TODO
117 }
118
119 if (!view->parent) {
120 impl->window = new PuglHaikuWindow(view);
121 impl->window->Lock();
122 }
123
124 impl->view = new PuglHaikuView(view);
125
126 if (view->parent) {
127 BView* const pview = (BView*)view->parent;
128 pview->AddChild(impl->view);
129 } else {
130 impl->window->AddChild(impl->view);
131 }
132
133 // Configure and create the backend
134 if ((st = view->backend->configure(view)) || (st = view->backend->create(view))) {
135 view->backend->destroy(view);
136 return st;
137 }
138
139 if (view->title) {
140 puglSetWindowTitle(view, view->title);
141 }
142
143 if (view->transientParent) {
144 puglSetTransientParent(view, view->transientParent);
145 }
146
147 puglDispatchSimpleEvent(view, PUGL_CREATE);
148
149 if (impl->window) {
150 impl->window->Unlock();
151 }
152
153 return PUGL_SUCCESS;
154 }
155
156 PuglStatus
157 puglShow(PuglView* const view)
158 {
159 PuglInternals* const impl = view->impl;
160 if (impl->window) {
161 impl->window->Show();
162 } else {
163 impl->view->Show();
164 }
165 return PUGL_SUCCESS;
166 }
167
168 PuglStatus
169 puglHide(PuglView* const view)
170 {
171 PuglInternals* const impl = view->impl;
172 if (impl->window) {
173 impl->window->Hide();
174 } else {
175 impl->view->Hide();
176 }
177 return PUGL_SUCCESS;
178 }
179
180 void
181 puglFreeViewInternals(PuglView* const view)
182 {
183 if (view && view->impl) {
184 PuglInternals* const impl = view->impl;
185 if (view->backend) {
186 view->backend->destroy(view);
187 }
188 if (impl->view) {
189 if (impl->window) {
190 impl->window->RemoveChild(impl->view);
191 }
192 delete impl->view;
193 delete impl->window;
194 }
195 free(impl);
196 }
197 }
198
199 void
200 puglFreeWorldInternals(PuglWorld* const world)
201 {
202 // if (world->impl->app != nullptr && world->impl->app->CountWindows() == 0) {
203 // delete world->impl->app;
204 // s_app = NULL;
205 // }
206 free(world->impl);
207 }
208
209 PuglStatus
210 puglGrabFocus(PuglView*)
211 {
212 return PUGL_UNSUPPORTED;
213 }
214
215 double
216 puglGetScaleFactor(const PuglView* const view)
217 {
218 return 1.0;
219 }
220
221 double
222 puglGetTime(const PuglWorld* const world)
223 {
224 struct timespec ts;
225 clock_gettime(CLOCK_MONOTONIC, &ts);
226 return ((double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0) -
227 world->startTime;
228 }
229
230 PuglStatus
231 puglUpdate(PuglWorld* const world, const double timeout)
232 {
233 return PUGL_UNSUPPORTED;
234 }
235
236 PuglStatus
237 puglPostRedisplay(PuglView* const view)
238 {
239 return PUGL_UNSUPPORTED;
240 }
241
242 PuglStatus
243 puglPostRedisplayRect(PuglView* const view, const PuglRect rect)
244 {
245 return PUGL_UNSUPPORTED;
246 }
247
248 PuglNativeView
249 puglGetNativeView(PuglView* const view)
250 {
251 return 0;
252 }
253
254 PuglStatus
255 puglSetWindowTitle(PuglView* const view, const char* const title)
256 {
257 puglSetString(&view->title, title);
258 return PUGL_UNSUPPORTED;
259 }
260
261 PuglStatus
262 puglSetSizeHint(PuglView* const view,
263 const PuglSizeHint hint,
264 const PuglSpan width,
265 const PuglSpan height)
266 {
267 view->sizeHints[hint].width = width;
268 view->sizeHints[hint].height = height;
269 return PUGL_SUCCESS;
270 }
271
272 PuglStatus
273 puglStartTimer(PuglView* const view, const uintptr_t id, const double timeout)
274 {
275 return PUGL_UNSUPPORTED;
276 }
277
278 PuglStatus
279 puglStopTimer(PuglView* const view, const uintptr_t id)
280 {
281 return PUGL_UNSUPPORTED;
282 }
283
284 PuglStatus
285 puglPaste(PuglView* const view)
286 {
287 return PUGL_UNSUPPORTED;
288 }
289
290 PuglStatus
291 puglAcceptOffer(PuglView* const view,
292 const PuglDataOfferEvent* const offer,
293 const uint32_t typeIndex)
294 {
295 return PUGL_UNSUPPORTED;
296 }
297
298 uint32_t
299 puglGetNumClipboardTypes(const PuglView* const view)
300 {
301 return 0u;
302 }
303
304 const char*
305 puglGetClipboardType(const PuglView* const view, const uint32_t typeIndex)
306 {
307 return NULL;
308 }
309
310 const void*
311 puglGetClipboard(PuglView* const view,
312 const uint32_t typeIndex,
313 size_t* const len)
314 {
315 return NULL;
316 }
317
318 PuglStatus
319 puglSetClipboard(PuglView* const view,
320 const char* const type,
321 const void* const data,
322 const size_t len)
323 {
324 return PUGL_FAILURE;
325 }
326
327 PuglStatus
328 puglSetCursor(PuglView* const view, const PuglCursor cursor)
329 {
330 return PUGL_FAILURE;
331 }
332
333 PuglStatus
334 puglSetTransientParent(PuglView* const view, const PuglNativeView parent)
335 {
336 return PUGL_FAILURE;
337 }
338
339 PuglStatus
340 puglSetPosition(PuglView* const view, const int x, const int y)
341 {
342 return PUGL_FAILURE;
343 }
344
345 #if 0
346 PuglStatus
347 puglGrabFocus(PuglView* view)
348 {
349 view->impl->bView->MakeFocus(true);
350 return PUGL_SUCCESS;
351 }
352
353 // extras follow
354
355 void
356 puglRaiseWindow(PuglView* view)
357 {
358 }
359
360 void
361 puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height)
362 {
363 bView->ResizeTo(width, height);
364
365 if (bWindow != nullptr && bWindow->LockLooper())
366 {
367 bWindow->MoveTo(50, 50);
368 bWindow->ResizeTo(width, height);
369
370 if (! forced)
371 bWindow->Flush();
372
373 bWindow->UnlockLooper();
374 }
375 // TODO resizable
376 }
377
378 void setVisible(const bool yesNo)
379 {
380 if (bWindow != nullptr)
381 {
382 if (bWindow->LockLooper())
383 {
384 if (yesNo)
385 bWindow->Show();
386 else
387 bWindow->Hide();
388
389 // TODO use flush?
390 bWindow->Sync();
391 bWindow->UnlockLooper();
392 }
393 }
394 else
395 {
396 if (yesNo)
397 bView->Show();
398 else
399 bView->Hide();
400 }
401 }
402 #endif