iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IPlugAPP_main.cpp
1/*
2 ==============================================================================
3
4 This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5
6 See LICENSE.txt for more info.
7
8 ==============================================================================
9*/
10
11#include <memory>
12#include "wdltypes.h"
13#include "wdlstring.h"
14
15#include "IPlugPlatform.h"
16#include "IPlugAPP_host.h"
17
18#include "config.h"
19#include "resource.h"
20
21using namespace iplug;
22
23#pragma mark - WINDOWS
24#if defined OS_WIN
25#include <windows.h>
26#include <commctrl.h>
27
28extern WDL_DLGRET MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
29
30HWND gHWND;
31extern HINSTANCE gHINSTANCE;
32UINT gScrollMessage;
33
34int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nShowCmd)
35{
36 try
37 {
38#ifndef APP_ALLOW_MULTIPLE_INSTANCES
39 HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, BUNDLE_NAME); // BUNDLE_NAME used because it won't have spaces in it
40
41 if (!hMutex)
42 hMutex = CreateMutex(0, 0, BUNDLE_NAME);
43 else
44 {
45 HWND hWnd = FindWindow(0, BUNDLE_NAME);
46 SetForegroundWindow(hWnd);
47 return 0;
48 }
49#endif
50 gHINSTANCE = hInstance;
51
52 InitCommonControls();
53 gScrollMessage = RegisterWindowMessage("MSWHEEL_ROLLMSG");
54
55 IPlugAPPHost* pAppHost = IPlugAPPHost::Create();
56 pAppHost->Init();
57 pAppHost->TryToChangeAudio();
58
59 HACCEL hAccel = LoadAccelerators(gHINSTANCE, MAKEINTRESOURCE(IDR_ACCELERATOR1));
60
61 static UINT(WINAPI *__SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
62
63 if (!__SetProcessDpiAwarenessContext)
64 {
65 HINSTANCE h = LoadLibrary("user32.dll");
66 if (h) *(void **)&__SetProcessDpiAwarenessContext = GetProcAddress(h, "SetProcessDpiAwarenessContext");
67 if (!__SetProcessDpiAwarenessContext)
68 *(void **)&__SetProcessDpiAwarenessContext = (void*)(INT_PTR)1;
69 }
70 if ((UINT_PTR)__SetProcessDpiAwarenessContext > (UINT_PTR)1)
71 {
72 __SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
73 }
74
75 CreateDialog(gHINSTANCE, MAKEINTRESOURCE(IDD_DIALOG_MAIN), GetDesktopWindow(), IPlugAPPHost::MainDlgProc);
76
77#if !defined _DEBUG || defined NO_IGRAPHICS
78 HMENU menu = GetMenu(gHWND);
79 RemoveMenu(menu, 1, MF_BYPOSITION);
80 DrawMenuBar(gHWND);
81#endif
82
83 for (;;)
84 {
85 MSG msg= {0,};
86 int vvv = GetMessage(&msg, NULL, 0, 0);
87
88 if (!vvv)
89 break;
90
91 if (vvv < 0)
92 {
93 Sleep(10);
94 continue;
95 }
96
97 if (!msg.hwnd)
98 {
99 DispatchMessage(&msg);
100 continue;
101 }
102
103 if (gHWND && (TranslateAccelerator(gHWND, hAccel, &msg) || IsDialogMessage(gHWND, &msg)))
104 continue;
105
106 // default processing for other dialogs
107 HWND hWndParent = NULL;
108 HWND temphwnd = msg.hwnd;
109
110 do
111 {
112 if (GetClassLong(temphwnd, GCW_ATOM) == (INT)32770)
113 {
114 hWndParent = temphwnd;
115 if (!(GetWindowLong(temphwnd, GWL_STYLE) & WS_CHILD))
116 break; // not a child, exit
117 }
118 }
119 while (temphwnd = GetParent(temphwnd));
120
121 if (hWndParent && IsDialogMessage(hWndParent,&msg))
122 continue;
123
124 TranslateMessage(&msg);
125 DispatchMessage(&msg);
126 }
127
128 // in case gHWND didnt get destroyed -- this corresponds to SWELLAPP_DESTROY roughly
129 if (gHWND)
130 DestroyWindow(gHWND);
131
132#ifndef APP_ALLOW_MULTIPLE_INSTANCES
133 ReleaseMutex(hMutex);
134#endif
135 }
136 catch(std::exception e)
137 {
138 DBGMSG("Exception: %s", e.what());
139 return 1;
140 }
141 return 0;
142}
143#pragma mark - MAC
144#elif defined(OS_MAC)
145#import <Cocoa/Cocoa.h>
146#include "IPlugSWELL.h"
147#include "IPlugPaths.h"
148
149HWND gHWND;
150extern HMENU SWELL_app_stocksysmenu;
151
152int main(int argc, char *argv[])
153{
154#if APP_COPY_AUV3
155 //if invoked with an argument registerauv3 use plug-in kit to explicitly register auv3 app extension (doesn't happen from debugger)
156 if (std::string_view(argv[2]) == "registerauv3")
157 {
158 WDL_String appexPath;
159 appexPath.SetFormatted(1024, "pluginkit -a %s%s%s.appex", argv[0], "/../../Plugins/", appexPath.get_filepart());
160 if (system(appexPath.Get()) > -1)
161 NSLog(@"Registered audiounit app extension\n");
162 else
163 NSLog(@"Failed to register audiounit app extension\n");
164 }
165#endif
166
167 if (AppIsSandboxed())
168 DBGMSG("App is sandboxed, file system access etc restricted!\n");
169
170 return NSApplicationMain(argc, (const char **) argv);
171}
172
173INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2)
174{
175 IPlugAPPHost* pAppHost = nullptr;
176
177 switch (msg)
178 {
179 case SWELLAPP_ONLOAD:
180 {
181 pAppHost = IPlugAPPHost::Create();
182 pAppHost->Init();
183 pAppHost->TryToChangeAudio();
184 break;
185 }
186 case SWELLAPP_LOADED:
187 {
188 pAppHost = IPlugAPPHost::sInstance.get();
189
190 HMENU menu = SWELL_GetCurrentMenu();
191
192 if (menu)
193 {
194 // work on a new menu
195 menu = SWELL_DuplicateMenu(menu);
196 HMENU src = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MENU1));
197
198 for (int x = 0; x < GetMenuItemCount(src)-1; x++)
199 {
200 HMENU sm = GetSubMenu(src,x);
201
202 if (sm)
203 {
204 char str[1024];
205 MENUITEMINFO mii = {sizeof(mii), MIIM_TYPE};
206 mii.dwTypeData = str;
207 mii.cch = sizeof(str);
208 str[0] = 0;
209 GetMenuItemInfo(src, x, TRUE, &mii);
210 MENUITEMINFO mi= {sizeof(mi), MIIM_STATE|MIIM_SUBMENU|MIIM_TYPE,MFT_STRING, 0, 0, SWELL_DuplicateMenu(sm), NULL, NULL, 0, str};
211 InsertMenuItem(menu, x+1, TRUE, &mi);
212 }
213 }
214 }
215
216 if (menu)
217 {
218 HMENU sm = GetSubMenu(menu, 1);
219 DeleteMenu(sm, ID_QUIT, MF_BYCOMMAND); // remove QUIT from our file menu, since it is in the system menu on OSX
220 DeleteMenu(sm, ID_PREFERENCES, MF_BYCOMMAND); // remove PREFERENCES from the file menu, since it is in the system menu on OSX
221
222 // remove any trailing separators
223 int a = GetMenuItemCount(sm);
224
225 while (a > 0 && GetMenuItemID(sm, a-1) == 0)
226 DeleteMenu(sm, --a, MF_BYPOSITION);
227
228 DeleteMenu(menu, 1, MF_BYPOSITION); // delete file menu
229 }
230#if !defined _DEBUG || defined NO_IGRAPHICS
231 if (menu)
232 {
233 HMENU sm = GetSubMenu(menu, 1);
234 DeleteMenu(sm, ID_LIVE_EDIT, MF_BYCOMMAND);
235 DeleteMenu(sm, ID_SHOW_DRAWN, MF_BYCOMMAND);
236 DeleteMenu(sm, ID_SHOW_FPS, MF_BYCOMMAND);
237
238 // remove any trailing separators
239 int a = GetMenuItemCount(sm);
240
241 while (a > 0 && GetMenuItemID(sm, a-1) == 0)
242 DeleteMenu(sm, --a, MF_BYPOSITION);
243
244 DeleteMenu(menu, 1, MF_BYPOSITION); // delete debug menu
245 }
246#else
247 SetMenuItemModifier(menu, ID_LIVE_EDIT, MF_BYCOMMAND, 'E', FCONTROL);
248 SetMenuItemModifier(menu, ID_SHOW_DRAWN, MF_BYCOMMAND, 'D', FCONTROL);
249 SetMenuItemModifier(menu, ID_SHOW_BOUNDS, MF_BYCOMMAND, 'B', FCONTROL);
250 SetMenuItemModifier(menu, ID_SHOW_FPS, MF_BYCOMMAND, 'F', FCONTROL);
251#endif
252
253 HWND hwnd = CreateDialog(gHINST, MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL, IPlugAPPHost::MainDlgProc);
254
255 if (menu)
256 {
257 SetMenu(hwnd, menu); // set the menu for the dialog to our menu (on Windows that menu is set from the .rc, but on SWELL
258 SWELL_SetDefaultModalWindowMenu(menu); // other windows will get the stock (bundle) menus
259 }
260
261 break;
262 }
263 case SWELLAPP_ONCOMMAND:
264 // this is to catch commands coming from the system menu etc
265 if (gHWND && (parm1&0xffff))
266 SendMessage(gHWND, WM_COMMAND, parm1 & 0xffff, 0);
267 break;
268 case SWELLAPP_DESTROY:
269 if (gHWND)
270 DestroyWindow(gHWND);
271 break;
272 case SWELLAPP_PROCESSMESSAGE:
273 MSG* pMSG = (MSG*) parm1;
274 NSView* pContentView = (NSView*) pMSG->hwnd;
275 NSEvent* pEvent = (NSEvent*) parm2;
276 int etype = (int) [pEvent type];
277
278 bool textField = [pContentView isKindOfClass:[NSText class]];
279
280 if (!textField && etype == NSKeyDown)
281 {
282 int flag, code = SWELL_MacKeyToWindowsKey(pEvent, &flag);
283
284 if (!(flag&~FVIRTKEY) && (code == VK_RETURN || code == VK_ESCAPE))
285 {
286 [pContentView keyDown: pEvent];
287 return 1;
288 }
289 }
290 break;
291 }
292 return 0;
293}
294
295#define CBS_HASSTRINGS 0
296#define SWELL_DLG_SCALE_AUTOGEN 1
297#define SET_IDD_DIALOG_PREF_SCALE 1.5
298#if PLUG_HOST_RESIZE
299#define SWELL_DLG_FLAGS_AUTOGEN SWELL_DLG_WS_FLIPPED|SWELL_DLG_WS_RESIZABLE
300#endif
301#include "swell-dlggen.h"
302#include "resources/main.rc_mac_dlg"
303#include "swell-menugen.h"
304#include "resources/main.rc_mac_menu"
305
306#pragma mark - LINUX
307#elif defined(OS_LINUX)
308//#include <IPlugSWELL.h>
309//#include "swell-internal.h" // fixes problem with HWND forward decl
310//
311//HWND gHWND;
312//UINT gScrollMessage;
313//extern HMENU SWELL_app_stocksysmenu;
314//
315//int main(int argc, char **argv)
316//{
317// SWELL_initargs(&argc, &argv);
318// SWELL_Internal_PostMessage_Init();
319// SWELL_ExtendedAPI("APPNAME", (void*) "IGraphics Test");
320//
321// HMENU menu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MENU1));
322// CreateDialog(gHINSTANCE, MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL, MainDlgProc);
323// SetMenu(gHWND, menu);
324//
325// while (!gHWND->m_hashaddestroy)
326// {
327// SWELL_RunMessageLoop();
328// Sleep(10);
329// };
330//
331// if (gHWND)
332// DestroyWindow(gHWND);
333//
334// return 0;
335//}
336//
337//INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2)
338//{
339// switch (msg)
340// {
341// case SWELLAPP_ONLOAD:
342// break;
343// case SWELLAPP_LOADED:
344// {
345// HMENU menu = SWELL_GetCurrentMenu();
346//
347// if (menu)
348// {
349// // work on a new menu
350// menu = SWELL_DuplicateMenu(menu);
351// HMENU src = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MENU1));
352//
353// for (auto x = 0; x < GetMenuItemCount(src)-1; x++)
354// {
355// HMENU sm = GetSubMenu(src,x);
356// if (sm)
357// {
358// char str[1024];
359// MENUITEMINFO mii = {sizeof(mii), MIIM_TYPE};
360// mii.dwTypeData = str;
361// mii.cch = sizeof(str);
362// str[0] = 0;
363// GetMenuItemInfo(src, x, TRUE, &mii);
364// MENUITEMINFO mi= {sizeof(mi), MIIM_STATE|MIIM_SUBMENU|MIIM_TYPE,MFT_STRING, 0, 0, SWELL_DuplicateMenu(sm), NULL, NULL, 0, str};
365// InsertMenuItem(menu, x+1, TRUE, &mi);
366// }
367// }
368// }
369//
370// if (menu)
371// {
372// HMENU sm = GetSubMenu(menu, 1);
373// DeleteMenu(sm, ID_QUIT, MF_BYCOMMAND); // remove QUIT from our file menu, since it is in the system menu on OSX
374// DeleteMenu(sm, ID_PREFERENCES, MF_BYCOMMAND); // remove PREFERENCES from the file menu, since it is in the system menu on OSX
375//
376// // remove any trailing separators
377// int a = GetMenuItemCount(sm);
378//
379// while (a > 0 && GetMenuItemID(sm, a-1) == 0)
380// DeleteMenu(sm, --a, MF_BYPOSITION);
381//
382// DeleteMenu(menu, 1, MF_BYPOSITION); // delete file menu
383// }
384//
385// // if we want to set any default modifiers for items in the menus, we can use:
386// // SetMenuItemModifier(menu,commandID,MF_BYCOMMAND,'A',FCONTROL) etc.
387//
388// HWND hwnd = CreateDialog(gHINST,MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL, MainDlgProc);
389//
390// if (menu)
391// {
392// SetMenu(hwnd, menu); // set the menu for the dialog to our menu (on Windows that menu is set from the .rc, but on SWELL
393// SWELL_SetDefaultModalWindowMenu(menu); // other windows will get the stock (bundle) menus
394// }
395//
396// break;
397// }
398// case SWELLAPP_ONCOMMAND:
399// // this is to catch commands coming from the system menu etc
400// if (gHWND && (parm1&0xffff))
401// SendMessage(gHWND, WM_COMMAND, parm1 & 0xffff, 0);
402// break;
403// case SWELLAPP_DESTROY:
404// if (gHWND)
405// DestroyWindow(gHWND);
406// break;
407// case SWELLAPP_PROCESSMESSAGE: // can hook keyboard input here
408// // parm1 = (MSG*), should we want it -- look in swell.h to see what the return values refer to
409// break;
410// }
411// return 0;
412//}
413//
414//#define CBS_HASSTRINGS 0
415//#define SWELL_DLG_SCALE_AUTOGEN 1
416//#define SET_IDD_DIALOG_PREF_SCALE 1.5
417//#include "swell-dlggen.h"
418//#include "resources/main.rc_mac_dlg"
419//#include "swell-menugen.h"
420//#include "resources/main.rc_mac_menu"
421#endif
Common paths useful for plug-ins.
Include to get consistently named preprocessor macros for different platforms and logging functionali...
A class that hosts an IPlug as a standalone app and provides Audio/Midi I/O.
Definition: IPlugAPP_host.h:83