···77# Target Windows XP compatibility
88add_definitions(-DWINVER=0x0501)
99add_definitions(-D_WIN32_WINNT=0x0501)
1010+add_definitions(-D_WIN32_WINNT_WIN2K=0x0500)
1111+add_definitions(-DMINGW_HAS_SECURE_API=1)
1212+1313+# Disable threading to avoid mcfgthread dependency
1414+add_compile_options(-fno-threadsafe-statics)
1515+add_compile_options(-D_GLIBCXX_HAS_GTHREADS=0)
10161117add_executable(HelloWorldApp WIN32 main.cpp)
1218target_link_libraries(HelloWorldApp user32 gdi32)
13191414-# Minimal static linking
2020+# Include current directory for headers
2121+target_include_directories(HelloWorldApp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
2222+2323+# Minimal static linking and avoid threading dependencies
1524target_link_options(HelloWorldApp PRIVATE
1625 -static-libgcc
1726 -static-libstdc++
2727+ -static
1828 -Wl,--subsystem,windows:5.01
1929)
2030
+82-12
flake.nix
···3636 '';
37373838 buildPhase = ''
3939+ export LDFLAGS="-static -static-libgcc -static-libstdc++"
3940 cmake -DCMAKE_BUILD_TYPE=Release \
4041 -DCMAKE_SYSTEM_NAME=Windows \
4142 -DCMAKE_C_COMPILER=$CC \
4242- -DCMAKE_CXX_COMPILER=$CXX .
4343+ -DCMAKE_CXX_COMPILER=$CXX \
4444+ -DCMAKE_EXE_LINKER_FLAGS="$LDFLAGS" .
4345 make VERBOSE=1
4446 '';
4547···5254 deploy-to-xp = pkgs.writeShellScriptBin "deploy-to-xp" ''
5355 XP_DIR="$HOME/Documents/xp-drive"
5456 mkdir -p "$XP_DIR"
5555- cp ${self'.packages.hello-world-app}/bin/HelloWorld.exe "$XP_DIR/"
5656- echo "Deployed HelloWorld.exe to $XP_DIR"
5757+5858+ # Handle Windows file locking by using a temporary name first
5959+ TEMP_NAME="HelloWorld_new.exe"
6060+ OLD_NAME="HelloWorld_old.exe"
6161+ FINAL_NAME="HelloWorld.exe"
6262+6363+ echo "Deploying to $XP_DIR..."
6464+6565+ # Copy to temporary name first
6666+ if cp ${self'.packages.hello-world-app}/bin/HelloWorld.exe "$XP_DIR/$TEMP_NAME"; then
6767+ echo "✓ Copied new version as $TEMP_NAME"
6868+6969+ # If the original exists, try to rename it
7070+ if [ -f "$XP_DIR/$FINAL_NAME" ]; then
7171+ if mv "$XP_DIR/$FINAL_NAME" "$XP_DIR/$OLD_NAME" 2>/dev/null; then
7272+ echo "✓ Backed up old version as $OLD_NAME"
7373+ else
7474+ echo "⚠ Warning: Could not backup old version (file may be in use)"
7575+ echo " Close the application on XP and try again, or manually rename files"
7676+ echo " New version is available as: $TEMP_NAME"
7777+ exit 1
7878+ fi
7979+ fi
8080+8181+ # Move temp to final name
8282+ if mv "$XP_DIR/$TEMP_NAME" "$XP_DIR/$FINAL_NAME"; then
8383+ echo "✓ Deployed HelloWorld.exe successfully"
8484+8585+ # Clean up old backup if it exists
8686+ if [ -f "$XP_DIR/$OLD_NAME" ]; then
8787+ rm -f "$XP_DIR/$OLD_NAME" 2>/dev/null || echo " (Old backup file remains)"
8888+ fi
8989+ else
9090+ echo "✗ Failed to finalize deployment"
9191+ exit 1
9292+ fi
9393+ else
9494+ echo "✗ Failed to copy new version"
9595+ exit 1
9696+ fi
9797+9898+ echo ""
9999+ echo "Deployment complete! 🎉"
100100+ echo "You can now run the updated application on XP"
57101 '';
5810259103 setup-dev = pkgs.writeShellScriptBin "setup-dev" ''
60104 echo "Setting up development environment for Zed..."
6110562106 # Get the proper MinGW headers - use the known path from our build
107107+ GCC_BASE="/nix/store/l2gk3vvpdf33jf3gnfljyyx3dgwks8zp-i686-w64-mingw32-stage-final-gcc-debug-10.3.0/i686-w64-mingw32"
108108+ SYS_INCLUDE="$GCC_BASE/sys-include"
63109 MINGW_MAIN_INCLUDE="/nix/store/hhbkp872dkayzd2qxfhkdc4rgn393g52-mingw-w64-i686-w64-mingw32-9.0.0-dev/include"
110110+ MCFGTHREAD_INCLUDE="/nix/store/21c6w351iwpblnfz2m9v3ssvxcmqsz7h-mcfgthreads-i686-w64-mingw32-git-dev/include"
111111+ CPP_INCLUDE="$GCC_BASE/include/c++/10.3.0"
112112+ CPP_TARGET_INCLUDE="$CPP_INCLUDE/i686-w64-mingw32"
641136565- # Verify it exists, if not try to find it dynamically
114114+ # Verify paths exist
115115+ if [ ! -f "$SYS_INCLUDE/stdlib.h" ]; then
116116+ echo "Error: Could not find C standard library at $SYS_INCLUDE"
117117+ exit 1
118118+ fi
119119+66120 if [ ! -f "$MINGW_MAIN_INCLUDE/windows.h" ]; then
6767- echo "Static path not found, searching dynamically..."
6868- MINGW_MAIN_INCLUDE=$(i686-w64-mingw32-gcc -v -E - < /dev/null 2>&1 | sed -n '/mingw-w64.*-dev\/include/p' | head -1 | awk '{print $2}')
6969-7070- if [ -z "$MINGW_MAIN_INCLUDE" ] || [ ! -f "$MINGW_MAIN_INCLUDE/windows.h" ]; then
7171- echo "Error: Could not find proper MinGW headers with windows.h"
7272- exit 1
7373- fi
121121+ echo "Error: Could not find MinGW headers at $MINGW_MAIN_INCLUDE"
122122+ exit 1
123123+ fi
124124+125125+ if [ ! -f "$CPP_INCLUDE/vector" ]; then
126126+ echo "Error: Could not find C++ standard library at $CPP_INCLUDE"
127127+ exit 1
128128+ fi
129129+130130+ if [ ! -f "$MCFGTHREAD_INCLUDE/mcfgthread/gthread.h" ]; then
131131+ echo "Error: Could not find mcfgthread headers at $MCFGTHREAD_INCLUDE"
132132+ exit 1
74133 fi
7513476135 # Create simplified .clangd config to avoid intrinsics issues
···87146 - -std=c++17
88147 - -fno-builtin
89148 - -D__NO_INLINE__
149149+ - -isystem
150150+ - $SYS_INCLUDE
90151 - -isystem
91152 - $MINGW_MAIN_INCLUDE
153153+ - -isystem
154154+ - $MCFGTHREAD_INCLUDE
155155+ - -isystem
156156+ - $CPP_INCLUDE
157157+ - -isystem
158158+ - $CPP_TARGET_INCLUDE
92159 Remove:
93160 - -I*/gcc/*/include
94161 EOF
···105172 EOF
106173107174 echo "Generated simplified .clangd config and compile_commands.json"
175175+ echo "Using C standard library: $SYS_INCLUDE"
108176 echo "Using MinGW headers: $MINGW_MAIN_INCLUDE"
177177+ echo "Using mcfgthread headers: $MCFGTHREAD_INCLUDE"
178178+ echo "Using C++ headers: $CPP_INCLUDE"
109179 echo ""
110110- echo "This avoids GCC intrinsics that cause clang issues"
180180+ echo "This includes complete C/C++ standard libraries and Win32 APIs"
111181 echo "Restart Zed for the changes to take effect"
112182 '';
113183
+99-10
main.cpp
···11#include <windows.h>
22+#include "qr.h"
2334#define ID_ABOUT 1001
45#define ID_EXIT 1002
66+#define ID_GENERATE_QR 1003
5768LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
99+1010+// Global QR code instance - static allocation, no new/delete
1111+QRCode g_qrCode;
1212+BOOL g_hasQrCode = FALSE;
1313+char g_qrText[256] = "Hello World!";
714815int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) {
916 const char* CLASS_NAME = "HelloWorldWindow";
···34413542 // Create menu
3643 HMENU hMenu = CreateMenu();
3737- HMENU hSubMenu = CreatePopupMenu();
38443939- AppendMenu(hSubMenu, MF_STRING, ID_ABOUT, "&About");
4040- AppendMenu(hSubMenu, MF_SEPARATOR, 0, NULL);
4141- AppendMenu(hSubMenu, MF_STRING, ID_EXIT, "E&xit");
4242- AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hSubMenu, "&Help");
4545+ // Tools menu
4646+ HMENU hToolsMenu = CreatePopupMenu();
4747+ AppendMenu(hToolsMenu, MF_STRING, ID_GENERATE_QR, "&Generate QR Pattern");
4848+ AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hToolsMenu, "&Tools");
4949+5050+ // Help menu
5151+ HMENU hHelpMenu = CreatePopupMenu();
5252+ AppendMenu(hHelpMenu, MF_STRING, ID_ABOUT, "&About");
5353+ AppendMenu(hHelpMenu, MF_SEPARATOR, 0, NULL);
5454+ AppendMenu(hHelpMenu, MF_STRING, ID_EXIT, "E&xit");
5555+ AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hHelpMenu, "&Help");
43564457 SetMenu(hwnd, hMenu);
4558···57705871LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
5972 switch (uMsg) {
7373+ case WM_SIZE:
7474+ // Trigger repaint when window is resized
7575+ InvalidateRect(hwnd, NULL, TRUE);
7676+ return 0;
7777+6078 case WM_DESTROY:
7979+ // No cleanup needed for static allocation
6180 PostQuitMessage(0);
6281 return 0;
6382···6887 RECT rect;
6988 GetClientRect(hwnd, &rect);
70897171- // Center the text
7272- SetTextAlign(hdc, TA_CENTER);
7373- SetBkMode(hdc, TRANSPARENT);
7474- TextOut(hdc, rect.right / 2, rect.bottom / 2 - 10, "Hello World!", 12);
9090+ if (g_hasQrCode) {
9191+ // Draw QR code - calculate size based on window
9292+ int qrSize = QRCode_GetSize();
9393+ int moduleSize = 8;
9494+ int qrPixelSize = qrSize * moduleSize;
9595+9696+ // Center horizontally and vertically with some padding
9797+ int startX = (rect.right - qrPixelSize) / 2;
9898+ int startY = (rect.bottom - qrPixelSize - 80) / 2; // Leave space for text
9999+100100+ QRCode_DrawToHDC(&g_qrCode, hdc, startX, startY, moduleSize);
101101+102102+ // Draw text below QR code
103103+ SetTextAlign(hdc, TA_CENTER);
104104+ SetBkMode(hdc, TRANSPARENT);
105105+ int textLen = 0;
106106+ while (g_qrText[textLen]) textLen++; // Calculate length
107107+ TextOut(hdc, rect.right / 2, startY + qrPixelSize + 20,
108108+ g_qrText, textLen);
109109+110110+ // Add disclaimer
111111+ const char* disclaimer = "(Visual demo - not scannable)";
112112+ int disclaimerLen = 0;
113113+ while (disclaimer[disclaimerLen]) disclaimerLen++;
114114+ TextOut(hdc, rect.right / 2, startY + qrPixelSize + 40,
115115+ disclaimer, disclaimerLen);
116116+ } else {
117117+ // Default view - center in current window size
118118+ SetTextAlign(hdc, TA_CENTER);
119119+ SetBkMode(hdc, TRANSPARENT);
120120+ int centerY = rect.bottom / 2;
121121+ TextOut(hdc, rect.right / 2, centerY - 10, "Hello World!", 12);
122122+ TextOut(hdc, rect.right / 2, centerY + 10,
123123+ "Use Tools > Generate QR Pattern", 32);
124124+ }
7512576126 EndPaint(hwnd, &ps);
77127 return 0;
···84134 "Version: 1.0.0\n"
85135 "Built by: Kieran Klukas\n\n"
86136 "A simple Win32 application\n"
8787- "compatible with Windows XP";
137137+ "compatible with Windows XP\n\n"
138138+ "Features:\n"
139139+ "- QR Pattern Generation (visual demo)\n"
140140+ "- XP Compatible Design\n"
141141+ "- Pure Win32 API";
88142 MessageBox(hwnd, aboutText, "About Hello World App",
89143 MB_OK | MB_ICONINFORMATION);
144144+ break;
145145+ }
146146+ case ID_GENERATE_QR: {
147147+ // Simple input dialog using InputBox simulation
148148+ if (MessageBox(hwnd, "Generate QR code pattern for current text?\n\n(Note: This creates a visual QR-like pattern for demo purposes,\nnot a scannable QR code)\n\nClick OK to use default text,\nor Cancel to cycle through presets.",
149149+ "Generate QR Pattern", MB_OKCANCEL | MB_ICONQUESTION) == IDCANCEL) {
150150+151151+ // For now, use a simple preset - in a real app you'd want a proper input dialog
152152+ const char* presets[] = {
153153+ "Hello World!",
154154+ "https://github.com/taciturnaxolotl/shortwave",
155155+ "Made with love by Kieran Klukas",
156156+ "Windows XP Forever!",
157157+ "QR codes are cool!"
158158+ };
159159+160160+ static int presetIndex = 0;
161161+ const char* selectedText = presets[presetIndex % 5];
162162+ presetIndex++;
163163+164164+ // Copy selected text to global buffer
165165+ int i = 0;
166166+ while (selectedText[i] && i < 255) {
167167+ g_qrText[i] = selectedText[i];
168168+ i++;
169169+ }
170170+ g_qrText[i] = '\0';
171171+ }
172172+173173+ // Generate new QR code - no new/delete, just reinitialize
174174+ QRCode_Init(&g_qrCode, g_qrText);
175175+ g_hasQrCode = TRUE;
176176+177177+ // Refresh the window
178178+ InvalidateRect(hwnd, NULL, TRUE);
90179 break;
91180 }
92181 case ID_EXIT:
+176
qr.h
···11+#pragma once
22+#include <windows.h>
33+44+#define QR_SIZE 21
55+#define MAX_TEXT_LEN 256
66+77+// Pure C struct for QR code - no C++ classes
88+typedef struct {
99+ BOOL modules[QR_SIZE][QR_SIZE];
1010+ char text[MAX_TEXT_LEN];
1111+} QRCode;
1212+1313+// Function prototypes
1414+void QRCode_Init(QRCode* qr, const char* inputText);
1515+void QRCode_GeneratePattern(QRCode* qr);
1616+void QRCode_AddFinderPattern(QRCode* qr, int x, int y);
1717+BOOL QRCode_IsReserved(int x, int y);
1818+void QRCode_DrawToHDC(QRCode* qr, HDC hdc, int startX, int startY, int moduleSize);
1919+int QRCode_GetSize(void);
2020+const char* QRCode_GetText(QRCode* qr);
2121+2222+// Implementation
2323+void QRCode_Init(QRCode* qr, const char* inputText) {
2424+ int x, y, i;
2525+2626+ // Initialize modules array
2727+ for (y = 0; y < QR_SIZE; y++) {
2828+ for (x = 0; x < QR_SIZE; x++) {
2929+ qr->modules[y][x] = FALSE;
3030+ }
3131+ }
3232+3333+ // Copy text (safe copy)
3434+ i = 0;
3535+ while (inputText[i] && i < MAX_TEXT_LEN - 1) {
3636+ qr->text[i] = inputText[i];
3737+ i++;
3838+ }
3939+ qr->text[i] = '\0';
4040+4141+ // Generate pattern
4242+ QRCode_GeneratePattern(qr);
4343+}
4444+4545+void QRCode_GeneratePattern(QRCode* qr) {
4646+ int i, x, y;
4747+ unsigned int hash = 0;
4848+ unsigned char textBytes[MAX_TEXT_LEN];
4949+ int textLen = 0;
5050+5151+ // Add finder patterns (corners)
5252+ QRCode_AddFinderPattern(qr, 0, 0);
5353+ QRCode_AddFinderPattern(qr, QR_SIZE - 7, 0);
5454+ QRCode_AddFinderPattern(qr, 0, QR_SIZE - 7);
5555+5656+ // Add timing patterns
5757+ for (i = 8; i < QR_SIZE - 8; i++) {
5858+ qr->modules[6][i] = (i % 2 == 0) ? TRUE : FALSE;
5959+ qr->modules[i][6] = (i % 2 == 0) ? TRUE : FALSE;
6060+ }
6161+6262+ // Convert text to bytes and calculate length
6363+ while (qr->text[textLen] && textLen < MAX_TEXT_LEN - 1) {
6464+ textBytes[textLen] = (unsigned char)qr->text[textLen];
6565+ textLen++;
6666+ }
6767+6868+ // Add format information (fake but realistic looking)
6969+ // These would normally encode error correction level and mask pattern
7070+ qr->modules[8][0] = TRUE;
7171+ qr->modules[8][1] = FALSE;
7272+ qr->modules[8][2] = TRUE;
7373+ qr->modules[8][3] = TRUE;
7474+ qr->modules[8][4] = FALSE;
7575+ qr->modules[8][5] = TRUE;
7676+7777+ // Add data in a more realistic zigzag pattern
7878+ int bitIndex = 0;
7979+ BOOL upward = TRUE;
8080+8181+ for (x = QR_SIZE - 1; x > 0; x -= 2) {
8282+ if (x == 6) x--; // Skip timing column
8383+8484+ for (i = 0; i < QR_SIZE; i++) {
8585+ y = upward ? (QR_SIZE - 1 - i) : i;
8686+8787+ // Fill two columns (right to left)
8888+ for (int col = 0; col < 2; col++) {
8989+ int currentX = x - col;
9090+ if (currentX >= 0 && !QRCode_IsReserved(currentX, y)) {
9191+ // Use text data in a more structured way
9292+ BOOL bit = FALSE;
9393+ if (bitIndex < textLen * 8) {
9494+ int byteIndex = bitIndex / 8;
9595+ int bitPos = 7 - (bitIndex % 8);
9696+ bit = (textBytes[byteIndex] >> bitPos) & 1;
9797+ bitIndex++;
9898+ } else {
9999+ // Padding pattern
100100+ bit = ((currentX + y) % 3 == 0) ? TRUE : FALSE;
101101+ }
102102+ qr->modules[y][currentX] = bit;
103103+ }
104104+ }
105105+ }
106106+ upward = !upward;
107107+ }
108108+}
109109+110110+void QRCode_AddFinderPattern(QRCode* qr, int x, int y) {
111111+ int dx, dy;
112112+ BOOL dark;
113113+114114+ for (dy = 0; dy < 7; dy++) {
115115+ for (dx = 0; dx < 7; dx++) {
116116+ if (x + dx < QR_SIZE && y + dy < QR_SIZE) {
117117+ dark = (dx == 0 || dx == 6 || dy == 0 || dy == 6 ||
118118+ (dx >= 2 && dx <= 4 && dy >= 2 && dy <= 4)) ? TRUE : FALSE;
119119+ qr->modules[y + dy][x + dx] = dark;
120120+ }
121121+ }
122122+ }
123123+}
124124+125125+BOOL QRCode_IsReserved(int x, int y) {
126126+ // Check if position is part of finder patterns
127127+ if ((x < 9 && y < 9) ||
128128+ (x >= QR_SIZE - 8 && y < 9) ||
129129+ (x < 9 && y >= QR_SIZE - 8)) {
130130+ return TRUE;
131131+ }
132132+133133+ // Check timing patterns
134134+ if (x == 6 || y == 6) {
135135+ return TRUE;
136136+ }
137137+138138+ // Check format information areas
139139+ if ((x < 9 && y == 8) || (x == 8 && y < 9)) {
140140+ return TRUE;
141141+ }
142142+ if ((x >= QR_SIZE - 8 && y == 8) || (x == 8 && y >= QR_SIZE - 7)) {
143143+ return TRUE;
144144+ }
145145+146146+ return FALSE;
147147+}
148148+149149+void QRCode_DrawToHDC(QRCode* qr, HDC hdc, int startX, int startY, int moduleSize) {
150150+ HBRUSH blackBrush = CreateSolidBrush(RGB(0, 0, 0));
151151+ HBRUSH whiteBrush = CreateSolidBrush(RGB(255, 255, 255));
152152+ int x, y;
153153+ RECT rect;
154154+155155+ for (y = 0; y < QR_SIZE; y++) {
156156+ for (x = 0; x < QR_SIZE; x++) {
157157+ rect.left = startX + x * moduleSize;
158158+ rect.top = startY + y * moduleSize;
159159+ rect.right = startX + (x + 1) * moduleSize;
160160+ rect.bottom = startY + (y + 1) * moduleSize;
161161+162162+ FillRect(hdc, &rect, qr->modules[y][x] ? blackBrush : whiteBrush);
163163+ }
164164+ }
165165+166166+ DeleteObject(blackBrush);
167167+ DeleteObject(whiteBrush);
168168+}
169169+170170+int QRCode_GetSize(void) {
171171+ return QR_SIZE;
172172+}
173173+174174+const char* QRCode_GetText(QRCode* qr) {
175175+ return qr->text;
176176+}