fe1aec5925
A code-ownership proof (window class procedure's module, via the pure window_origin) plus REAPER's FX-surface token routes a plugin editor to OLE; FX chrome keeps the instrument drop. The OLE loop re-asks the law each turn, so passing a plugin editor stays reversible.
49 lines
1.8 KiB
C++
49 lines
1.8 KiB
C++
// window_origin — pure implementation. See window_origin.h.
|
|
|
|
#include "core/ui/window_origin.h"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace reasampler::ui {
|
|
|
|
namespace {
|
|
|
|
// Case-folded (ASCII only — Windows' own directory names are ASCII), separator-unified, with the
|
|
// "\\?\" long-path prefix GetModuleFileName may report dropped, so the same directory compares
|
|
// equal however each API chose to spell it.
|
|
std::string normalizePath(const std::string& p) {
|
|
std::string s = p.rfind("\\\\?\\", 0) == 0 ? p.substr(4) : p;
|
|
for (char& c : s) {
|
|
if (c == '/') c = '\\';
|
|
else if (c >= 'A' && c <= 'Z') c = static_cast<char>(c - 'A' + 'a');
|
|
}
|
|
while (!s.empty() && s.back() == '\\') s.pop_back();
|
|
return s;
|
|
}
|
|
|
|
// Directory containment, not string prefix: C:\Windows must not claim C:\WindowsApps.
|
|
bool isBeneath(const std::string& path, const std::string& dir) {
|
|
const std::string p = normalizePath(path);
|
|
const std::string d = normalizePath(dir);
|
|
return !d.empty() && p.size() > d.size() && p.compare(0, d.size(), d) == 0 &&
|
|
p[d.size()] == '\\';
|
|
}
|
|
|
|
} // namespace
|
|
|
|
WindowCode classifyWindowCode(const WindowFacts& facts, const std::string& systemRoot) {
|
|
// Another process's procedure address means nothing in ours; the process boundary is itself
|
|
// the proof. Inside an FX window that is the bridged plugin's editor.
|
|
if (facts.otherProcess) return WindowCode::Plugin;
|
|
if (!facts.procResolved) return WindowCode::Unknown;
|
|
if (facts.hostModule) return WindowCode::Host;
|
|
if (normalizePath(systemRoot).empty()) return WindowCode::Unknown;
|
|
return isBeneath(facts.modulePath, systemRoot) ? WindowCode::System : WindowCode::Plugin;
|
|
}
|
|
|
|
bool isPluginEditorChain(const std::vector<WindowCode>& chain) {
|
|
return std::find(chain.begin(), chain.end(), WindowCode::Plugin) != chain.end();
|
|
}
|
|
|
|
} // namespace reasampler::ui
|