Skip to content

feat(print): add initial Windows printing support via GDI#20828

Open
adinjithj wants to merge 5 commits intodarktable-org:masterfrom
adinjithj:feat/windows-printing
Open

feat(print): add initial Windows printing support via GDI#20828
adinjithj wants to merge 5 commits intodarktable-org:masterfrom
adinjithj:feat/windows-printing

Conversation

@adinjithj
Copy link
Copy Markdown

Add a Windows-native print backend (win_print.c) implementing the same API as the CUPS backend. Uses Windows GDI for printer discovery, paper enumeration, and bitmap printing.

  • Printer discovery via EnumPrinters()
  • Paper sizes via DeviceCapabilities()
  • Printer metrics via GetDeviceCaps()
  • PDF printing via ShellExecute("print")
  • Color management defaults to sRGB

Build system updated to conditionally compile the Windows backend when BUILD_PRINT is enabled on Windows, and the CUPS backend on Linux/macOS.

Refs: #19856

Add a Windows-native print backend (win_print.c) implementing the
same API as the CUPS backend. Uses Windows GDI for printer discovery,
paper enumeration, and bitmap printing.

- Printer discovery via EnumPrinters()
- Paper sizes via DeviceCapabilities()
- Printer metrics via GetDeviceCaps()
- PDF printing via ShellExecute("print")
- Color management defaults to sRGB

Build system updated to conditionally compile the Windows backend
when BUILD_PRINT is enabled on Windows, and the CUPS backend on
Linux/macOS.

Refs: darktable-org#19856
Copilot AI review requested due to automatic review settings April 17, 2026 16:45
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Windows-native printing backend to enable print mode on Windows builds, aligning with the existing CUPS-based print API used on Linux/macOS.

Changes:

  • Introduces src/common/win_print.c implementing printer discovery, paper enumeration, and PDF printing via Windows APIs.
  • Updates CMake logic to build print view/settings modules based on BUILD_PRINT (not CUPS_FOUND), and selects CUPS vs Windows backend per-platform.
  • Enables BUILD_PRINT on Windows by removing the forced disable in the top-level CMake.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/views/CMakeLists.txt Build print view module when BUILD_PRINT is enabled.
src/libs/CMakeLists.txt Build print settings module when BUILD_PRINT is enabled.
src/common/win_print.c New Windows print backend implementation using WinSpool/GDI + ShellExecute.
src/CMakeLists.txt Chooses Windows backend on WIN32, CUPS backend otherwise, and adjusts link libs/defines.
CMakeLists.txt Stops forcibly disabling BUILD_PRINT on Windows.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/common/win_print.c
Comment thread src/common/win_print.c Outdated
Comment thread src/common/win_print.c Outdated
Comment thread src/common/win_print.c
Comment thread src/common/win_print.c Outdated
Comment thread src/common/win_print.c Outdated
Comment thread src/CMakeLists.txt Outdated
Comment thread src/common/win_print.c Outdated
- Add missing <shellapi.h> include for ShellExecuteW
- Switch from ANSI (A) to wide (W) Win32 APIs for proper UTF-8
  support via g_utf8_to_utf16/g_utf16_to_utf8 conversion
- Use "WINSPOOL" as driver name in CreateDCW for reliable DC creation
- Fix printer status filter to check PAUSED, OFFLINE, NOT_AVAILABLE
  in addition to ERROR
- Check _cancel flag during printer enumeration loop for proper
  abort support
- Use "printto" verb with printer name in ShellExecuteW to target
  the user-selected printer instead of system default
- Fix sort_papers to use g_list_sort() instead of
  g_list_sort_with_data() to match its 2-argument signature
- Add gdi32 and shell32 to Windows link libraries in CMakeLists
Copy link
Copy Markdown
Member

@TurboGit TurboGit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this. Definitly something missing on Windows and we had many user requests about this.

The CI fails with:

D:/a/darktable/darktable/src/src/common/printing.c: In function 'dt_printing_setup_image':
D:/a/darktable/darktable/src/src/common/printing.c:332:16: error: 'pos.x' may be used uninitialized [-Werror=maybe-uninitialized]
  332 |   dt_image_pos pos;
      |                ^~~
compilation terminated due to -Wfatal-errors.
cc1.exe: all warnings being treated as errors

I let you look at the Copilot report.

