iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
ReaperExt_include_in_plug_src.h
1
2#ifndef NO_IGRAPHICS
3#define BUNDLE_ID ""
4#define APP_GROUP_ID ""
5#include "IGraphics_include_in_plug_src.h"
6#endif
7
8#define REAPERAPI_IMPLEMENT
9void (*AttachWindowTopmostButton)(HWND hwnd);
10#include "reaper_plugin_functions.h"
11
12#include "resource.h"
13#include <vector>
14#include <map>
15#include <deque>
16#include <cstring>
17
18REAPER_PLUGIN_HINSTANCE gHINSTANCE;
19HWND gParent;
20HWND gHWND = NULL;
21std::unique_ptr<PLUG_CLASS_NAME> gPlug;
22RECT gPrevBounds;
23int gErrorCount = 0;
24
25#ifndef NO_IGRAPHICS
33static int TextEntryAcceleratorProc(MSG* msg, accelerator_register_t*)
34{
35 if (!msg || !gPlug || !gHWND)
36 return 0;
37
38 IGraphics* graphics = gPlug->GetUI();
39 if (!graphics || !graphics->GetControlInTextEntry())
40 return 0;
41
42 const HWND focusedWindow = GetFocus();
43 if (!focusedWindow || (focusedWindow != gHWND && !IsChild(gHWND, focusedWindow)))
44 return 0;
45
46#ifdef OS_WIN
47 if (msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSKEYUP)
48 return -20;
49#endif
50
51 return -1;
52}
53
54// REAPER retains this pointer for the lifetime of the extension.
55accelerator_register_t gTextEntryAccelerator = {
56 TextEntryAcceleratorProc,
57 true,
58 nullptr
59};
60#endif
61
64{
65 int* pToggle = nullptr;
66 gaccel_register_t accel = {{0,0,0}, ""};
67 std::function<void()> func;
68 bool addMenuItem = false;
69 const char* contextMenuId = nullptr; // REAPER context menu to add this action to, if any
70 const char* menuLabel = nullptr; // label used in menus, defaults to the action name
71};
72
73// std::deque (not std::vector) so element addresses stay stable: REAPER keeps the
74// raw &gActions.back().accel pointer we register, which a vector realloc would dangle.
75std::deque<ReaperAction> gActions;
76
77// Persistent registration record for per-project state (see "projectconfig").
78// Must outlive registration, so it lives at file scope.
79project_config_extension_t gProjectConfig = {
80 ReaperExtBase::ProcessExtensionLine,
81 ReaperExtBase::SaveExtensionConfig,
82 ReaperExtBase::BeginLoadProjectState,
83 nullptr
84};
85
86//TODO: don't #include cpp here
87#include "ReaperExtBase.cpp"
88
89// super nasty looking macro here but allows importing functions from Reaper with simple looking code
90#define IMPAPI(x) if (!((*((void **)&(x)) = (void*) pRec->GetFunc(#x)))) gErrorCount++;
91
92#pragma mark - ENTRY POINT
93extern "C"
94{
95 REAPER_PLUGIN_DLL_EXPORT int REAPER_PLUGIN_ENTRYPOINT(REAPER_PLUGIN_HINSTANCE hInstance, reaper_plugin_info_t* pRec)
96 {
97 gHINSTANCE = hInstance;
98
99 if (pRec)
100 {
101 if (pRec->caller_version != REAPER_PLUGIN_VERSION || !pRec->GetFunc)
102 return 0;
103
104 gPlug = std::make_unique<PLUG_CLASS_NAME>(pRec);
105
106 // initialize API function pointers from Reaper
107 IMPAPI(Main_OnCommand);
108 IMPAPI(GetResourcePath);
109 IMPAPI(AddExtensionsMainMenu);
110 IMPAPI(AttachWindowTopmostButton);
111 IMPAPI(ShowConsoleMsg);
112 IMPAPI(DockWindowAdd);
113 IMPAPI(DockWindowAddEx);
114 IMPAPI(DockWindowRemove);
115 IMPAPI(DockWindowActivate);
116 IMPAPI(DockIsChildOfDock);
117 IMPAPI(get_ini_file);
118 IMPAPI(EnsureNotCompletelyOffscreen);
119
120 if (gErrorCount > 0)
121 return 0;
122
123 pRec->Register("hookcommand", (void*) ReaperExtBase::HookCommandProc);
124 pRec->Register("toggleaction", (void*) ReaperExtBase::ToggleActionCallback);
125 pRec->Register("hookcustommenu", (void*) ReaperExtBase::MenuHook);
126 pRec->Register("hookpostcommand", (void*) ReaperExtBase::PostCommandProc);
127 pRec->Register("projectconfig", (void*) &gProjectConfig);
128#ifndef NO_IGRAPHICS
129 pRec->Register("accelerator", (void*) &gTextEntryAccelerator);
130#endif
131
132 // Creates the Extensions main menu if it doesn't exist yet. It is populated from
133 // ReaperExtBase::MenuHook(), which REAPER calls with menuidstr "Main extensions".
134 AddExtensionsMainMenu();
135
136 gParent = pRec->hwnd_main;
137
138 return 1;
139 }
140 else
141 {
142 return 0;
143 }
144 }
145};
146
147
148#ifndef OS_WIN
149#define SWELL_DLG_FLAGS_AUTOGEN SWELL_DLG_WS_FLIPPED|SWELL_DLG_WS_RESIZABLE
150#include "swell-dlggen.h"
151#include "main.rc_mac_dlg"
152#undef BEGIN
153#undef END
154#include "swell-menugen.h"
155#include "main.rc_mac_menu"
156float iplug::GetScaleForHWND(HWND hWnd)
157{
158 return 1.f;
159}
160#else
161
162UINT(WINAPI* __GetDpiForWindow)(HWND);
163
164float GetScaleForHWND(HWND hWnd)
165{
166 if (!__GetDpiForWindow)
167 {
168 HINSTANCE h = LoadLibraryA("user32.dll");
169 if (h) *(void**)&__GetDpiForWindow = GetProcAddress(h, "GetDpiForWindow");
170
171 if (!__GetDpiForWindow)
172 return 1;
173 }
174
175 int dpi = __GetDpiForWindow(hWnd);
176
177 if (dpi != USER_DEFAULT_SCREEN_DPI)
178 return static_cast<float>(dpi) / USER_DEFAULT_SCREEN_DPI;
179
180 return 1;
181}
182
183#endif
The lowest level base class of an IGraphics context.
Definition: IGraphics.h:86
IControl * GetControlInTextEntry()
Definition: IGraphics.h:1148
Helper struct for registering Reaper Actions.