// DisplayConfig helper for spike S2: list targets, detach/attach a target // from the desktop topology, and try monitor specialization. // // dispctl list // dispctl detach remove target from active desktop topology // dispctl extend re-extend desktop to all displays // dispctl specialize [0|1] set monitor specialization flag #include #include #include #include #include static const char* err(LONG e) { switch (e) { case ERROR_SUCCESS: return "OK"; case ERROR_ACCESS_DENIED: return "ACCESS_DENIED"; case ERROR_NOT_SUPPORTED: return "NOT_SUPPORTED"; case ERROR_INVALID_PARAMETER: return "INVALID_PARAMETER"; case ERROR_GEN_FAILURE: return "GEN_FAILURE"; default: return "?"; } } int main(int argc, char** argv) { const char* cmd = argc > 1 ? argv[1] : "list"; long want = argc > 2 ? atol(argv[2]) : -1; UINT32 np = 0, nm = 0; if (GetDisplayConfigBufferSizes(QDC_ALL_PATHS, &np, &nm) != ERROR_SUCCESS) return 1; std::vector paths(np); std::vector modes(nm); if (QueryDisplayConfig(QDC_ALL_PATHS, &np, paths.data(), &nm, modes.data(), nullptr) != ERROR_SUCCESS) return 1; paths.resize(np); modes.resize(nm); if (strcmp(cmd, "list") == 0) { for (auto& p : paths) { DISPLAYCONFIG_TARGET_DEVICE_NAME tn{}; tn.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; tn.header.size = sizeof(tn); tn.header.adapterId = p.targetInfo.adapterId; tn.header.id = p.targetInfo.id; DisplayConfigGetDeviceInfo(&tn.header); printf("target id=%u luid=0x%x active=%d available=%d name='%ls'\n", p.targetInfo.id, p.targetInfo.adapterId.LowPart, (p.flags & DISPLAYCONFIG_PATH_ACTIVE) ? 1 : 0, p.targetInfo.targetAvailable, tn.monitorFriendlyDeviceName); } return 0; } if (strcmp(cmd, "detach") == 0) { // rebuild from ACTIVE paths only, minus the requested target UINT32 anp = 0, anm = 0; GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &anp, &anm); std::vector ap(anp); std::vector am(anm); if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &anp, ap.data(), &anm, am.data(), nullptr) != ERROR_SUCCESS) return 1; ap.resize(anp); std::vector keep; for (auto& p : ap) if ((long)p.targetInfo.id != want) keep.push_back(p); if (keep.size() == ap.size()) { printf("target %ld not in active topology (already detached)\n", want); return 0; } LONG r = SetDisplayConfig((UINT32)keep.size(), keep.data(), anm, am.data(), SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_ALLOW_CHANGES | SDC_SAVE_TO_DATABASE); printf("SetDisplayConfig(detach %ld) = %ld (%s)\n", want, r, err(r)); return r == ERROR_SUCCESS ? 0 : 1; } if (strcmp(cmd, "extend") == 0) { LONG r = SetDisplayConfig(0, nullptr, 0, nullptr, SDC_APPLY | SDC_TOPOLOGY_EXTEND); printf("SetDisplayConfig(extend) = %ld (%s)\n", r, err(r)); return r == ERROR_SUCCESS ? 0 : 1; } if (strcmp(cmd, "spec-get") == 0) { for (auto& p : paths) { if ((long)p.targetInfo.id != want) continue; DISPLAYCONFIG_GET_MONITOR_SPECIALIZATION gs{}; gs.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_MONITOR_SPECIALIZATION; gs.header.size = sizeof(gs); gs.header.adapterId = p.targetInfo.adapterId; gs.header.id = p.targetInfo.id; LONG r = DisplayConfigGetDeviceInfo(&gs.header); printf("spec-get(%ld) = %ld (%s): enabled=%u availForMonitor=%u availForSystem=%u\n", want, r, err(r), gs.isSpecializationEnabled, gs.isSpecializationAvailableForMonitor, gs.isSpecializationAvailableForSystem); return r == ERROR_SUCCESS ? 0 : 1; } printf("target %ld not found\n", want); return 1; } if (strcmp(cmd, "specialize") == 0) { bool enable = argc > 3 ? atoi(argv[3]) != 0 : true; for (auto& p : paths) { if ((long)p.targetInfo.id != want) continue; DISPLAYCONFIG_SET_MONITOR_SPECIALIZATION ms{}; ms.header.type = DISPLAYCONFIG_DEVICE_INFO_SET_MONITOR_SPECIALIZATION; ms.header.size = sizeof(ms); ms.header.adapterId = p.targetInfo.adapterId; ms.header.id = p.targetInfo.id; ms.isSpecializationEnabled = enable ? 1 : 0; wcscpy_s(ms.specializationApplicationName, L"sauna"); LONG r = DisplayConfigSetDeviceInfo(&ms.header); printf("DisplayConfigSetDeviceInfo(specialize %ld -> %d) = %ld (%s)\n", want, (int)enable, r, err(r)); return r == ERROR_SUCCESS ? 0 : 1; } printf("target %ld not found\n", want); return 1; } fprintf(stderr, "unknown command\n"); return 1; }