🌈️ apply a wallpaper based on the weather outside
0

Configure Feed

Select the types of activity you want to include in your feed.

feat(apply): initial Windows multi-monitor setup

Angel Wang (Jun 26, 2026, 7:37 PM -0600) 725d5c5a 823b6dca

+76 -4
+76 -4
src/apply/application.ts
··· 2 2 import lab from "@colordx/core/plugins/lab" 3 3 import type { ImageAnalysisData } from "../analyze/analysis.ts" 4 4 import { chalkDebug } from "../utils.ts" 5 + import * as path from "@std/path" 5 6 6 7 extend([lab]) 7 8 ··· 98 99 return matchingImages 99 100 } 100 101 101 - export function setWindowsWallpaper() { 102 - const user32 = Deno.dlopen("user32.dll", { 103 - SystemParametersInfoA: { parameters: ["u16", "u16", "pointer", "u16"], result: "void" } 104 - }) 102 + 103 + export async function setWindowsWallpaper(tempImagePath: string, ...imagePaths: string[]) { 104 + interface Rect { 105 + left: number 106 + top: number 107 + right: number 108 + bottom: number 109 + } 110 + 111 + interface Vector2 { 112 + width: number 113 + height: number 114 + } 115 + 116 + const pathToUser32 = path.fromFileUrl( 117 + "file:///C:/Windows/System32/user32.dll", 118 + ); // jank 119 + 120 + const user32 = Deno.dlopen(pathToUser32, { 121 + SystemParametersInfoA: { 122 + parameters: ["u16", "u16", "pointer", "u16"], 123 + result: "bool", 124 + }, 125 + 126 + EnumDisplayMonitors: { 127 + parameters: ["pointer", "pointer", "pointer", "i32"], 128 + result: "bool", 129 + }, 130 + }); 131 + 132 + const monitors: Vector2[] = [] 133 + 134 + const monitorEnum = new Deno.UnsafeCallback({ 135 + parameters: ["pointer", "pointer", "pointer", "i32"], 136 + result: "bool", 137 + }, (_hMon, _hdc, lprcMonitor, _pData) => { 138 + // grab the buffer of our data... 139 + const buffer = Deno.UnsafePointerView.getArrayBuffer(lprcMonitor!, 16) 140 + // ..convert it to an Int32 array... 141 + const array = Array.from(new Int32Array(buffer)) 142 + // ..then populate: left - right top - bottom 143 + const rect = { width: Math.abs(array[2] - array[0]), height: Math.abs(array[1] - array[3]) } 144 + monitors.push(rect) 145 + 146 + return true 147 + }); 148 + 149 + user32.symbols.EnumDisplayMonitors(null, null, monitorEnum.pointer, 0); 150 + 151 + // from this point on monitorsRect is populated 152 + 153 + console.log(monitors) 154 + 155 + for (let i = 0; i < monitors.length; i++) { 156 + const monitor = monitors[i] 157 + if (monitor.width >= monitor.height) { 158 + await $`magick ${imagePaths[i]} -resize ${monitor.width}x -format "%m" ${path.join(tempImagePath, `monitorImage${i}.png`)}` 159 + } else { 160 + await $`magick ${imagePaths[i]} -resize x${monitor.height} -format "%m" ${path.join(tempImagePath, `monitorImage${i}.png`)}` 161 + } 162 + } 163 + 164 + // TODO: this isn't the right order of images 165 + console.log(await $`magick ${path.join(tempImagePath, `monitorImage*.png`)} +append ${path.join(tempImagePath, "out.png")}`) 166 + 167 + const pointer = Deno.UnsafePointer.of( 168 + Buffer.from( 169 + "C:\\Users\\angelcube\\Pictures\\wallpaper\\vocaloid_morningglory_lobelia.jpg", 170 + "ascii", 171 + ), 172 + ); 173 + 174 + user32.symbols.SystemParametersInfoA(20, 0, pointer, 3); 175 + 176 + user32.close(); 105 177 }