Comment thread src/common/win_print.c Outdated
@@ -0,0 +1,472 @@
/*
This file is part of darktable,
Copyright (C) 2025 darktable developers.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2026 :)

@TurboGit TurboGit added priority: medium core features are degraded in a way that is still mostly usable, software stutters scope: windows support windows related issues and PR scope: print all cups and printing related issues feature: new new features to add labels Apr 18, 2026


- Zero-initialize dt_image_pos to fix -Wmaybe-uninitialized compiler warning

- Update copyright year in win_print.c to 2026
Copy link
Copy Markdown
Member

@TurboGit TurboGit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another GitLab CI compilation issue:

D:/a/_temp/msys64/ucrt64/include/libsecret-1 -isystem D:/a/_temp/msys64/ucrt64/include/GraphicsMagick -isystem D:/a/_temp/msys64/ucrt64/include/osmgpsmap-1.0 -isystem D:/a/_temp/msys64/ucrt64/include/libsoup-3.0 -isystem D:/a/_temp/msys64/ucrt64/include/Imath -isystem D:/a/_temp/msys64/ucrt64/include/OpenEXR -Wall -Wno-format -Wshadow -Wtype-limits -Wvla -Wold-style-declaration -Wmaybe-uninitialized -Wno-unknown-pragmas -Wno-error=varargs -Wno-format-truncation -Wno-error=address-of-packed-member -fopenmp -march=native -msse2 -g -mfpmath=sse -O3 -DNDEBUG -O3 -ffast-math -fno-finite-math-only -fexpensive-optimizations -std=c99   -DUNICODE -D_UNICODE -Werror -Wfatal-errors -MD -MT bin/CMakeFiles/lib_darktable.dir/common/win_print.c.obj -MF bin\CMakeFiles\lib_darktable.dir\common\win_print.c.obj.d -o bin/CMakeFiles/lib_darktable.dir/common/win_print.c.obj -c D:/a/darktable/darktable/src/src/common/win_print.c
In file included from D:/a/darktable/darktable/src/src/win/win.h:5,
                 from D:/a/darktable/darktable/src/src/common/darktable.h:33,
                 from D:/a/darktable/darktable/src/src/common/color_harmony.h:21,
                 from D:/a/darktable/darktable/src/src/common/image.h:21,
                 from D:/a/darktable/darktable/src/src/common/win_print.c:33:
D:/a/_temp/msys64/ucrt64/include/winsock2.h:15:2: error: #warning Please include winsock2.h before windows.h [-Werror=cpp]
   15 | #warning Please include winsock2.h before windows.h
      |  ^~~~~~~
compilation terminated due to -Wfatal-errors.
cc1.exe: all warnings being treated as errors

@adinjithj
Copy link
Copy Markdown
Author

okay i have to take a better look on this

@TurboGit TurboGit marked this pull request as draft April 19, 2026 06:49
@TurboGit
Copy link
Copy Markdown
Member

@adinjithj : Sure no urgency, I have set this to draft for now. Ping me when you think it is in a reviewable state. TIA.

Your Name added 2 commits April 19, 2026 23:46
The Windows API requires that winsock2.h must be included before windows.h
to avoid conflicts. This fix reorders the includes in win_print.c so that:
- winsock2.h is first
- windows.h follows
- Other headers follow in logical groups

This resolves the MSYS2/Windows CI build failure with:
  'winsock2.h:15: error: #warning Please include winsock2.h before windows.h'

The entire win_print.c is guarded by #ifdef _WIN32, so this change only
affects Windows builds and is safe for Linux/macOS where the file is not
compiled.
…ackend

Address potential NULL pointer dereferences when encoding conversion fails:
- Check wprinter before CreateDCW in dt_get_printer_info()
- Check name_utf8 before logging skipped printers
- Check name_utf8 before using in dt_get_printer_info()
- Check paper_name_utf8 before copying to struct
- Check both wfilename and wprinter before ShellExecuteW()

Also fix malloc -> g_malloc0 in paper enumeration for consistency with
project's glib allocation pattern.

These changes prevent crashes if g_utf16_to_utf8() or g_utf8_to_utf16()
encounter encoding errors or OOM conditions.
@adinjithj adinjithj marked this pull request as ready for review April 20, 2026 16:46
Copy link
Copy Markdown
Member

@TurboGit TurboGit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have spotted many routines just duplicated from cups_print.c. This should be avoided and have the code shared with cups_print.c.

Also, can you clarify how the printer profile (ICC) is handled on Windows?

Comment thread src/common/win_print.c
g_free(wprinter);
}

void dt_get_print_layout(const dt_print_info_t *prt,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm not mistaken this is the very same code as dt_get_print_layout found in cups_print.c. Why is it duplicated here?

Comment thread src/common/win_print.c
}
}

dt_paper_info_t *dt_get_paper(GList *papers,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very same code as in cups_print.c I think. Should not be duplicated.

Comment thread src/common/win_print.c
_cancel = 1;
}

void dt_printers_discovery(void (*cb)(dt_printer_info_t *pr, void *user_data),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost same code as in cups_print.c. Only _cancel = 0 is new here, if really needed should be added into cups_print.c too.

Comment thread src/common/win_print.c
}

// initialize the pinfo structure
void dt_init_print_info(dt_print_info_t *pinfo)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as in cups_print.c.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: new new features to add priority: medium core features are degraded in a way that is still mostly usable, software stutters scope: print all cups and printing related issues scope: windows support windows related issues and PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants