Via HPLIP (HP Linux Imaging and Printing), Hewlett-Packard provides Linux drivers for many HP printers and all-in-one devices. The 2840 is fully supported. These drivers consist of applications and dynamically linked libraries which can work in Cygwin in Windows The process of compiling them is not straightforward, but it's certainly not impossible. Here I will concisely describe how to compile a lite version of HPLIP with scanning and printing support.
First, note the dependencies that are listed in the manual installation page. Some of these, (such as gcc, libjpeg and libcrypto) are standard Cygwin packages. They can simply be installed via the setup program. That is the easy part. The next step is compiling the dependencies. The following instructions list the important points (such as problems and workarounds) and omit the obvious things (such as running make and "make install"). They place everything under /opt/hplip, to keep things tidy and somewhat portable.
HPLIP seems to only require a stripped-down version of Net-SNMP; basically only the library is needed. Compiling only the needed parts simplifies things and avoids some issues:
./configure --prefix=/opt/hplip --disable-agent --disable-applications --with-perl-modules=no --disable-embedded-perl
The entire agent subdirectory is not needed; remove it from SUBDIRS in the generated top level Makefile.
Windows DLLs can't have undefined symbols, and because of this libtool normally requires a -no-undefined switch to build shared libraries in Windows. In in the Cygwin section of func_mode_link () in libtool uncomment the allow_undefined=no line and comment out the yes line. Note comments explaining the issue.
Even the network scanner driver depends on CUPS. Fortunately, CUPS is easy to compile. The only problem is that the rules for generating shared libraries are for Unix only. One could add Cygwin-specific rules or set up the project for Automake and Libtool, but it's far simpler to just disable shared libraries:
LIBS=-lz ./configure --prefix=/opt/hplip --disable-shared --with-cups-group=None
After CUPS is installed, create an administration password with "lppasswd -g admin -a root" and change AuthType to BasicDigest in /opt/hplip/etc/cups/cupsd.conf. The administration interface is at http://localhost:631/ and https://localhost:631/. Note that you don't need to let cupsd through your Windows firewall to access the administration interface on localhost.
This is easiest to build. I simply configured it using:
./configure --prefix=/opt/hplip --with-group=None --disable-ipv6
When attempting to run "saned -d" before, I got "invalid fd in set, attempting to re-bind" errors. I think disabling IPv6 fixed that. In any case, I don't need IPv6.
While building tools/sane-desc, I got missing include file errors the first time. Surprisingly, retrying fixed that error.
If you get a .run file, you can get a .tar.gz by starting with the 0x1F byte after the shell script. The contents of the resulting tar.gz are not all in one directory, like with most software. That means you need to create a new directory, change to it and extract there. You can also download a .tar.gz from HP. At this point you definitely need the dependencies, so add /opt/hplip/bin to the path and use CPPFLAGS and LDFLAGS:
CPPFLAGS=-I/opt/hplip/include LDFLAGS=-L/opt/hplip/lib LIBS="-lssl -lz" ./configure --prefix=/opt/hplip --enable-hpijs-only-build=no --enable-hpijs-install=no --enable-gui-build=no --enable-dbus-build=no --enable-cups-drv-install=yes --with-cupsbackenddir=/opt/hplip/lib/cups/backend --with-cupsfilterdir=/opt/hplip/lib/cups/filter --enable-qt4=no --enable-lite-build
After this, the generated libtool again needs to be fixed. Under the "libtool link mode" comment, uncomment "allow_undefined=no" and comment out "allow_undefined=yes". In prnt/hpcups/ErnieFilter.cpp, ensure that math.h is included; remove the conditional around the include.
After "make install" copy data/models/models.dat to /opt/hplip/share/hplip/data/models/models.dat, or maybe move the whole data directory. Also, move /opt/hplip/lib/bin/cygsane-hpaio-1.dll to /opt/hplip/lib/sane/. Then, add a hpaio line to /opt/hplip/etc/sane.d/dll.conf. You can comment out all the other lines in that dll.conf and remove /etc/sane.d and the dll.conf file found there. The only file that remains outside of /opt/hplip is /etc/hp/hplip.conf. That path is hard-coded into several hplip files.
Finally, it's time to configure CUPS. You can create a URI for your printer by probing it with hp-mkuri. For example "hp-mkuri -i 184.108.40.206" would give you something like hp:/net/HP_Color_LaserJet_2840?ip=220.127.116.11 if successful. When adding a printer, choose HPLIP and enter that URI. You can find your PPD file in /opt/hplip/share/ppd/HP/ and with the 2840, CUPS can retrieve settings from the printer (it just takes a while). At that point, you can print a test page.
At this point, scanning should work. Scanning from the command line via scanimage does not need saned running because it uses the backend directly. The output goes to standard output, so be sure to redirect it. Scanning from a GUI is possible via xsane-win32 and there even TWAIN frontends for SANE. Note that although saned is designed to run under inetd, it can be run temporarily via "/opt/hplib/sbin/saned -d".
The HPLIP GUI is not available and faxing isn't supported. The LyX instructions for compiling Qt in Cygwin seem promising, but I may not work on that anytime soon because I don't need the fax features and I expect the GUI would be bloated.