Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 1 | /* |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 2 | * PostScript driver initialization functions |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3 | * |
| 4 | * Copyright 1998 Huw D M Davies |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 5 | * Copyright 2001 Marcus Meissner |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 6 | * |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 7 | * This library is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU Lesser General Public |
| 9 | * License as published by the Free Software Foundation; either |
| 10 | * version 2.1 of the License, or (at your option) any later version. |
| 11 | * |
| 12 | * This library is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | * Lesser General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU Lesser General Public |
| 18 | * License along with this library; if not, write to the Free Software |
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 20 | */ |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 21 | |
Patrik Stridvall | 172cd1b | 2001-06-11 20:16:11 +0000 | [diff] [blame] | 22 | #include "config.h" |
Marcus Meissner | f061f76 | 2002-11-12 02:22:24 +0000 | [diff] [blame] | 23 | #include "wine/port.h" |
Patrik Stridvall | 172cd1b | 2001-06-11 20:16:11 +0000 | [diff] [blame] | 24 | |
Jeff Garzik | c3e1f72 | 1999-02-19 15:42:11 +0000 | [diff] [blame] | 25 | #include <string.h> |
Patrik Stridvall | d016f81 | 2002-08-17 00:43:16 +0000 | [diff] [blame] | 26 | #ifdef HAVE_UNISTD_H |
| 27 | # include <unistd.h> |
| 28 | #endif |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 29 | |
Dimitrie O. Paun | 297f3d8 | 2003-01-07 20:36:20 +0000 | [diff] [blame] | 30 | #define NONAMELESSUNION |
| 31 | #define NONAMELESSSTRUCT |
Alexandre Julliard | a0d7731 | 1998-09-13 16:32:00 +0000 | [diff] [blame] | 32 | #include "psdrv.h" |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 33 | #include "wine/debug.h" |
Alexandre Julliard | a0d7731 | 1998-09-13 16:32:00 +0000 | [diff] [blame] | 34 | #include "winreg.h" |
Alexandre Julliard | 5954560 | 1999-02-10 06:52:57 +0000 | [diff] [blame] | 35 | #include "winspool.h" |
Alexandre Julliard | a0d7731 | 1998-09-13 16:32:00 +0000 | [diff] [blame] | 36 | #include "winerror.h" |
Huw Davies | 9fb3f4e | 2003-11-09 00:26:50 +0000 | [diff] [blame] | 37 | #include "wownt32.h" |
Dmitry Timoshkov | 3a910c7 | 2003-08-12 20:42:18 +0000 | [diff] [blame] | 38 | #include "heap.h" |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 39 | |
Marcus Meissner | f061f76 | 2002-11-12 02:22:24 +0000 | [diff] [blame] | 40 | WINE_DEFAULT_DEBUG_CHANNEL(psdrv); |
| 41 | |
| 42 | #ifdef HAVE_CUPS_CUPS_H |
| 43 | #include <cups/cups.h> |
| 44 | |
Marcus Meissner | 26b9bca | 2003-03-07 20:36:08 +0000 | [diff] [blame] | 45 | #ifndef SONAME_LIBCUPS |
| 46 | #define SONAME_LIBCUPS "libcups.so" |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 47 | #endif |
| 48 | |
Marcus Meissner | f061f76 | 2002-11-12 02:22:24 +0000 | [diff] [blame] | 49 | static void *cupshandle = NULL; |
| 50 | #endif |
Patrik Stridvall | b4b9fae | 1999-04-19 14:56:29 +0000 | [diff] [blame] | 51 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 52 | static PSDRV_DEVMODEA DefaultDevmode = |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 53 | { |
| 54 | { /* dmPublic */ |
| 55 | /* dmDeviceName */ "Wine PostScript Driver", |
| 56 | /* dmSpecVersion */ 0x30a, |
| 57 | /* dmDriverVersion */ 0x001, |
Huw D M Davies | e39b676 | 1999-05-17 16:20:51 +0000 | [diff] [blame] | 58 | /* dmSize */ sizeof(DEVMODEA), |
Marcus Meissner | 0f53dbf | 2002-11-04 22:37:57 +0000 | [diff] [blame] | 59 | /* dmDriverExtra */ sizeof(PSDRV_DEVMODEA)-sizeof(DEVMODEA), |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 60 | /* dmFields */ DM_ORIENTATION | DM_PAPERSIZE | DM_SCALE | |
| 61 | DM_COPIES | DM_DEFAULTSOURCE | DM_COLOR | |
Huw Davies | 83d6e26 | 2003-11-05 00:37:47 +0000 | [diff] [blame] | 62 | DM_YRESOLUTION | DM_TTOPTION, |
Huw D M Davies | e39b676 | 1999-05-17 16:20:51 +0000 | [diff] [blame] | 63 | { /* u1 */ |
| 64 | { /* s1 */ |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 65 | /* dmOrientation */ DMORIENT_PORTRAIT, |
Huw D M Davies | 7526fc5 | 2002-04-06 00:04:31 +0000 | [diff] [blame] | 66 | /* dmPaperSize */ DMPAPER_LETTER, |
| 67 | /* dmPaperLength */ 2794, |
| 68 | /* dmPaperWidth */ 2159 |
Huw D M Davies | e39b676 | 1999-05-17 16:20:51 +0000 | [diff] [blame] | 69 | } |
| 70 | }, |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 71 | /* dmScale */ 100, /* ?? */ |
| 72 | /* dmCopies */ 1, |
| 73 | /* dmDefaultSource */ DMBIN_AUTO, |
| 74 | /* dmPrintQuality */ 0, |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 75 | /* dmColor */ DMCOLOR_COLOR, |
Huw Davies | 83d6e26 | 2003-11-05 00:37:47 +0000 | [diff] [blame] | 76 | /* dmDuplex */ DMDUP_SIMPLEX, |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 77 | /* dmYResolution */ 0, |
| 78 | /* dmTTOption */ DMTT_SUBDEV, |
| 79 | /* dmCollate */ 0, |
| 80 | /* dmFormName */ "", |
| 81 | /* dmUnusedPadding */ 0, |
| 82 | /* dmBitsPerPel */ 0, |
| 83 | /* dmPelsWidth */ 0, |
| 84 | /* dmPelsHeight */ 0, |
| 85 | /* dmDisplayFlags */ 0, |
Patrik Stridvall | a9f6a9d | 2000-10-24 02:22:16 +0000 | [diff] [blame] | 86 | /* dmDisplayFrequency */ 0, |
| 87 | /* dmICMMethod */ 0, |
| 88 | /* dmICMIntent */ 0, |
| 89 | /* dmMediaType */ 0, |
| 90 | /* dmDitherType */ 0, |
| 91 | /* dmReserved1 */ 0, |
| 92 | /* dmReserved2 */ 0, |
| 93 | /* dmPanningWidth */ 0, |
| 94 | /* dmPanningHeight */ 0 |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 95 | }, |
| 96 | { /* dmDocPrivate */ |
Patrik Stridvall | a9f6a9d | 2000-10-24 02:22:16 +0000 | [diff] [blame] | 97 | /* dummy */ 0 |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 98 | }, |
| 99 | { /* dmDrvPrivate */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 100 | /* numInstalledOptions */ 0 |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 101 | } |
| 102 | }; |
| 103 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 104 | HANDLE PSDRV_Heap = 0; |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 105 | |
Alexandre Julliard | 83decd2 | 2004-03-04 06:26:11 +0000 | [diff] [blame] | 106 | static HFONT PSDRV_DefaultFont = 0; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 107 | static LOGFONTA DefaultLogFont = { |
Alexandre Julliard | 85ed45e | 1998-08-22 19:03:56 +0000 | [diff] [blame] | 108 | 100, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, 0, 0, |
| 109 | DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" |
| 110 | }; |
| 111 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 112 | /********************************************************************* |
Alexandre Julliard | 1e1313d | 2002-11-04 23:53:41 +0000 | [diff] [blame] | 113 | * DllMain |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 114 | * |
Alexandre Julliard | 1e1313d | 2002-11-04 23:53:41 +0000 | [diff] [blame] | 115 | * Initializes font metrics and registers driver. wineps dll entry point. |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 116 | * |
| 117 | */ |
Alexandre Julliard | 1e1313d | 2002-11-04 23:53:41 +0000 | [diff] [blame] | 118 | BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 119 | { |
Alexandre Julliard | b34fb35 | 2002-10-18 23:48:57 +0000 | [diff] [blame] | 120 | TRACE("(%p, 0x%08lx, %p)\n", hinst, reason, reserved); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 121 | |
Dimitrie O. Paun | 84bde6a | 2000-05-30 20:27:23 +0000 | [diff] [blame] | 122 | switch(reason) { |
Ian Pilcher | 2ce7bc8 | 2001-04-30 18:17:13 +0000 | [diff] [blame] | 123 | |
Dimitrie O. Paun | 84bde6a | 2000-05-30 20:27:23 +0000 | [diff] [blame] | 124 | case DLL_PROCESS_ATTACH: |
Dmitry Timoshkov | 4e1ef0c | 2003-06-30 20:53:48 +0000 | [diff] [blame] | 125 | DisableThreadLibraryCalls(hinst); |
Ian Pilcher | 2ce7bc8 | 2001-04-30 18:17:13 +0000 | [diff] [blame] | 126 | |
| 127 | PSDRV_Heap = HeapCreate(0, 0x10000, 0); |
Francois Gouget | 9b0b1e0 | 2003-01-14 23:43:41 +0000 | [diff] [blame] | 128 | if (PSDRV_Heap == NULL) |
Ian Pilcher | 2ce7bc8 | 2001-04-30 18:17:13 +0000 | [diff] [blame] | 129 | return FALSE; |
| 130 | |
| 131 | if (PSDRV_GetFontMetrics() == FALSE) { |
| 132 | HeapDestroy(PSDRV_Heap); |
| 133 | return FALSE; |
| 134 | } |
| 135 | |
| 136 | PSDRV_DefaultFont = CreateFontIndirectA(&DefaultLogFont); |
Francois Gouget | 9b0b1e0 | 2003-01-14 23:43:41 +0000 | [diff] [blame] | 137 | if (PSDRV_DefaultFont == NULL) { |
Ian Pilcher | 2ce7bc8 | 2001-04-30 18:17:13 +0000 | [diff] [blame] | 138 | HeapDestroy(PSDRV_Heap); |
| 139 | return FALSE; |
| 140 | } |
Marcus Meissner | f061f76 | 2002-11-12 02:22:24 +0000 | [diff] [blame] | 141 | #ifdef HAVE_CUPS_CUPS_H |
| 142 | /* dynamically load CUPS if not yet loaded */ |
| 143 | if (!cupshandle) { |
Marcus Meissner | 26b9bca | 2003-03-07 20:36:08 +0000 | [diff] [blame] | 144 | cupshandle = wine_dlopen(SONAME_LIBCUPS, RTLD_NOW, NULL, 0); |
Marcus Meissner | f061f76 | 2002-11-12 02:22:24 +0000 | [diff] [blame] | 145 | if (!cupshandle) cupshandle = (void*)-1; |
| 146 | } |
| 147 | #endif |
Ian Pilcher | 2ce7bc8 | 2001-04-30 18:17:13 +0000 | [diff] [blame] | 148 | break; |
| 149 | |
Dimitrie O. Paun | 84bde6a | 2000-05-30 20:27:23 +0000 | [diff] [blame] | 150 | case DLL_PROCESS_DETACH: |
Ian Pilcher | 2ce7bc8 | 2001-04-30 18:17:13 +0000 | [diff] [blame] | 151 | |
| 152 | DeleteObject( PSDRV_DefaultFont ); |
| 153 | HeapDestroy( PSDRV_Heap ); |
Marcus Meissner | f061f76 | 2002-11-12 02:22:24 +0000 | [diff] [blame] | 154 | #ifdef HAVE_CUPS_CUPS_H |
| 155 | if (cupshandle && (cupshandle != (void*)-1)) { |
| 156 | wine_dlclose(cupshandle, NULL, 0); |
| 157 | cupshandle = NULL; |
| 158 | } |
| 159 | #endif |
Ian Pilcher | 2ce7bc8 | 2001-04-30 18:17:13 +0000 | [diff] [blame] | 160 | break; |
Dimitrie O. Paun | 84bde6a | 2000-05-30 20:27:23 +0000 | [diff] [blame] | 161 | } |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 162 | |
Dimitrie O. Paun | 84bde6a | 2000-05-30 20:27:23 +0000 | [diff] [blame] | 163 | return TRUE; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 164 | } |
| 165 | |
Dimitrie O. Paun | 84bde6a | 2000-05-30 20:27:23 +0000 | [diff] [blame] | 166 | |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 167 | static void PSDRV_UpdateDevCaps( PSDRV_PDEVICE *physDev ) |
| 168 | { |
| 169 | PAGESIZE *page; |
| 170 | INT width = 0, height = 0; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 171 | |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 172 | if(physDev->Devmode->dmPublic.dmFields & DM_PAPERSIZE) { |
| 173 | for(page = physDev->pi->ppd->PageSizes; page; page = page->next) { |
| 174 | if(page->WinPage == physDev->Devmode->dmPublic.u1.s1.dmPaperSize) |
| 175 | break; |
| 176 | } |
| 177 | |
| 178 | if(!page) { |
| 179 | FIXME("Can't find page\n"); |
| 180 | physDev->ImageableArea.left = 0; |
| 181 | physDev->ImageableArea.right = 0; |
| 182 | physDev->ImageableArea.bottom = 0; |
| 183 | physDev->ImageableArea.top = 0; |
| 184 | physDev->PageSize.cx = 0; |
| 185 | physDev->PageSize.cy = 0; |
| 186 | } else if(page->ImageableArea) { |
| 187 | /* physDev sizes in device units; ppd sizes in 1/72" */ |
| 188 | physDev->ImageableArea.left = page->ImageableArea->llx * |
| 189 | physDev->logPixelsX / 72; |
| 190 | physDev->ImageableArea.right = page->ImageableArea->urx * |
| 191 | physDev->logPixelsX / 72; |
| 192 | physDev->ImageableArea.bottom = page->ImageableArea->lly * |
| 193 | physDev->logPixelsY / 72; |
| 194 | physDev->ImageableArea.top = page->ImageableArea->ury * |
| 195 | physDev->logPixelsY / 72; |
| 196 | physDev->PageSize.cx = page->PaperDimension->x * |
| 197 | physDev->logPixelsX / 72; |
| 198 | physDev->PageSize.cy = page->PaperDimension->y * |
| 199 | physDev->logPixelsY / 72; |
| 200 | } else { |
| 201 | physDev->ImageableArea.left = physDev->ImageableArea.bottom = 0; |
| 202 | physDev->ImageableArea.right = physDev->PageSize.cx = |
| 203 | page->PaperDimension->x * physDev->logPixelsX / 72; |
| 204 | physDev->ImageableArea.top = physDev->PageSize.cy = |
| 205 | page->PaperDimension->y * physDev->logPixelsY / 72; |
| 206 | } |
| 207 | } else if((physDev->Devmode->dmPublic.dmFields & DM_PAPERLENGTH) && |
| 208 | (physDev->Devmode->dmPublic.dmFields & DM_PAPERWIDTH)) { |
| 209 | /* physDev sizes in device units; Devmode sizes in 1/10 mm */ |
| 210 | physDev->ImageableArea.left = physDev->ImageableArea.bottom = 0; |
| 211 | physDev->ImageableArea.right = physDev->PageSize.cx = |
| 212 | physDev->Devmode->dmPublic.u1.s1.dmPaperWidth * |
| 213 | physDev->logPixelsX / 254; |
| 214 | physDev->ImageableArea.top = physDev->PageSize.cy = |
| 215 | physDev->Devmode->dmPublic.u1.s1.dmPaperLength * |
| 216 | physDev->logPixelsY / 254; |
| 217 | } else { |
| 218 | FIXME("Odd dmFields %lx\n", physDev->Devmode->dmPublic.dmFields); |
| 219 | physDev->ImageableArea.left = 0; |
| 220 | physDev->ImageableArea.right = 0; |
| 221 | physDev->ImageableArea.bottom = 0; |
| 222 | physDev->ImageableArea.top = 0; |
| 223 | physDev->PageSize.cx = 0; |
| 224 | physDev->PageSize.cy = 0; |
| 225 | } |
| 226 | |
Dan Kegel | 0fd521f | 2003-01-08 21:09:25 +0000 | [diff] [blame] | 227 | TRACE("ImageableArea = %ld,%ld - %ld,%ld: PageSize = %ldx%ld\n", |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 228 | physDev->ImageableArea.left, physDev->ImageableArea.bottom, |
| 229 | physDev->ImageableArea.right, physDev->ImageableArea.top, |
| 230 | physDev->PageSize.cx, physDev->PageSize.cy); |
| 231 | |
| 232 | /* these are in device units */ |
| 233 | width = physDev->ImageableArea.right - physDev->ImageableArea.left; |
| 234 | height = physDev->ImageableArea.top - physDev->ImageableArea.bottom; |
| 235 | |
| 236 | if(physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_PORTRAIT) { |
| 237 | physDev->horzRes = width; |
| 238 | physDev->vertRes = height; |
| 239 | } else { |
| 240 | physDev->horzRes = height; |
| 241 | physDev->vertRes = width; |
| 242 | } |
| 243 | |
| 244 | /* these are in mm */ |
| 245 | physDev->horzSize = (physDev->horzRes * 25.4) / physDev->logPixelsX; |
| 246 | physDev->vertSize = (physDev->vertRes * 25.4) / physDev->logPixelsY; |
| 247 | |
| 248 | TRACE("devcaps: horzSize = %dmm, vertSize = %dmm, " |
| 249 | "horzRes = %d, vertRes = %d\n", |
| 250 | physDev->horzSize, physDev->vertSize, |
| 251 | physDev->horzRes, physDev->vertRes); |
| 252 | } |
| 253 | |
| 254 | |
Dmitry Timoshkov | 3a910c7 | 2003-08-12 20:42:18 +0000 | [diff] [blame] | 255 | /*********************************************************** |
| 256 | * DEVMODEdupWtoA |
| 257 | * |
| 258 | * Creates an ascii copy of supplied devmode on heap |
| 259 | * |
| 260 | * Copied from dlls/winspool/info.c until full unicodification |
| 261 | */ |
| 262 | static LPDEVMODEA DEVMODEdupWtoA(HANDLE heap, const DEVMODEW *dmW) |
| 263 | { |
| 264 | LPDEVMODEA dmA; |
| 265 | DWORD size; |
| 266 | BOOL Formname; |
Eric Pouech | 0a25896 | 2004-11-30 21:38:57 +0000 | [diff] [blame] | 267 | ptrdiff_t off_formname = (const char *)dmW->dmFormName - (const char *)dmW; |
Dmitry Timoshkov | 3a910c7 | 2003-08-12 20:42:18 +0000 | [diff] [blame] | 268 | |
| 269 | if(!dmW) return NULL; |
| 270 | Formname = (dmW->dmSize > off_formname); |
| 271 | size = dmW->dmSize - CCHDEVICENAME - (Formname ? CCHFORMNAME : 0); |
| 272 | dmA = HeapAlloc(heap, HEAP_ZERO_MEMORY, size + dmW->dmDriverExtra); |
| 273 | WideCharToMultiByte(CP_ACP, 0, dmW->dmDeviceName, -1, dmA->dmDeviceName, |
| 274 | CCHDEVICENAME, NULL, NULL); |
| 275 | if(!Formname) { |
| 276 | memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion, |
| 277 | dmW->dmSize - CCHDEVICENAME * sizeof(WCHAR)); |
| 278 | } else { |
| 279 | memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion, |
| 280 | off_formname - CCHDEVICENAME * sizeof(WCHAR)); |
| 281 | WideCharToMultiByte(CP_ACP, 0, dmW->dmFormName, -1, dmA->dmFormName, |
| 282 | CCHFORMNAME, NULL, NULL); |
| 283 | memcpy(&dmA->dmLogPixels, &dmW->dmLogPixels, dmW->dmSize - |
| 284 | (off_formname + CCHFORMNAME * sizeof(WCHAR))); |
| 285 | } |
| 286 | dmA->dmSize = size; |
Eric Pouech | 0a25896 | 2004-11-30 21:38:57 +0000 | [diff] [blame] | 287 | memcpy((char *)dmA + dmA->dmSize, (const char *)dmW + dmW->dmSize, |
Dmitry Timoshkov | 3a910c7 | 2003-08-12 20:42:18 +0000 | [diff] [blame] | 288 | dmW->dmDriverExtra); |
| 289 | return dmA; |
| 290 | } |
| 291 | |
| 292 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 293 | /********************************************************************** |
| 294 | * PSDRV_CreateDC |
| 295 | */ |
Alexandre Julliard | 83decd2 | 2004-03-04 06:26:11 +0000 | [diff] [blame] | 296 | BOOL PSDRV_CreateDC( HDC hdc, PSDRV_PDEVICE **pdev, LPCWSTR driver, LPCWSTR device, |
Dmitry Timoshkov | 3a910c7 | 2003-08-12 20:42:18 +0000 | [diff] [blame] | 297 | LPCWSTR output, const DEVMODEW* initData ) |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 298 | { |
| 299 | PSDRV_PDEVICE *physDev; |
Noel Borthwick | 86b686f | 1999-06-05 08:52:30 +0000 | [diff] [blame] | 300 | PRINTERINFO *pi; |
Dmitry Timoshkov | 3a910c7 | 2003-08-12 20:42:18 +0000 | [diff] [blame] | 301 | char deviceA[CCHDEVICENAME]; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 302 | |
Noel Borthwick | 86b686f | 1999-06-05 08:52:30 +0000 | [diff] [blame] | 303 | /* If no device name was specified, retrieve the device name |
| 304 | * from the DEVMODE structure from the DC's physDev. |
| 305 | * (See CreateCompatibleDC) */ |
Alexandre Julliard | d3cab18 | 2002-06-10 22:52:47 +0000 | [diff] [blame] | 306 | if ( !device && *pdev ) |
Noel Borthwick | 86b686f | 1999-06-05 08:52:30 +0000 | [diff] [blame] | 307 | { |
Alexandre Julliard | d3cab18 | 2002-06-10 22:52:47 +0000 | [diff] [blame] | 308 | physDev = *pdev; |
Dmitry Timoshkov | 3a910c7 | 2003-08-12 20:42:18 +0000 | [diff] [blame] | 309 | strcpy(deviceA, physDev->Devmode->dmPublic.dmDeviceName); |
Noel Borthwick | 86b686f | 1999-06-05 08:52:30 +0000 | [diff] [blame] | 310 | } |
Dmitry Timoshkov | 3a910c7 | 2003-08-12 20:42:18 +0000 | [diff] [blame] | 311 | else |
| 312 | WideCharToMultiByte(CP_ACP, 0, device, -1, deviceA, sizeof(deviceA), NULL, NULL); |
| 313 | pi = PSDRV_FindPrinterInfo(deviceA); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 314 | |
Dmitry Timoshkov | 3a910c7 | 2003-08-12 20:42:18 +0000 | [diff] [blame] | 315 | TRACE("(%s %s %s %p)\n", debugstr_w(driver), debugstr_w(device), |
| 316 | debugstr_w(output), initData); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 317 | |
Alexandre Julliard | a0d7731 | 1998-09-13 16:32:00 +0000 | [diff] [blame] | 318 | if(!pi) return FALSE; |
| 319 | |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 320 | if(!pi->Fonts) { |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 321 | MESSAGE("To use WINEPS you need to install some AFM files.\n"); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 322 | return FALSE; |
| 323 | } |
| 324 | |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 325 | physDev = (PSDRV_PDEVICE *)HeapAlloc( PSDRV_Heap, HEAP_ZERO_MEMORY, |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 326 | sizeof(*physDev) ); |
| 327 | if (!physDev) return FALSE; |
Alexandre Julliard | d3cab18 | 2002-06-10 22:52:47 +0000 | [diff] [blame] | 328 | *pdev = physDev; |
Alexandre Julliard | 83decd2 | 2004-03-04 06:26:11 +0000 | [diff] [blame] | 329 | physDev->hdc = hdc; |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 330 | |
| 331 | physDev->pi = pi; |
| 332 | |
Huw D M Davies | e39b676 | 1999-05-17 16:20:51 +0000 | [diff] [blame] | 333 | physDev->Devmode = (PSDRV_DEVMODEA *)HeapAlloc( PSDRV_Heap, 0, |
| 334 | sizeof(PSDRV_DEVMODEA) ); |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 335 | if(!physDev->Devmode) { |
| 336 | HeapFree( PSDRV_Heap, 0, physDev ); |
| 337 | return FALSE; |
| 338 | } |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 339 | |
Huw D M Davies | e39b676 | 1999-05-17 16:20:51 +0000 | [diff] [blame] | 340 | memcpy( physDev->Devmode, pi->Devmode, sizeof(PSDRV_DEVMODEA) ); |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 341 | |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 342 | physDev->logPixelsX = physDev->pi->ppd->DefaultResolution; |
| 343 | physDev->logPixelsY = physDev->pi->ppd->DefaultResolution; |
Huw D M Davies | d4b933e | 2001-01-28 23:13:45 +0000 | [diff] [blame] | 344 | |
Huw Davies | 69c7164 | 2003-05-20 02:24:50 +0000 | [diff] [blame] | 345 | if (output) { |
Dmitry Timoshkov | 3a910c7 | 2003-08-12 20:42:18 +0000 | [diff] [blame] | 346 | physDev->job.output = HEAP_strdupWtoA( PSDRV_Heap, 0, output ); |
Huw Davies | 69c7164 | 2003-05-20 02:24:50 +0000 | [diff] [blame] | 347 | } else |
| 348 | physDev->job.output = NULL; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 349 | physDev->job.hJob = 0; |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 350 | |
| 351 | if(initData) { |
Dmitry Timoshkov | 3a910c7 | 2003-08-12 20:42:18 +0000 | [diff] [blame] | 352 | DEVMODEA *devmodeA = DEVMODEdupWtoA(PSDRV_Heap, initData); |
| 353 | PSDRV_MergeDevmodes(physDev->Devmode, (PSDRV_DEVMODEA *)devmodeA, pi); |
| 354 | HeapFree(PSDRV_Heap, 0, devmodeA); |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 355 | } |
| 356 | |
| 357 | PSDRV_UpdateDevCaps(physDev); |
Alexandre Julliard | 83decd2 | 2004-03-04 06:26:11 +0000 | [diff] [blame] | 358 | SelectObject( hdc, PSDRV_DefaultFont ); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 359 | return TRUE; |
| 360 | } |
| 361 | |
| 362 | |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 363 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 364 | /********************************************************************** |
| 365 | * PSDRV_DeleteDC |
| 366 | */ |
Alexandre Julliard | e21c15e | 2002-03-28 22:22:05 +0000 | [diff] [blame] | 367 | BOOL PSDRV_DeleteDC( PSDRV_PDEVICE *physDev ) |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 368 | { |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 369 | TRACE("\n"); |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 370 | |
| 371 | HeapFree( PSDRV_Heap, 0, physDev->Devmode ); |
Michael Stefaniuc | 5ad7d85 | 2004-12-23 17:06:43 +0000 | [diff] [blame] | 372 | HeapFree( PSDRV_Heap, 0, physDev->job.output ); |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 373 | HeapFree( PSDRV_Heap, 0, physDev ); |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 374 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 375 | return TRUE; |
| 376 | } |
| 377 | |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 378 | |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 379 | /********************************************************************** |
| 380 | * ResetDC (WINEPS.@) |
Alexandre Julliard | 9208301 | 2001-07-29 20:25:14 +0000 | [diff] [blame] | 381 | */ |
Vincent Béron | 431a96f | 2004-01-13 01:06:44 +0000 | [diff] [blame] | 382 | HDC PSDRV_ResetDC( PSDRV_PDEVICE *physDev, const DEVMODEW *lpInitData ) |
Alexandre Julliard | 9208301 | 2001-07-29 20:25:14 +0000 | [diff] [blame] | 383 | { |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 384 | if(lpInitData) { |
Huw Davies | 9fb3f4e | 2003-11-09 00:26:50 +0000 | [diff] [blame] | 385 | HRGN hrgn; |
Vincent Béron | 431a96f | 2004-01-13 01:06:44 +0000 | [diff] [blame] | 386 | DEVMODEA *devmodeA = DEVMODEdupWtoA(PSDRV_Heap, lpInitData); |
| 387 | PSDRV_MergeDevmodes(physDev->Devmode, (PSDRV_DEVMODEA *)devmodeA, physDev->pi); |
| 388 | HeapFree(PSDRV_Heap, 0, devmodeA); |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 389 | PSDRV_UpdateDevCaps(physDev); |
Huw Davies | 9fb3f4e | 2003-11-09 00:26:50 +0000 | [diff] [blame] | 390 | hrgn = CreateRectRgn(0, 0, physDev->horzRes, physDev->vertRes); |
| 391 | SelectVisRgn16(HDC_16(physDev->hdc), HRGN_16(hrgn)); |
| 392 | DeleteObject(hrgn); |
Alexandre Julliard | 9208301 | 2001-07-29 20:25:14 +0000 | [diff] [blame] | 393 | } |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 394 | return physDev->hdc; |
Alexandre Julliard | 9208301 | 2001-07-29 20:25:14 +0000 | [diff] [blame] | 395 | } |
| 396 | |
Alexandre Julliard | 9208301 | 2001-07-29 20:25:14 +0000 | [diff] [blame] | 397 | /*********************************************************************** |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 398 | * GetDeviceCaps (WINEPS.@) |
| 399 | */ |
Alexandre Julliard | e21c15e | 2002-03-28 22:22:05 +0000 | [diff] [blame] | 400 | INT PSDRV_GetDeviceCaps( PSDRV_PDEVICE *physDev, INT cap ) |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 401 | { |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 402 | switch(cap) |
| 403 | { |
| 404 | case DRIVERVERSION: |
| 405 | return 0; |
| 406 | case TECHNOLOGY: |
| 407 | return DT_RASPRINTER; |
| 408 | case HORZSIZE: |
Huw D M Davies | 7a6ea91 | 2002-06-24 23:41:55 +0000 | [diff] [blame] | 409 | return MulDiv(physDev->horzSize, 100, |
| 410 | physDev->Devmode->dmPublic.dmScale); |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 411 | case VERTSIZE: |
Huw D M Davies | 7a6ea91 | 2002-06-24 23:41:55 +0000 | [diff] [blame] | 412 | return MulDiv(physDev->vertSize, 100, |
| 413 | physDev->Devmode->dmPublic.dmScale); |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 414 | case HORZRES: |
| 415 | return physDev->horzRes; |
| 416 | case VERTRES: |
| 417 | return physDev->vertRes; |
| 418 | case BITSPIXEL: |
Huw Davies | a3c10cf | 2003-06-23 20:52:22 +0000 | [diff] [blame] | 419 | return physDev->pi->ppd->ColorDevice ? 8 : 1; |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 420 | case PLANES: |
| 421 | return 1; |
| 422 | case NUMBRUSHES: |
| 423 | return -1; |
| 424 | case NUMPENS: |
| 425 | return 10; |
| 426 | case NUMMARKERS: |
| 427 | return 0; |
| 428 | case NUMFONTS: |
| 429 | return 39; |
| 430 | case NUMCOLORS: |
| 431 | return (physDev->pi->ppd->ColorDevice ? 256 : -1); |
| 432 | case PDEVICESIZE: |
| 433 | return sizeof(PSDRV_PDEVICE); |
| 434 | case CURVECAPS: |
| 435 | return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE | |
| 436 | CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT); |
| 437 | case LINECAPS: |
| 438 | return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE | |
| 439 | LC_STYLED | LC_WIDESTYLED | LC_INTERIORS); |
| 440 | case POLYGONALCAPS: |
| 441 | return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE | |
| 442 | PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS); |
| 443 | case TEXTCAPS: |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 444 | return TC_CR_ANY | TC_VA_ABLE; /* psdrv 0x59f7 */ |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 445 | case CLIPCAPS: |
| 446 | return CP_RECTANGLE; |
| 447 | case RASTERCAPS: |
| 448 | return (RC_BITBLT | RC_BITMAP64 | RC_GDI20_OUTPUT | RC_DIBTODEV | |
| 449 | RC_STRETCHBLT | RC_STRETCHDIB); /* psdrv 0x6e99 */ |
| 450 | /* Are aspect[XY] and logPixels[XY] correct? */ |
| 451 | /* Need to handle different res in x and y => fix ppd */ |
| 452 | case ASPECTX: |
| 453 | case ASPECTY: |
| 454 | return physDev->pi->ppd->DefaultResolution; |
| 455 | case ASPECTXY: |
| 456 | return (int)hypot( (double)physDev->pi->ppd->DefaultResolution, |
| 457 | (double)physDev->pi->ppd->DefaultResolution ); |
| 458 | case LOGPIXELSX: |
Huw D M Davies | 7a6ea91 | 2002-06-24 23:41:55 +0000 | [diff] [blame] | 459 | return MulDiv(physDev->logPixelsX, |
| 460 | physDev->Devmode->dmPublic.dmScale, 100); |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 461 | case LOGPIXELSY: |
Huw D M Davies | 7a6ea91 | 2002-06-24 23:41:55 +0000 | [diff] [blame] | 462 | return MulDiv(physDev->logPixelsY, |
| 463 | physDev->Devmode->dmPublic.dmScale, 100); |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 464 | case SIZEPALETTE: |
| 465 | return 0; |
| 466 | case NUMRESERVED: |
| 467 | return 0; |
| 468 | case COLORRES: |
| 469 | return 0; |
| 470 | case PHYSICALWIDTH: |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 471 | return (physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE) ? |
| 472 | physDev->PageSize.cy : physDev->PageSize.cx; |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 473 | case PHYSICALHEIGHT: |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 474 | return (physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE) ? |
| 475 | physDev->PageSize.cx : physDev->PageSize.cy; |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 476 | case PHYSICALOFFSETX: |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 477 | if(physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE) { |
| 478 | if(physDev->pi->ppd->LandscapeOrientation == -90) |
| 479 | return physDev->PageSize.cy - physDev->ImageableArea.top; |
| 480 | else |
| 481 | return physDev->ImageableArea.bottom; |
| 482 | } |
| 483 | return physDev->ImageableArea.left; |
| 484 | |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 485 | case PHYSICALOFFSETY: |
Huw D M Davies | b88f724 | 2002-04-06 00:12:42 +0000 | [diff] [blame] | 486 | if(physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE) { |
| 487 | if(physDev->pi->ppd->LandscapeOrientation == -90) |
| 488 | return physDev->PageSize.cx - physDev->ImageableArea.right; |
| 489 | else |
| 490 | return physDev->ImageableArea.left; |
| 491 | } |
| 492 | return physDev->PageSize.cy - physDev->ImageableArea.top; |
| 493 | |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 494 | case SCALINGFACTORX: |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 495 | case SCALINGFACTORY: |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 496 | case VREFRESH: |
| 497 | case DESKTOPVERTRES: |
| 498 | case DESKTOPHORZRES: |
| 499 | case BTLALIGNMENT: |
| 500 | return 0; |
| 501 | default: |
Alexandre Julliard | b34fb35 | 2002-10-18 23:48:57 +0000 | [diff] [blame] | 502 | FIXME("(%p): unsupported capability %d, will return 0\n", physDev->hdc, cap ); |
Alexandre Julliard | 99bb9f9 | 2001-07-28 00:18:02 +0000 | [diff] [blame] | 503 | return 0; |
| 504 | } |
| 505 | } |
| 506 | |
| 507 | |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 508 | /********************************************************************** |
| 509 | * PSDRV_FindPrinterInfo |
| 510 | */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 511 | PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name) |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 512 | { |
| 513 | static PRINTERINFO *PSDRV_PrinterList; |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 514 | DWORD type = REG_BINARY, needed, res, dwPaperSize; |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 515 | PRINTERINFO *pi = PSDRV_PrinterList, **last = &PSDRV_PrinterList; |
| 516 | FONTNAME *font; |
Ian Pilcher | 4bc1ebb5 | 2001-07-24 20:52:19 +0000 | [diff] [blame] | 517 | const AFM *afm; |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 518 | HANDLE hPrinter; |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 519 | const char *ppd = NULL; |
Francois Gouget | f101e27 | 2001-10-22 19:00:08 +0000 | [diff] [blame] | 520 | DWORD ppdType; |
| 521 | char* ppdFileName = NULL; |
Dmitry Timoshkov | 043f640 | 2001-07-02 18:00:33 +0000 | [diff] [blame] | 522 | HKEY hkey; |
Huw D M Davies | 933733c | 2002-08-15 23:20:19 +0000 | [diff] [blame] | 523 | BOOL using_default_devmode = FALSE; |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 524 | |
Alexandre Julliard | 61fece0 | 1999-06-26 19:09:08 +0000 | [diff] [blame] | 525 | TRACE("'%s'\n", name); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 526 | |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 527 | /* |
| 528 | * If this loop completes, last will point to the 'next' element of the |
| 529 | * final PRINTERINFO in the list |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 530 | */ |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 531 | for( ; pi; last = &pi->next, pi = pi->next) |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 532 | if(!strcmp(pi->FriendlyName, name)) |
| 533 | return pi; |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 534 | |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 535 | pi = *last = HeapAlloc( PSDRV_Heap, HEAP_ZERO_MEMORY, sizeof(*pi) ); |
| 536 | if (pi == NULL) |
| 537 | return NULL; |
Alexandre Julliard | 5f728ca | 2001-07-24 21:45:22 +0000 | [diff] [blame] | 538 | |
| 539 | if (!(pi->FriendlyName = HeapAlloc( PSDRV_Heap, 0, strlen(name)+1 ))) goto fail; |
| 540 | strcpy( pi->FriendlyName, name ); |
| 541 | |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 542 | /* Use Get|SetPrinterDataExA instead? */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 543 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 544 | res = DrvGetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE, &type, |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 545 | NULL, 0, &needed ); |
| 546 | |
Huw D M Davies | 450270b | 1999-07-10 11:58:50 +0000 | [diff] [blame] | 547 | if(res == ERROR_INVALID_PRINTER_NAME || needed != sizeof(DefaultDevmode)) { |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 548 | pi->Devmode = HeapAlloc( PSDRV_Heap, 0, sizeof(DefaultDevmode) ); |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 549 | if (pi->Devmode == NULL) |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 550 | goto cleanup; |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 551 | memcpy(pi->Devmode, &DefaultDevmode, sizeof(DefaultDevmode) ); |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 552 | strcpy(pi->Devmode->dmPublic.dmDeviceName,name); |
Huw D M Davies | 933733c | 2002-08-15 23:20:19 +0000 | [diff] [blame] | 553 | using_default_devmode = TRUE; |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 554 | |
| 555 | /* need to do something here AddPrinter?? */ |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 556 | } |
| 557 | else { |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 558 | pi->Devmode = HeapAlloc( PSDRV_Heap, 0, needed ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 559 | DrvGetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE, &type, |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 560 | (LPBYTE)pi->Devmode, needed, &needed); |
| 561 | } |
| 562 | |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 563 | if (OpenPrinterA (pi->FriendlyName, &hPrinter, NULL) == 0) { |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 564 | ERR ("OpenPrinterA failed with code %li\n", GetLastError ()); |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 565 | goto cleanup; |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 566 | } |
Francois Gouget | f101e27 | 2001-10-22 19:00:08 +0000 | [diff] [blame] | 567 | |
Marcus Meissner | f061f76 | 2002-11-12 02:22:24 +0000 | [diff] [blame] | 568 | #ifdef HAVE_CUPS_CUPS_H |
| 569 | if (cupshandle != (void*)-1) { |
| 570 | typeof(cupsGetPPD) * pcupsGetPPD = NULL; |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 571 | |
Marcus Meissner | f061f76 | 2002-11-12 02:22:24 +0000 | [diff] [blame] | 572 | pcupsGetPPD = wine_dlsym(cupshandle, "cupsGetPPD", NULL, 0); |
| 573 | if (pcupsGetPPD) { |
| 574 | ppd = pcupsGetPPD(name); |
| 575 | |
| 576 | if (ppd) { |
| 577 | needed=strlen(ppd)+1; |
| 578 | ppdFileName=HeapAlloc(PSDRV_Heap, 0, needed); |
| 579 | memcpy(ppdFileName, ppd, needed); |
| 580 | ppdType=REG_SZ; |
| 581 | res = ERROR_SUCCESS; |
| 582 | /* we should unlink() that file later */ |
| 583 | } else { |
| 584 | res = ERROR_FILE_NOT_FOUND; |
| 585 | WARN("Did not find ppd for %s\n",name); |
| 586 | } |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 587 | } |
| 588 | } |
| 589 | #endif |
Francois Gouget | f101e27 | 2001-10-22 19:00:08 +0000 | [diff] [blame] | 590 | if (!ppdFileName) { |
| 591 | res = GetPrinterDataA(hPrinter, "PPD File", NULL, NULL, 0, &needed); |
| 592 | if ((res==ERROR_SUCCESS) || (res==ERROR_MORE_DATA)) { |
| 593 | ppdFileName=HeapAlloc(PSDRV_Heap, 0, needed); |
| 594 | res = GetPrinterDataA(hPrinter, "PPD File", &ppdType, ppdFileName, needed, &needed); |
| 595 | } |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 596 | } |
Marcus Meissner | 0c63012 | 2001-05-09 17:10:41 +0000 | [diff] [blame] | 597 | /* Look for a ppd file for this printer in the config file. |
Francois Gouget | f101e27 | 2001-10-22 19:00:08 +0000 | [diff] [blame] | 598 | * First look under that printer's name, and then under 'generic' |
Marcus Meissner | 0c63012 | 2001-05-09 17:10:41 +0000 | [diff] [blame] | 599 | */ |
Dmitry Timoshkov | 043f640 | 2001-07-02 18:00:33 +0000 | [diff] [blame] | 600 | if((res != ERROR_SUCCESS) && !RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\ppd", &hkey)) |
| 601 | { |
Francois Gouget | f101e27 | 2001-10-22 19:00:08 +0000 | [diff] [blame] | 602 | const char* value_name; |
| 603 | |
| 604 | if (RegQueryValueExA(hkey, name, 0, NULL, NULL, &needed) == ERROR_SUCCESS) { |
| 605 | value_name=name; |
| 606 | } else if (RegQueryValueExA(hkey, "generic", 0, NULL, NULL, &needed) == ERROR_SUCCESS) { |
| 607 | value_name="generic"; |
| 608 | } else { |
| 609 | value_name=NULL; |
| 610 | } |
| 611 | if (value_name) { |
| 612 | ppdFileName=HeapAlloc(PSDRV_Heap, 0, needed); |
| 613 | RegQueryValueExA(hkey, value_name, 0, &ppdType, ppdFileName, &needed); |
| 614 | } |
| 615 | RegCloseKey(hkey); |
Dmitry Timoshkov | 043f640 | 2001-07-02 18:00:33 +0000 | [diff] [blame] | 616 | } |
| 617 | |
Francois Gouget | f101e27 | 2001-10-22 19:00:08 +0000 | [diff] [blame] | 618 | if (!ppdFileName) { |
| 619 | res = ERROR_FILE_NOT_FOUND; |
| 620 | ERR ("Error %li getting PPD file name for printer '%s'\n", res, name); |
| 621 | goto closeprinter; |
| 622 | } else { |
| 623 | res = ERROR_SUCCESS; |
| 624 | if (ppdType==REG_EXPAND_SZ) { |
| 625 | char* tmp; |
Marcus Meissner | 0c63012 | 2001-05-09 17:10:41 +0000 | [diff] [blame] | 626 | |
Francois Gouget | f101e27 | 2001-10-22 19:00:08 +0000 | [diff] [blame] | 627 | /* Expand environment variable references */ |
| 628 | needed=ExpandEnvironmentStringsA(ppdFileName,NULL,0); |
| 629 | tmp=HeapAlloc(PSDRV_Heap, 0, needed); |
| 630 | ExpandEnvironmentStringsA(ppdFileName,tmp,needed); |
| 631 | HeapFree(PSDRV_Heap, 0, ppdFileName); |
| 632 | ppdFileName=tmp; |
| 633 | } |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 634 | } |
Francois Gouget | f101e27 | 2001-10-22 19:00:08 +0000 | [diff] [blame] | 635 | |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 636 | pi->ppd = PSDRV_ParsePPD(ppdFileName); |
| 637 | if(!pi->ppd) { |
| 638 | MESSAGE("Couldn't find PPD file '%s', expect a crash now!\n", |
| 639 | ppdFileName); |
| 640 | goto closeprinter; |
| 641 | } |
Francois Gouget | f101e27 | 2001-10-22 19:00:08 +0000 | [diff] [blame] | 642 | |
Huw Davies | 6124a02 | 2003-05-20 02:22:25 +0000 | [diff] [blame] | 643 | /* Some gimp-print ppd files don't contain a DefaultResolution line |
| 644 | set it to 300 if it's not specified */ |
| 645 | if(pi->ppd->DefaultResolution == 0) |
| 646 | pi->ppd->DefaultResolution = 300; |
Huw D M Davies | 933733c | 2002-08-15 23:20:19 +0000 | [diff] [blame] | 647 | |
| 648 | if(using_default_devmode) { |
| 649 | DWORD papersize; |
| 650 | |
| 651 | if(GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IPAPERSIZE | LOCALE_RETURN_NUMBER, |
Alexandre Julliard | b65d136 | 2004-02-25 01:35:01 +0000 | [diff] [blame] | 652 | (LPWSTR)&papersize, sizeof(papersize)/sizeof(WCHAR))) { |
Huw D M Davies | 933733c | 2002-08-15 23:20:19 +0000 | [diff] [blame] | 653 | PSDRV_DEVMODEA dm; |
| 654 | memset(&dm, 0, sizeof(dm)); |
| 655 | dm.dmPublic.dmFields = DM_PAPERSIZE; |
| 656 | dm.dmPublic.u1.s1.dmPaperSize = papersize; |
| 657 | PSDRV_MergeDevmodes(pi->Devmode, &dm, pi); |
| 658 | } |
| 659 | DrvSetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE, |
| 660 | REG_BINARY, (LPBYTE)pi->Devmode, sizeof(DefaultDevmode) ); |
| 661 | } |
| 662 | |
Huw Davies | 6124a02 | 2003-05-20 02:22:25 +0000 | [diff] [blame] | 663 | if(pi->ppd->DefaultPageSize) { /* We'll let the ppd override the devmode */ |
| 664 | PSDRV_DEVMODEA dm; |
| 665 | memset(&dm, 0, sizeof(dm)); |
| 666 | dm.dmPublic.dmFields = DM_PAPERSIZE; |
| 667 | dm.dmPublic.u1.s1.dmPaperSize = pi->ppd->DefaultPageSize->WinPage; |
| 668 | PSDRV_MergeDevmodes(pi->Devmode, &dm, pi); |
| 669 | } |
Huw D M Davies | 933733c | 2002-08-15 23:20:19 +0000 | [diff] [blame] | 670 | |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 671 | /* |
| 672 | * This is a hack. The default paper size should be read in as part of |
| 673 | * the Devmode structure, but Wine doesn't currently provide a convenient |
| 674 | * way to configure printers. |
| 675 | */ |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 676 | res = GetPrinterDataA (hPrinter, "Paper Size", NULL, (LPBYTE) &dwPaperSize, |
| 677 | sizeof (DWORD), &needed); |
| 678 | if (res == ERROR_SUCCESS) |
| 679 | pi->Devmode->dmPublic.u1.s1.dmPaperSize = (SHORT) dwPaperSize; |
| 680 | else if (res == ERROR_FILE_NOT_FOUND) |
| 681 | TRACE ("No 'Paper Size' for printer '%s'\n", name); |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 682 | else { |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 683 | ERR ("GetPrinterDataA returned %li\n", res); |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 684 | goto closeprinter; |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 685 | } |
| 686 | |
Huw Davies | 83d6e26 | 2003-11-05 00:37:47 +0000 | [diff] [blame] | 687 | /* Duplex is indicated by the setting of the DM_DUPLEX bit in dmFields. |
| 688 | WinDuplex == 0 is a special case which means that the ppd has a |
| 689 | *DefaultDuplex: NotCapable entry. In this case we'll try not to confuse |
| 690 | apps and set dmDuplex to DMDUP_SIMPLEX but leave the DM_DUPLEX clear. |
| 691 | PSDRV_WriteHeader understands this and copes. */ |
| 692 | pi->Devmode->dmPublic.dmFields &= ~DM_DUPLEX; |
| 693 | if(pi->ppd->DefaultDuplex) { |
| 694 | pi->Devmode->dmPublic.dmDuplex = pi->ppd->DefaultDuplex->WinDuplex; |
| 695 | if(pi->Devmode->dmPublic.dmDuplex != 0) |
| 696 | pi->Devmode->dmPublic.dmFields |= DM_DUPLEX; |
| 697 | else |
| 698 | pi->Devmode->dmPublic.dmDuplex = DMDUP_SIMPLEX; |
| 699 | } |
| 700 | |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 701 | res = EnumPrinterDataExA (hPrinter, "PrinterDriverData\\FontSubTable", NULL, |
| 702 | 0, &needed, &pi->FontSubTableSize); |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 703 | if (res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND) { |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 704 | TRACE ("No 'FontSubTable' for printer '%s'\n", name); |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 705 | } |
| 706 | else if (res == ERROR_MORE_DATA) { |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 707 | pi->FontSubTable = HeapAlloc (PSDRV_Heap, 0, needed); |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 708 | if (pi->FontSubTable == NULL) { |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 709 | ERR ("Failed to allocate %li bytes from heap\n", needed); |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 710 | goto closeprinter; |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 711 | } |
| 712 | |
| 713 | res = EnumPrinterDataExA (hPrinter, "PrinterDriverData\\FontSubTable", |
| 714 | (LPBYTE) pi->FontSubTable, needed, &needed, |
| 715 | &pi->FontSubTableSize); |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 716 | if (res != ERROR_SUCCESS) { |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 717 | ERR ("EnumPrinterDataExA returned %li\n", res); |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 718 | goto closeprinter; |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 719 | } |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 720 | } |
| 721 | else { |
| 722 | ERR("EnumPrinterDataExA returned %li\n", res); |
| 723 | goto closeprinter; |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 724 | } |
| 725 | |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 726 | if (ClosePrinter (hPrinter) == 0) { |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 727 | ERR ("ClosePrinter failed with code %li\n", GetLastError ()); |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 728 | goto cleanup; |
Ian Pilcher | 744820d | 2001-04-02 19:14:41 +0000 | [diff] [blame] | 729 | } |
| 730 | |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 731 | pi->next = NULL; |
| 732 | pi->Fonts = NULL; |
| 733 | |
| 734 | for(font = pi->ppd->InstalledFonts; font; font = font->next) { |
| 735 | afm = PSDRV_FindAFMinList(PSDRV_AFMFontList, font->Name); |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 736 | if(!afm) { |
| 737 | TRACE( "Couldn't find AFM file for installed printer font '%s' - " |
| 738 | "ignoring\n", font->Name); |
| 739 | } |
| 740 | else { |
Ian Pilcher | 42e052d | 2001-07-26 21:42:45 +0000 | [diff] [blame] | 741 | BOOL added; |
| 742 | if (PSDRV_AddAFMtoList(&pi->Fonts, afm, &added) == FALSE) { |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 743 | PSDRV_FreeAFMList(pi->Fonts); |
| 744 | goto cleanup; |
| 745 | } |
| 746 | } |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 747 | |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 748 | } |
| 749 | if (ppd) unlink(ppd); |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 750 | return pi; |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 751 | |
| 752 | closeprinter: |
| 753 | ClosePrinter(hPrinter); |
| 754 | cleanup: |
Michael Stefaniuc | 5ad7d85 | 2004-12-23 17:06:43 +0000 | [diff] [blame] | 755 | HeapFree(PSDRV_Heap, 0, ppdFileName); |
| 756 | HeapFree(PSDRV_Heap, 0, pi->FontSubTable); |
| 757 | HeapFree(PSDRV_Heap, 0, pi->FriendlyName); |
| 758 | HeapFree(PSDRV_Heap, 0, pi->Devmode); |
Ian Pilcher | 91857a6 | 2001-05-03 18:34:27 +0000 | [diff] [blame] | 759 | fail: |
Marcus Meissner | ab8b7db | 2001-04-27 18:02:46 +0000 | [diff] [blame] | 760 | HeapFree(PSDRV_Heap, 0, pi); |
| 761 | if (ppd) unlink(ppd); |
| 762 | *last = NULL; |
| 763 | return NULL; |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 764 | } |