Extract layout bootstrap and thin NodeCanvas startup shells
This commit is contained in:
@@ -97,6 +97,7 @@ set(PP_PANOPAINTER_APP_SOURCES
|
||||
src/app_dialogs_info_openers.cpp
|
||||
src/app_events.cpp
|
||||
src/app_layout.cpp
|
||||
src/app_layout_bootstrap.cpp
|
||||
src/app_layout_brush.cpp
|
||||
src/app_layout_draw_toolbar.cpp
|
||||
src/app_layout_ui_state.cpp
|
||||
|
||||
@@ -80,13 +80,13 @@ What is still carrying too much live ownership:
|
||||
Current hotspot files:
|
||||
|
||||
- `src/canvas.cpp`: 2645 lines
|
||||
- `src/app_layout.cpp`: 229 lines
|
||||
- `src/app_layout.cpp`: 125 lines
|
||||
- `src/canvas_modes.cpp`: 1798 lines
|
||||
- `src/node.cpp`: 1594 lines
|
||||
- `src/main.cpp`: 390 lines
|
||||
- `src/main.cpp`: 271 lines
|
||||
- `src/node_panel_brush.cpp`: 1197 lines
|
||||
- `src/node_stroke_preview.cpp`: 890 lines
|
||||
- `src/node_canvas.cpp`: 831 lines
|
||||
- `src/node_canvas.cpp`: 852 lines
|
||||
- `src/app.cpp`: 502 lines
|
||||
- `src/app_dialogs.cpp`: 142 lines
|
||||
|
||||
@@ -135,7 +135,14 @@ Current architecture mismatches that must be treated as real blockers:
|
||||
`execute_legacy_canvas_draw_unmerged_node_canvas_shell(...)`, while the
|
||||
broader unmerged cache/viewport/background/composite pass setup now also
|
||||
routes through
|
||||
`execute_legacy_canvas_draw_unmerged_node_canvas_pass(...)`.
|
||||
`execute_legacy_canvas_draw_unmerged_node_canvas_pass(...)`, while
|
||||
`NodeCanvas::draw()` setup, merged-pass shell, and unmerged-pass shell now
|
||||
also route through `prepare_legacy_node_canvas_draw_setup(...)`,
|
||||
`execute_legacy_canvas_draw_node_canvas_shell(...)`,
|
||||
`execute_legacy_canvas_draw_merged_pass(...)`, and
|
||||
`execute_legacy_canvas_draw_node_canvas_unmerged_pass(...)`, which
|
||||
materially shortens the live `NodeCanvas::draw()` body even though the file
|
||||
itself is still large.
|
||||
- `app_layout.cpp` and `app_dialogs.cpp` are still mixed shell/controller files
|
||||
rather than thin composition/binding surfaces, even though tools-menu binding
|
||||
plus nested panels/options submenu wiring now live in
|
||||
@@ -154,8 +161,9 @@ Current architecture mismatches that must be treated as real blockers:
|
||||
persisted floating/docked panel-state ownership now also live in
|
||||
`src/app_layout_ui_state.cpp`, while draw-toolbar binding now also lives in
|
||||
`src/app_layout_draw_toolbar.cpp`, while brush-refresh now also lives in
|
||||
`src/app_layout_brush.cpp`, and `src/app_layout.cpp` is now mostly
|
||||
layout/bootstrap composition, while the
|
||||
`src/app_layout_brush.cpp`, while layout bootstrap plus reload/load
|
||||
continuation wiring now also lives in `src/app_layout_bootstrap.cpp`, and
|
||||
`src/app_layout.cpp` is now mostly thin call-through entrypoints, while the
|
||||
informational overlay opener family now also lives in
|
||||
`src/app_dialogs_info_openers.cpp` and the corresponding `App::dialog_*`
|
||||
entrypoints are thinner, while the export/video/PPBR dialog family now also
|
||||
@@ -193,8 +201,9 @@ Current architecture mismatches that must be treated as real blockers:
|
||||
while the retained Win32 VR/HMD shell now also routes through
|
||||
`src/platform_windows/windows_vr_shell.h` instead of staying inline in
|
||||
`src/main.cpp`, while RenderDoc startup/frame capture, SHCore DPI bootstrap,
|
||||
Win32 error-string conversion, and the GL debug pre/post callbacks now also
|
||||
live in `src/platform_windows/windows_bootstrap_helpers.cpp` instead of
|
||||
Win32 error-string conversion, the GL debug pre/post callbacks, and the WMI
|
||||
startup probe now also live in
|
||||
`src/platform_windows/windows_bootstrap_helpers.cpp` instead of
|
||||
`src/main.cpp`, while Win32 lifecycle running-state, close/shutdown
|
||||
sequencing, FPS title update/wakeup posting, stylus frame update, window
|
||||
preference save, and VR lifecycle wrappers now also live in
|
||||
|
||||
@@ -235,6 +235,13 @@ Current slice:
|
||||
`execute_legacy_canvas_draw_unmerged_node_canvas_pass(...)`, which removes
|
||||
another coherent outer-shell block even though the broader node draw loop
|
||||
still lives in `src/node_canvas.cpp`.
|
||||
- `NodeCanvas::draw()` setup, merged-pass shell, and unmerged-pass shell now
|
||||
also route through `prepare_legacy_node_canvas_draw_setup(...)`,
|
||||
`execute_legacy_canvas_draw_node_canvas_shell(...)`,
|
||||
`execute_legacy_canvas_draw_merged_pass(...)`, and
|
||||
`execute_legacy_canvas_draw_node_canvas_unmerged_pass(...)`, which
|
||||
materially shortens the live `NodeCanvas::draw()` body even though the file
|
||||
itself is still large.
|
||||
|
||||
Write scope:
|
||||
- `src/node_stroke_preview.cpp`
|
||||
@@ -313,7 +320,7 @@ targets look like helpers under one old monolith.
|
||||
Status: In Progress
|
||||
|
||||
Why now:
|
||||
`src/app_layout.cpp` is still a 229-line mixed file that builds menus,
|
||||
`src/app_layout.cpp` is still a 125-line mixed file that builds menus,
|
||||
attaches callbacks, computes planner inputs, and mutates UI state directly.
|
||||
|
||||
Current slice:
|
||||
@@ -348,6 +355,9 @@ Current slice:
|
||||
layout/bootstrap composition.
|
||||
- Brush-refresh now also lives in `src/app_layout_brush.cpp`, and
|
||||
`src/app_layout.cpp` is down to the remaining layout/bootstrap composition.
|
||||
- Layout bootstrap plus reload/load continuation wiring now also lives in
|
||||
`src/app_layout_bootstrap.cpp`, and `src/app_layout.cpp` is down to thin
|
||||
call-through entrypoints plus the remaining local helper pocket.
|
||||
|
||||
Write scope:
|
||||
- `src/app_layout.cpp`
|
||||
@@ -505,6 +515,9 @@ Current slice:
|
||||
conversion, `UnadjustWindowRectEx`, and GL debug pre/post callbacks now also
|
||||
live in `src/platform_windows/windows_bootstrap_helpers.cpp` instead of
|
||||
`src/main.cpp`
|
||||
- the WMI startup probe now also lives in
|
||||
`src/platform_windows/windows_bootstrap_helpers.cpp` instead of
|
||||
`src/main.cpp`
|
||||
- Win32 lifecycle running-state, close/shutdown handling, FPS title update and
|
||||
wakeup posting, stylus frame update, window preference save, and VR
|
||||
lifecycle wrappers now also live in
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
#include "pch.h"
|
||||
#include "app.h"
|
||||
#include "node_panel_grid.h"
|
||||
#include "node_icon.h"
|
||||
#include "node_dialog_open.h"
|
||||
#include "node_text.h"
|
||||
#include "node_progress_bar.h"
|
||||
#include "node_dialog_picker.h"
|
||||
#include "node_panel_floating.h"
|
||||
#include "app_core/about_menu.h"
|
||||
#include "app_core/app_preferences.h"
|
||||
@@ -18,10 +13,6 @@
|
||||
#include "legacy_document_layer_services.h"
|
||||
#include "legacy_preference_storage.h"
|
||||
#include "font.h"
|
||||
#include "node_remote_page.h"
|
||||
#include "node_shorcuts.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace pp::panopainter {
|
||||
void bind_legacy_main_toolbar(App& app);
|
||||
@@ -30,6 +21,7 @@ void bind_legacy_edit_menu(App& app);
|
||||
void bind_legacy_about_menu(App& app);
|
||||
void bind_legacy_layer_menu(App& app);
|
||||
void bind_legacy_tools_menu(App& app);
|
||||
void init_layout_bootstrap(App& app);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -120,137 +112,7 @@ void App::init_menu_layer()
|
||||
|
||||
void App::initLayout()
|
||||
{
|
||||
LOG("initializing layout statics");
|
||||
NodeBorder::static_init();
|
||||
NodeImage::static_init();
|
||||
NodeIcon::static_init();
|
||||
NodeStrokePreview::static_init();
|
||||
|
||||
static std::vector<std::shared_ptr<Layer>> saved_layers;
|
||||
layout.on_reloading = [&] {
|
||||
saved_layers = std::move(Canvas::I->m_layers);
|
||||
ui_save();
|
||||
NodeStrokePreview::empty_queue();
|
||||
};
|
||||
|
||||
layout.on_loaded = [&] (bool reloaded) {
|
||||
LOG("initializing layout updating after load %d x %d zoom %f", (int)width, (int)height, zoom);
|
||||
layout[main_id]->update(width, height, zoom);
|
||||
|
||||
LOG("initializing layout components");
|
||||
|
||||
init_sidebar();
|
||||
|
||||
if (reloaded)
|
||||
{
|
||||
for (const auto& l : saved_layers)
|
||||
layers->add_layer(l->m_name.c_str(), false, true, l);
|
||||
}
|
||||
else
|
||||
{
|
||||
layers->add_layer("Default", false, true);
|
||||
Canvas::I->m_unsaved = false;
|
||||
}
|
||||
|
||||
init_toolbar_draw();
|
||||
init_toolbar_main();
|
||||
init_menu_file();
|
||||
init_menu_edit();
|
||||
init_menu_layer();
|
||||
init_menu_tools();
|
||||
init_menu_about();
|
||||
|
||||
// set version string
|
||||
if (auto* version_label = layout[main_id]->find<NodeText>("version"))
|
||||
{
|
||||
version_label->set_text(g_version);
|
||||
}
|
||||
|
||||
const auto renderer_features = ShaderManager::render_device_features();
|
||||
const auto renderer_diagnostics = pp::app::plan_renderer_diagnostics({
|
||||
.framebuffer_fetch = renderer_features.framebuffer_fetch,
|
||||
.float32_render_targets = renderer_features.float32_render_targets,
|
||||
.float32_linear_filtering = renderer_features.float32_linear_filtering,
|
||||
.float16_render_targets = renderer_features.float16_render_targets,
|
||||
});
|
||||
|
||||
if (auto x = layout[main_id]->find<NodeBorder>("ext-fbf"))
|
||||
{
|
||||
x->m_color = renderer_diagnostics.framebuffer_fetch.supported ?
|
||||
glm::vec4(0, 1, 0, 1) :
|
||||
glm::vec4(1, 0, 0, 1);
|
||||
}
|
||||
|
||||
if (auto x = layout[main_id]->find<NodeBorder>("ext-flt"))
|
||||
{
|
||||
if (renderer_diagnostics.floating_point_targets.supported)
|
||||
{
|
||||
if (auto t = x->find<NodeText>("ext-flt-text"))
|
||||
{
|
||||
t->set_text(std::string(renderer_diagnostics.floating_point_targets.label));
|
||||
}
|
||||
x->m_color = glm::vec4(0, 1, 0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
x->m_color = glm::vec4(1, 0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
dialog_whatsnew(false);
|
||||
|
||||
brush_update(true, true);
|
||||
|
||||
// hacky thing to make the toolbar buttons not steal events when moving cursor fast
|
||||
if (auto* toolbar = layout[main_id]->find<Node>("toolbar"))
|
||||
toolbar->m_flood_events = true;
|
||||
|
||||
NodeImage* n = new NodeImage;
|
||||
n->m_path = "data/ui/p-black.png";
|
||||
n->m_tex_id = const_hash("data/ui/p-black.png");
|
||||
n->SetSize(30, 45);
|
||||
n->create();
|
||||
|
||||
NodeButtonCustom* butt = new NodeButtonCustom;
|
||||
butt->create();
|
||||
butt->add_child(n);
|
||||
butt->SetPositioning(YGPositionTypeAbsolute);
|
||||
butt->set_color({ 0, 0, 0, 0 });
|
||||
//n->SetPosition(100, 100);
|
||||
YGNodeStyleSetPosition(butt->y_node, YGEdgeBottom, 8);
|
||||
YGNodeStyleSetPosition(butt->y_node, YGEdgeLeft, 10);
|
||||
//butt->SetSize(30, 45);
|
||||
layout[main_id]->add_child(butt);
|
||||
|
||||
butt->on_click = [this](Node*){
|
||||
toggle_ui();
|
||||
};
|
||||
|
||||
ui_restore();
|
||||
|
||||
redraw = true;
|
||||
};
|
||||
|
||||
LOG("initializing layout xml");
|
||||
if (layout.m_loaded)
|
||||
{
|
||||
LOG("restore layout");
|
||||
layout.restore_context();
|
||||
}
|
||||
else
|
||||
layout.load("data/layout.xml");
|
||||
LOG("initializing layout completed");
|
||||
|
||||
LOG("initializing layout designer xml");
|
||||
layout_designer.on_loaded = [&](bool reloaded) {
|
||||
layout_designer.create();
|
||||
//layout_designer[main_id]->add_child(layout_designer.instantiate("shortcuts"));
|
||||
auto p = layout_designer[main_id]->add_child<NodeShortcuts>();
|
||||
//p->SetPosition(300, 300);
|
||||
//p->SetSize(600, 400);
|
||||
//p->m_container->add_child<NodePanelAnimation>();
|
||||
};
|
||||
//layout_designer.load("data/dialogs/shortcuts.xml");
|
||||
pp::panopainter::init_layout_bootstrap(*this);
|
||||
}
|
||||
|
||||
void App::set_ui_scale(float scale)
|
||||
|
||||
148
src/app_layout_bootstrap.cpp
Normal file
148
src/app_layout_bootstrap.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
#include "pch.h"
|
||||
#include "app.h"
|
||||
#include "node_border.h"
|
||||
#include "node_button_custom.h"
|
||||
#include "node_icon.h"
|
||||
#include "node_image.h"
|
||||
#include "node_shorcuts.h"
|
||||
#include "node_stroke_preview.h"
|
||||
#include "node_text.h"
|
||||
#include "app_core/app_status.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
std::vector<std::shared_ptr<Layer>> saved_layers;
|
||||
|
||||
void capture_layout_reload_state(App& app)
|
||||
{
|
||||
saved_layers = std::move(Canvas::I->m_layers);
|
||||
app.ui_save();
|
||||
NodeStrokePreview::empty_queue();
|
||||
}
|
||||
|
||||
void apply_layout_loaded_state(App& app, bool reloaded)
|
||||
{
|
||||
LOG("initializing layout updating after load %d x %d zoom %f", (int)app.width, (int)app.height, app.zoom);
|
||||
app.layout[app.main_id]->update(app.width, app.height, app.zoom);
|
||||
|
||||
LOG("initializing layout components");
|
||||
app.init_sidebar();
|
||||
|
||||
if (reloaded) {
|
||||
for (const auto& layer : saved_layers)
|
||||
app.layers->add_layer(layer->m_name.c_str(), false, true, layer);
|
||||
} else {
|
||||
app.layers->add_layer("Default", false, true);
|
||||
Canvas::I->m_unsaved = false;
|
||||
}
|
||||
|
||||
app.init_toolbar_draw();
|
||||
app.init_toolbar_main();
|
||||
app.init_menu_file();
|
||||
app.init_menu_edit();
|
||||
app.init_menu_layer();
|
||||
app.init_menu_tools();
|
||||
app.init_menu_about();
|
||||
|
||||
if (auto* version_label = app.layout[app.main_id]->find<NodeText>("version")) {
|
||||
version_label->set_text(g_version);
|
||||
}
|
||||
|
||||
const auto renderer_features = ShaderManager::render_device_features();
|
||||
const auto renderer_diagnostics = pp::app::plan_renderer_diagnostics({
|
||||
.framebuffer_fetch = renderer_features.framebuffer_fetch,
|
||||
.float32_render_targets = renderer_features.float32_render_targets,
|
||||
.float32_linear_filtering = renderer_features.float32_linear_filtering,
|
||||
.float16_render_targets = renderer_features.float16_render_targets,
|
||||
});
|
||||
|
||||
if (auto* indicator = app.layout[app.main_id]->find<NodeBorder>("ext-fbf")) {
|
||||
indicator->m_color = renderer_diagnostics.framebuffer_fetch.supported
|
||||
? glm::vec4(0, 1, 0, 1)
|
||||
: glm::vec4(1, 0, 0, 1);
|
||||
}
|
||||
|
||||
if (auto* indicator = app.layout[app.main_id]->find<NodeBorder>("ext-flt")) {
|
||||
if (renderer_diagnostics.floating_point_targets.supported) {
|
||||
if (auto* text = indicator->find<NodeText>("ext-flt-text"))
|
||||
text->set_text(std::string(renderer_diagnostics.floating_point_targets.label));
|
||||
indicator->m_color = glm::vec4(0, 1, 0, 1);
|
||||
} else {
|
||||
indicator->m_color = glm::vec4(1, 0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
app.dialog_whatsnew(false);
|
||||
app.brush_update(true, true);
|
||||
|
||||
if (auto* toolbar = app.layout[app.main_id]->find<Node>("toolbar"))
|
||||
toolbar->m_flood_events = true;
|
||||
|
||||
auto* toggle_button = new NodeImage;
|
||||
toggle_button->m_path = "data/ui/p-black.png";
|
||||
toggle_button->m_tex_id = const_hash("data/ui/p-black.png");
|
||||
toggle_button->SetSize(30, 45);
|
||||
toggle_button->create();
|
||||
|
||||
auto* button = new NodeButtonCustom;
|
||||
button->create();
|
||||
button->add_child(toggle_button);
|
||||
button->SetPositioning(YGPositionTypeAbsolute);
|
||||
button->set_color({ 0, 0, 0, 0 });
|
||||
YGNodeStyleSetPosition(button->y_node, YGEdgeBottom, 8);
|
||||
YGNodeStyleSetPosition(button->y_node, YGEdgeLeft, 10);
|
||||
app.layout[app.main_id]->add_child(button);
|
||||
|
||||
button->on_click = [&app](Node*) {
|
||||
app.toggle_ui();
|
||||
};
|
||||
|
||||
app.ui_restore();
|
||||
app.redraw = true;
|
||||
}
|
||||
|
||||
void init_layout_designer(App& app)
|
||||
{
|
||||
app.layout_designer.on_loaded = [&app](bool) {
|
||||
app.layout_designer.create();
|
||||
auto* shortcuts = app.layout_designer[app.main_id]->add_child<NodeShortcuts>();
|
||||
(void)shortcuts;
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace pp::panopainter {
|
||||
|
||||
void init_layout_bootstrap(App& app)
|
||||
{
|
||||
LOG("initializing layout statics");
|
||||
NodeBorder::static_init();
|
||||
NodeImage::static_init();
|
||||
NodeIcon::static_init();
|
||||
NodeStrokePreview::static_init();
|
||||
|
||||
app.layout.on_reloading = [&app] {
|
||||
capture_layout_reload_state(app);
|
||||
};
|
||||
|
||||
app.layout.on_loaded = [&app](bool reloaded) {
|
||||
apply_layout_loaded_state(app, reloaded);
|
||||
};
|
||||
|
||||
LOG("initializing layout xml");
|
||||
if (app.layout.m_loaded) {
|
||||
LOG("restore layout");
|
||||
app.layout.restore_context();
|
||||
} else {
|
||||
app.layout.load("data/layout.xml");
|
||||
}
|
||||
LOG("initializing layout completed");
|
||||
|
||||
LOG("initializing layout designer xml");
|
||||
init_layout_designer(app);
|
||||
}
|
||||
|
||||
} // namespace pp::panopainter
|
||||
@@ -1112,6 +1112,99 @@ inline void execute_legacy_canvas_draw_unmerged_node_canvas_shell(
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename PrepareDensityRenderTarget,
|
||||
typename PrepareStandardRenderTarget,
|
||||
typename DrawMergedPass,
|
||||
typename DrawUnmergedPass>
|
||||
inline void execute_legacy_canvas_draw_node_canvas_shell(
|
||||
bool use_density_render_target,
|
||||
bool draw_merged,
|
||||
PrepareDensityRenderTarget&& prepare_density_render_target,
|
||||
PrepareStandardRenderTarget&& prepare_standard_render_target,
|
||||
DrawMergedPass&& draw_merged_pass,
|
||||
DrawUnmergedPass&& draw_unmerged_pass)
|
||||
{
|
||||
if (use_density_render_target) {
|
||||
prepare_density_render_target();
|
||||
} else {
|
||||
prepare_standard_render_target();
|
||||
}
|
||||
|
||||
if (draw_merged) {
|
||||
draw_merged_pass();
|
||||
return;
|
||||
}
|
||||
|
||||
draw_unmerged_pass();
|
||||
}
|
||||
|
||||
template <typename NodeCanvasT>
|
||||
inline void prepare_legacy_node_canvas_draw_setup(
|
||||
NodeCanvasT& node_canvas,
|
||||
const glm::vec4& box,
|
||||
const glm::ivec4& c,
|
||||
const glm::mat4& proj,
|
||||
const glm::mat4& camera)
|
||||
{
|
||||
node_canvas.m_canvas->m_mv = camera;
|
||||
node_canvas.m_canvas->m_proj = proj;
|
||||
node_canvas.m_canvas->m_box = box;
|
||||
node_canvas.m_canvas->m_vp = c;
|
||||
|
||||
for (int plane_index = 0; plane_index < 6; plane_index++) {
|
||||
node_canvas.m_canvas->m_plane_unproject[plane_index] =
|
||||
glm::inverse(node_canvas.m_canvas->m_proj * node_canvas.m_canvas->m_mv * node_canvas.m_canvas->m_plane_transform[plane_index]);
|
||||
node_canvas.m_canvas->m_plane_dir[plane_index] =
|
||||
-(node_canvas.m_canvas->m_plane_transform[plane_index] * glm::vec4(node_canvas.m_canvas->m_plane_origin[plane_index], 1));
|
||||
node_canvas.m_canvas->m_plane_shape[plane_index] =
|
||||
node_canvas.m_canvas->face_to_shape2D(plane_index);
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename NodeCanvasT,
|
||||
typename ApplyCapability,
|
||||
typename SetActiveTextureUnit,
|
||||
typename DrawFacePlane>
|
||||
inline void execute_legacy_canvas_draw_merged_pass(
|
||||
NodeCanvasT& node_canvas,
|
||||
const glm::mat4& proj,
|
||||
const glm::mat4& camera,
|
||||
ApplyCapability&& apply_node_canvas_capability,
|
||||
SetActiveTextureUnit&& set_active_texture_unit,
|
||||
DrawFacePlane&& draw_face_plane)
|
||||
{
|
||||
execute_legacy_canvas_draw_merge_background_setup(
|
||||
{
|
||||
.draw_merged = true,
|
||||
},
|
||||
{
|
||||
.disable_blend = [&] {
|
||||
apply_node_canvas_capability(pp::renderer::gl::blend_state(), false);
|
||||
},
|
||||
.draw_checkerboard_plane = make_legacy_canvas_draw_merge_background_checkerboard_plane(
|
||||
proj,
|
||||
camera,
|
||||
node_canvas.m_canvas->m_layers.size() + 500.f,
|
||||
node_canvas.m_canvas->m_plane_transform,
|
||||
std::forward<DrawFacePlane>(draw_face_plane)),
|
||||
});
|
||||
|
||||
const auto draw_merged_texture_plane = make_legacy_canvas_draw_merge_layer_texture_draw(
|
||||
&node_canvas.m_canvas->m_layers_merge,
|
||||
&node_canvas.m_sampler,
|
||||
&node_canvas.m_face_plane,
|
||||
std::forward<SetActiveTextureUnit>(set_active_texture_unit),
|
||||
proj,
|
||||
camera,
|
||||
node_canvas.m_canvas->m_plane_transform);
|
||||
|
||||
for (int plane_index = 0; plane_index < 6; plane_index++) {
|
||||
draw_merged_texture_plane(plane_index);
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename NodeCanvasT,
|
||||
typename ApplyViewport,
|
||||
@@ -1219,6 +1312,63 @@ inline void execute_legacy_canvas_draw_unmerged_node_canvas_pass(
|
||||
});
|
||||
}
|
||||
|
||||
template <
|
||||
typename NodeCanvasT,
|
||||
typename ApplyViewport,
|
||||
typename ApplyCapability,
|
||||
typename SetSampler,
|
||||
typename MakeLayerPathExecution,
|
||||
typename LogOnionRangeFailure>
|
||||
inline void execute_legacy_canvas_draw_node_canvas_unmerged_pass(
|
||||
NodeCanvasT& node_canvas,
|
||||
bool use_blend,
|
||||
bool copy_blend_destination,
|
||||
const glm::mat4& proj,
|
||||
const glm::mat4& camera,
|
||||
const glm::mat4& layer_orientation,
|
||||
const glm::ivec4& c,
|
||||
ApplyViewport&& apply_node_canvas_viewport,
|
||||
ApplyCapability&& apply_node_canvas_capability,
|
||||
SetSampler&& set_sampler,
|
||||
MakeLayerPathExecution&& make_layer_path_execution,
|
||||
LogOnionRangeFailure&& log_onion_range_failure)
|
||||
{
|
||||
const auto& brush = node_canvas.m_canvas->m_current_stroke->m_brush;
|
||||
execute_legacy_canvas_draw_unmerged_node_canvas_pass(
|
||||
node_canvas,
|
||||
use_blend,
|
||||
proj,
|
||||
camera,
|
||||
layer_orientation,
|
||||
c,
|
||||
std::forward<ApplyViewport>(apply_node_canvas_viewport),
|
||||
std::forward<ApplyCapability>(apply_node_canvas_capability),
|
||||
[&] {
|
||||
node_canvas.m_face_plane.draw_fill();
|
||||
},
|
||||
std::forward<SetSampler>(set_sampler),
|
||||
[&](size_t layer_index, int plane_index, const glm::mat4& plane_mvp_z) {
|
||||
return make_layer_path_execution(
|
||||
layer_index,
|
||||
plane_index,
|
||||
plane_mvp_z,
|
||||
brush.get(),
|
||||
copy_blend_destination,
|
||||
node_canvas.m_canvas->m_cam_fov < 20.f);
|
||||
},
|
||||
[&] {
|
||||
return make_legacy_canvas_draw_merge_cache_to_screen_checkerboard_plane(
|
||||
proj,
|
||||
camera,
|
||||
node_canvas.m_canvas->m_layers.size() + 500.f,
|
||||
node_canvas.m_canvas->m_plane_transform,
|
||||
[&] {
|
||||
node_canvas.m_face_plane.draw_fill();
|
||||
});
|
||||
},
|
||||
std::forward<LogOnionRangeFailure>(log_onion_range_failure));
|
||||
}
|
||||
|
||||
inline void execute_legacy_canvas_draw_merge_plane_setup(
|
||||
const LegacyCanvasDrawMergePlaneSetupUniforms& uniforms,
|
||||
const LegacyCanvasDrawMergePlaneSetupExecution& execution)
|
||||
|
||||
195
src/main.cpp
195
src/main.cpp
@@ -16,7 +16,6 @@
|
||||
#include "platform_windows/windows_vr_shell.h"
|
||||
#include "../resource.h"
|
||||
|
||||
#include <WbemCli.h>
|
||||
#include "wacom.h"
|
||||
#include "abr.h"
|
||||
|
||||
@@ -75,198 +74,6 @@ void win32_update_fps(int frames)
|
||||
}));
|
||||
}
|
||||
|
||||
int read_WMI_info()
|
||||
{
|
||||
// see: http://win32easy.blogspot.co.uk/2011/03/wmi-in-c-query-everyting-from-your-os.html
|
||||
|
||||
HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
if (FAILED(hRes))
|
||||
{
|
||||
LOG("Unable to launch COM: %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))
|
||||
{
|
||||
LOG("Unable to initialize security: %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
IWbemLocator* pLocator = NULL;
|
||||
if (FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
|
||||
{
|
||||
LOG("Unable to create a WbemLocator: %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
IWbemServices* pService = NULL;
|
||||
if (FAILED(hRes = pLocator->ConnectServer(BSTR(L"root\\CIMV2"), NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
|
||||
{
|
||||
pLocator->Release();
|
||||
LOG("Unable to connect to \"CIMV2\": %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto log_field = [](const wchar_t* section, IWbemClassObject* clsObj, const wchar_t* field) {
|
||||
VARIANT vRet;
|
||||
CIMTYPE pType;
|
||||
VariantInit(&vRet);
|
||||
if (SUCCEEDED(clsObj->Get(field, 0, &vRet, &pType, NULL)))
|
||||
{
|
||||
if (pType == CIM_STRING && pType != CIM_EMPTY && pType != CIM_ILLEGAL)
|
||||
{
|
||||
LOGW(L"%s %s: %s", section, field, vRet.bstrVal);
|
||||
}
|
||||
else if (pType == CIM_UINT32 && pType != CIM_EMPTY && pType != CIM_ILLEGAL)
|
||||
{
|
||||
LOGW(L"%s %s: %d", section, field, vRet.uintVal);
|
||||
}
|
||||
|
||||
VariantClear(&vRet);
|
||||
}
|
||||
};
|
||||
|
||||
auto get_int = [](IWbemClassObject* clsObj, const wchar_t* field) {
|
||||
VARIANT vRet;
|
||||
CIMTYPE pType;
|
||||
VariantInit(&vRet);
|
||||
int ret = 0;
|
||||
if (SUCCEEDED(clsObj->Get(field, 0, &vRet, &pType, NULL)))
|
||||
{
|
||||
if (pType == CIM_UINT32 && pType != CIM_EMPTY && pType != CIM_ILLEGAL)
|
||||
ret = vRet.uintVal;
|
||||
VariantClear(&vRet);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
// GET DEVICE INFO
|
||||
{
|
||||
IEnumWbemClassObject* pEnumerator = NULL;
|
||||
if (FAILED(hRes = pService->ExecQuery(BSTR(L"WQL"), BSTR(L"SELECT * FROM Win32_ComputerSystem"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
|
||||
{
|
||||
pLocator->Release();
|
||||
pService->Release();
|
||||
LOG("Unable to retrive desktop monitors: %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
IWbemClassObject* clsObj = NULL;
|
||||
int numElems;
|
||||
while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
|
||||
{
|
||||
if (FAILED(hRes))
|
||||
break;
|
||||
|
||||
log_field(L"Machine", clsObj, L"Name");
|
||||
log_field(L"Machine", clsObj, L"Model");
|
||||
log_field(L"Machine", clsObj, L"Manufacturer");
|
||||
|
||||
clsObj->Release();
|
||||
}
|
||||
pEnumerator->Release();
|
||||
}
|
||||
|
||||
// GET OS INFO
|
||||
{
|
||||
IEnumWbemClassObject* pEnumerator = NULL;
|
||||
if (FAILED(hRes = pService->ExecQuery(BSTR(L"WQL"), BSTR(L"SELECT * FROM Win32_OperatingSystem"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
|
||||
{
|
||||
pLocator->Release();
|
||||
pService->Release();
|
||||
LOG("Unable to retrive desktop monitors: %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
IWbemClassObject* clsObj = NULL;
|
||||
int numElems;
|
||||
while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
|
||||
{
|
||||
if (FAILED(hRes))
|
||||
break;
|
||||
|
||||
log_field(L"OS", clsObj, L"Name");
|
||||
log_field(L"OS", clsObj, L"Version");
|
||||
log_field(L"OS", clsObj, L"Locale");
|
||||
log_field(L"OS", clsObj, L"OSProductSuite");
|
||||
log_field(L"OS", clsObj, L"Manufacturer");
|
||||
log_field(L"OS", clsObj, L"Description");
|
||||
|
||||
clsObj->Release();
|
||||
}
|
||||
pEnumerator->Release();
|
||||
}
|
||||
|
||||
|
||||
pService->Release();
|
||||
pService = NULL;
|
||||
if (FAILED(hRes = pLocator->ConnectServer(BSTR(L"root\\Microsoft\\Windows\\DeviceGuard"), NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
|
||||
{
|
||||
pLocator->Release();
|
||||
LOG("Unable to connect to \"DeviceGuard\": %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// GET DEVICE GUARD
|
||||
{
|
||||
IEnumWbemClassObject* pEnumerator = NULL;
|
||||
if (FAILED(hRes = pService->ExecQuery(BSTR(L"WQL"), BSTR(L"SELECT * FROM Win32_DeviceGuard"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
|
||||
{
|
||||
pLocator->Release();
|
||||
pService->Release();
|
||||
LOG("Unable to retrive desktop monitors: %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
IWbemClassObject* clsObj = NULL;
|
||||
int numElems;
|
||||
while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
|
||||
{
|
||||
if (FAILED(hRes))
|
||||
break;
|
||||
|
||||
if (get_int(clsObj, L"CodeIntegrityPolicyEnforcementStatus") > 0)
|
||||
{
|
||||
LOG("SANDBOX DETECTED");
|
||||
retained_state().sandboxed = true;
|
||||
}
|
||||
|
||||
SAFEARRAY *psaNames = NULL;
|
||||
if (SUCCEEDED(clsObj->GetNames(0, WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, 0, &psaNames)))
|
||||
{
|
||||
// Get the number of properties.
|
||||
long lLower, lUpper;
|
||||
BSTR PropName = NULL;
|
||||
SafeArrayGetLBound(psaNames, 1, &lLower);
|
||||
SafeArrayGetUBound(psaNames, 1, &lUpper);
|
||||
|
||||
for (long i = lLower; i <= lUpper; i++)
|
||||
{
|
||||
// Get this property.
|
||||
SafeArrayGetElement(psaNames, &i, &PropName);
|
||||
|
||||
LOGW(L"Prop: %s", PropName);
|
||||
log_field(L"DeviceGuard", clsObj, PropName);
|
||||
|
||||
SysFreeString(PropName);
|
||||
}
|
||||
|
||||
SafeArrayDestroy(psaNames);
|
||||
}
|
||||
|
||||
clsObj->Release();
|
||||
}
|
||||
pEnumerator->Release();
|
||||
}
|
||||
|
||||
|
||||
pLocator->Release();
|
||||
CoUninitialize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// create a reverse map from kKey to VK_XXX
|
||||
void init_vk_map()
|
||||
{
|
||||
@@ -329,7 +136,7 @@ int main(int argc, char** argv)
|
||||
|
||||
pp::platform::windows::setup_exception_handler();
|
||||
|
||||
read_WMI_info();
|
||||
pp::platform::windows::read_WMI_info();
|
||||
|
||||
App::I->create();
|
||||
|
||||
|
||||
@@ -582,11 +582,6 @@ void NodeCanvas::draw()
|
||||
glm::mat4 proj = glm::perspective(glm::radians(m_canvas->m_cam_fov), box.z / box.w, 0.001f, 1000.f);
|
||||
glm::mat4 camera = glm::translate(m_canvas->m_cam_pos) * m_canvas->m_cam_rot;
|
||||
|
||||
m_canvas->m_mv = camera;
|
||||
m_canvas->m_proj = proj;
|
||||
m_canvas->m_box = box;
|
||||
m_canvas->m_vp = c;
|
||||
|
||||
float pitch = 0;
|
||||
if (auto slider = root()->find<NodeSliderH>("pitch-slider"))
|
||||
pitch = (slider->get_value() - 0.5) * glm::half_pi<float>();
|
||||
@@ -597,123 +592,81 @@ void NodeCanvas::draw()
|
||||
if (auto slider = root()->find<NodeSliderH>("roll-slider"))
|
||||
roll = (slider->get_value() - 0.5) * glm::half_pi<float>();
|
||||
|
||||
// pre computed helpers
|
||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||
{
|
||||
//glm::mat4 plane_camera = glm::lookAt(m_canvas->m_plane_origin[plane_index], m_canvas->m_plane_normal[plane_index], m_canvas->m_plane_tangent[plane_index]);
|
||||
m_canvas->m_plane_unproject[plane_index] = glm::inverse(m_canvas->m_proj * m_canvas->m_mv * m_canvas->m_plane_transform[plane_index]);
|
||||
m_canvas->m_plane_dir[plane_index] = -(m_canvas->m_plane_transform[plane_index] * glm::vec4(m_canvas->m_plane_origin[plane_index], 1));
|
||||
// face is the 2d shape of the cube plane i projected onto the window space
|
||||
m_canvas->m_plane_shape[plane_index] = m_canvas->face_to_shape2D(plane_index);
|
||||
}
|
||||
|
||||
|
||||
if (m_density != 1.f)
|
||||
{
|
||||
m_rtt.bindFramebuffer();
|
||||
clear_node_canvas_color_buffer({ 1.f, 1.f, 0.f, 0.f });
|
||||
apply_node_canvas_viewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
clear_node_canvas_color_buffer({ 1.f, 1.f, 1.f, 0.f });
|
||||
apply_node_canvas_viewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w);
|
||||
}
|
||||
pp::panopainter::prepare_legacy_node_canvas_draw_setup(*this, box, c, proj, camera);
|
||||
|
||||
// NOTE: draw_merge has been disabled for worst performance
|
||||
bool draw_merged = !(m_canvas->m_current_mode == kCanvasMode::Camera);
|
||||
draw_merged = false;
|
||||
|
||||
if (draw_merged)
|
||||
{
|
||||
pp::panopainter::execute_legacy_canvas_draw_merge_background_setup(
|
||||
{
|
||||
.draw_merged = true,
|
||||
},
|
||||
{
|
||||
.disable_blend = [&] {
|
||||
apply_node_canvas_capability(pp::renderer::gl::blend_state(), false);
|
||||
pp::panopainter::execute_legacy_canvas_draw_node_canvas_shell(
|
||||
m_density != 1.f,
|
||||
draw_merged,
|
||||
[&] {
|
||||
m_rtt.bindFramebuffer();
|
||||
clear_node_canvas_color_buffer({ 1.f, 1.f, 0.f, 0.f });
|
||||
apply_node_canvas_viewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
|
||||
},
|
||||
[&] {
|
||||
clear_node_canvas_color_buffer({ 1.f, 1.f, 1.f, 0.f });
|
||||
apply_node_canvas_viewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w);
|
||||
},
|
||||
[&] {
|
||||
pp::panopainter::execute_legacy_canvas_draw_merged_pass(
|
||||
*this,
|
||||
proj,
|
||||
camera,
|
||||
[&](auto state, bool enabled) {
|
||||
apply_node_canvas_capability(state, enabled);
|
||||
},
|
||||
.draw_checkerboard_plane = pp::panopainter::make_legacy_canvas_draw_merge_background_checkerboard_plane(
|
||||
proj,
|
||||
camera,
|
||||
m_canvas->m_layers.size() + 500.f,
|
||||
m_canvas->m_plane_transform,
|
||||
[&] {
|
||||
m_face_plane.draw_fill();
|
||||
}),
|
||||
});
|
||||
[](int unit) {
|
||||
set_active_texture_unit(unit);
|
||||
},
|
||||
[&] {
|
||||
m_face_plane.draw_fill();
|
||||
});
|
||||
},
|
||||
[&] {
|
||||
const auto blend_gate = node_canvas_blend_gate_plan(
|
||||
m_cache_rtt.getWidth(),
|
||||
m_cache_rtt.getHeight(),
|
||||
m_canvas->m_layers,
|
||||
m_canvas->m_current_stroke ? m_canvas->m_current_stroke->m_brush.get() : nullptr);
|
||||
const bool use_blend = blend_gate.shader_blend;
|
||||
const bool copy_blend_destination = use_blend && !blend_gate.reads_destination_color;
|
||||
const auto layer_orientation = glm::eulerAngleYXZ(yaw, pitch, roll);
|
||||
|
||||
const auto draw_merged_texture_plane = pp::panopainter::make_legacy_canvas_draw_merge_layer_texture_draw(
|
||||
&m_canvas->m_layers_merge,
|
||||
&m_sampler,
|
||||
&m_face_plane,
|
||||
set_active_texture_unit,
|
||||
proj,
|
||||
camera,
|
||||
m_canvas->m_plane_transform);
|
||||
|
||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||
{
|
||||
draw_merged_texture_plane(plane_index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto blend_gate = node_canvas_blend_gate_plan(
|
||||
m_cache_rtt.getWidth(),
|
||||
m_cache_rtt.getHeight(),
|
||||
m_canvas->m_layers,
|
||||
m_canvas->m_current_stroke ? m_canvas->m_current_stroke->m_brush.get() : nullptr);
|
||||
const bool use_blend = blend_gate.shader_blend;
|
||||
const bool copy_blend_destination = use_blend && !blend_gate.reads_destination_color;
|
||||
const auto layer_orientation = glm::eulerAngleYXZ(yaw, pitch, roll);
|
||||
|
||||
const auto& b = m_canvas->m_current_stroke->m_brush;
|
||||
pp::panopainter::execute_legacy_canvas_draw_unmerged_node_canvas_pass(
|
||||
*this,
|
||||
use_blend,
|
||||
proj,
|
||||
camera,
|
||||
layer_orientation,
|
||||
c,
|
||||
[&](int x, int y, int width, int height) {
|
||||
apply_node_canvas_viewport(x, y, width, height);
|
||||
},
|
||||
[&](auto state, bool enabled) {
|
||||
apply_node_canvas_capability(state, enabled);
|
||||
},
|
||||
[&] {
|
||||
m_face_plane.draw_fill();
|
||||
},
|
||||
[&] {
|
||||
m_sampler.bind(0);
|
||||
set_active_texture_unit(0);
|
||||
},
|
||||
[&](size_t layer_index, int plane_index, const glm::mat4& plane_mvp_z) {
|
||||
return make_node_canvas_layer_path_execution(
|
||||
*this,
|
||||
layer_index,
|
||||
plane_index,
|
||||
plane_mvp_z,
|
||||
b.get(),
|
||||
copy_blend_destination,
|
||||
m_canvas->m_cam_fov < 20.f);
|
||||
},
|
||||
[&] {
|
||||
return pp::panopainter::make_legacy_canvas_draw_merge_cache_to_screen_checkerboard_plane(
|
||||
proj,
|
||||
camera,
|
||||
m_canvas->m_layers.size() + 500.f,
|
||||
m_canvas->m_plane_transform,
|
||||
[&] {
|
||||
m_face_plane.draw_fill();
|
||||
});
|
||||
},
|
||||
[&](const char* message) {
|
||||
LOG("NodeCanvas onion frame range failed: %s", message);
|
||||
});
|
||||
}
|
||||
pp::panopainter::execute_legacy_canvas_draw_node_canvas_unmerged_pass(
|
||||
*this,
|
||||
use_blend,
|
||||
copy_blend_destination,
|
||||
proj,
|
||||
camera,
|
||||
layer_orientation,
|
||||
c,
|
||||
[&](int x, int y, int width, int height) {
|
||||
apply_node_canvas_viewport(x, y, width, height);
|
||||
},
|
||||
[&](auto state, bool enabled) {
|
||||
apply_node_canvas_capability(state, enabled);
|
||||
},
|
||||
[&] {
|
||||
m_sampler.bind(0);
|
||||
set_active_texture_unit(0);
|
||||
},
|
||||
[&](size_t layer_index, int plane_index, const glm::mat4& plane_mvp_z, const Brush* brush, bool copy_blend_destination, bool use_nearest_sampler) {
|
||||
return make_node_canvas_layer_path_execution(
|
||||
*this,
|
||||
layer_index,
|
||||
plane_index,
|
||||
plane_mvp_z,
|
||||
brush,
|
||||
copy_blend_destination,
|
||||
use_nearest_sampler);
|
||||
},
|
||||
[&](const char* message) {
|
||||
LOG("NodeCanvas onion frame range failed: %s", message);
|
||||
});
|
||||
});
|
||||
|
||||
execute_node_canvas_draw_merge_tail(*this, ortho_proj, proj, camera, c);
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <WbemCli.h>
|
||||
#include <sstream>
|
||||
#include <shellscalingapi.h>
|
||||
#include <string>
|
||||
@@ -162,6 +163,198 @@ void setup_exception_handler()
|
||||
BT_SetTerminate();
|
||||
}
|
||||
|
||||
int read_WMI_info()
|
||||
{
|
||||
// see: http://win32easy.blogspot.co.uk/2011/03/wmi-in-c-query-everyting-from-your-os.html
|
||||
|
||||
HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
if (FAILED(hRes))
|
||||
{
|
||||
LOG("Unable to launch COM: %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))
|
||||
{
|
||||
LOG("Unable to initialize security: %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
IWbemLocator* pLocator = NULL;
|
||||
if (FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
|
||||
{
|
||||
LOG("Unable to create a WbemLocator: %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
IWbemServices* pService = NULL;
|
||||
if (FAILED(hRes = pLocator->ConnectServer(BSTR(L"root\\CIMV2"), NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
|
||||
{
|
||||
pLocator->Release();
|
||||
LOG("Unable to connect to \"CIMV2\": %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto log_field = [](const wchar_t* section, IWbemClassObject* clsObj, const wchar_t* field) {
|
||||
VARIANT vRet;
|
||||
CIMTYPE pType;
|
||||
VariantInit(&vRet);
|
||||
if (SUCCEEDED(clsObj->Get(field, 0, &vRet, &pType, NULL)))
|
||||
{
|
||||
if (pType == CIM_STRING && pType != CIM_EMPTY && pType != CIM_ILLEGAL)
|
||||
{
|
||||
LOGW(L"%s %s: %s", section, field, vRet.bstrVal);
|
||||
}
|
||||
else if (pType == CIM_UINT32 && pType != CIM_EMPTY && pType != CIM_ILLEGAL)
|
||||
{
|
||||
LOGW(L"%s %s: %d", section, field, vRet.uintVal);
|
||||
}
|
||||
|
||||
VariantClear(&vRet);
|
||||
}
|
||||
};
|
||||
|
||||
auto get_int = [](IWbemClassObject* clsObj, const wchar_t* field) {
|
||||
VARIANT vRet;
|
||||
CIMTYPE pType;
|
||||
VariantInit(&vRet);
|
||||
int ret = 0;
|
||||
if (SUCCEEDED(clsObj->Get(field, 0, &vRet, &pType, NULL)))
|
||||
{
|
||||
if (pType == CIM_UINT32 && pType != CIM_EMPTY && pType != CIM_ILLEGAL)
|
||||
ret = vRet.uintVal;
|
||||
VariantClear(&vRet);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
// GET DEVICE INFO
|
||||
{
|
||||
IEnumWbemClassObject* pEnumerator = NULL;
|
||||
if (FAILED(hRes = pService->ExecQuery(BSTR(L"WQL"), BSTR(L"SELECT * FROM Win32_ComputerSystem"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
|
||||
{
|
||||
pLocator->Release();
|
||||
pService->Release();
|
||||
LOG("Unable to retrive desktop monitors: %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
IWbemClassObject* clsObj = NULL;
|
||||
int numElems;
|
||||
while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
|
||||
{
|
||||
if (FAILED(hRes))
|
||||
break;
|
||||
|
||||
log_field(L"Machine", clsObj, L"Name");
|
||||
log_field(L"Machine", clsObj, L"Model");
|
||||
log_field(L"Machine", clsObj, L"Manufacturer");
|
||||
|
||||
clsObj->Release();
|
||||
}
|
||||
pEnumerator->Release();
|
||||
}
|
||||
|
||||
// GET OS INFO
|
||||
{
|
||||
IEnumWbemClassObject* pEnumerator = NULL;
|
||||
if (FAILED(hRes = pService->ExecQuery(BSTR(L"WQL"), BSTR(L"SELECT * FROM Win32_OperatingSystem"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
|
||||
{
|
||||
pLocator->Release();
|
||||
pService->Release();
|
||||
LOG("Unable to retrive desktop monitors: %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
IWbemClassObject* clsObj = NULL;
|
||||
int numElems;
|
||||
while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
|
||||
{
|
||||
if (FAILED(hRes))
|
||||
break;
|
||||
|
||||
log_field(L"OS", clsObj, L"Name");
|
||||
log_field(L"OS", clsObj, L"Version");
|
||||
log_field(L"OS", clsObj, L"Locale");
|
||||
log_field(L"OS", clsObj, L"OSProductSuite");
|
||||
log_field(L"OS", clsObj, L"Manufacturer");
|
||||
log_field(L"OS", clsObj, L"Description");
|
||||
|
||||
clsObj->Release();
|
||||
}
|
||||
pEnumerator->Release();
|
||||
}
|
||||
|
||||
|
||||
pService->Release();
|
||||
pService = NULL;
|
||||
if (FAILED(hRes = pLocator->ConnectServer(BSTR(L"root\\Microsoft\\Windows\\DeviceGuard"), NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
|
||||
{
|
||||
pLocator->Release();
|
||||
LOG("Unable to connect to \"DeviceGuard\": %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// GET DEVICE GUARD
|
||||
{
|
||||
IEnumWbemClassObject* pEnumerator = NULL;
|
||||
if (FAILED(hRes = pService->ExecQuery(BSTR(L"WQL"), BSTR(L"SELECT * FROM Win32_DeviceGuard"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
|
||||
{
|
||||
pLocator->Release();
|
||||
pService->Release();
|
||||
LOG("Unable to retrive desktop monitors: %x", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
IWbemClassObject* clsObj = NULL;
|
||||
int numElems;
|
||||
while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
|
||||
{
|
||||
if (FAILED(hRes))
|
||||
break;
|
||||
|
||||
if (get_int(clsObj, L"CodeIntegrityPolicyEnforcementStatus") > 0)
|
||||
{
|
||||
LOG("SANDBOX DETECTED");
|
||||
retained_state().sandboxed = true;
|
||||
}
|
||||
|
||||
SAFEARRAY *psaNames = NULL;
|
||||
if (SUCCEEDED(clsObj->GetNames(0, WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, 0, &psaNames)))
|
||||
{
|
||||
// Get the number of properties.
|
||||
long lLower, lUpper;
|
||||
BSTR PropName = NULL;
|
||||
SafeArrayGetLBound(psaNames, 1, &lLower);
|
||||
SafeArrayGetUBound(psaNames, 1, &lUpper);
|
||||
|
||||
for (long i = lLower; i <= lUpper; i++)
|
||||
{
|
||||
// Get this property.
|
||||
SafeArrayGetElement(psaNames, &i, &PropName);
|
||||
|
||||
LOGW(L"Prop: %s", PropName);
|
||||
log_field(L"DeviceGuard", clsObj, PropName);
|
||||
|
||||
SysFreeString(PropName);
|
||||
}
|
||||
|
||||
SafeArrayDestroy(psaNames);
|
||||
}
|
||||
|
||||
clsObj->Release();
|
||||
}
|
||||
pEnumerator->Release();
|
||||
}
|
||||
|
||||
|
||||
pLocator->Release();
|
||||
CoUninitialize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MainWindowStartupState initialize_main_window_startup_state()
|
||||
{
|
||||
auto startup = MainWindowStartupState {};
|
||||
|
||||
@@ -20,6 +20,7 @@ void init_shcore_API();
|
||||
std::string GetLastErrorAsString();
|
||||
void _pre_call_callback(const char* name, void* funcptr, int len_args, ...);
|
||||
void _post_call_callback(const char* name, void* funcptr, int len_args, ...);
|
||||
int read_WMI_info();
|
||||
|
||||
struct MainWindowStartupState
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user