include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / wineps.drv / escape.c
blob19c1125e50c81e0e02782a6d8576f790cc11589a
1 /*
2 * PostScript driver Escape function
4 * Copyright 1998 Huw D M Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <signal.h>
26 #include <errno.h>
27 #include <fcntl.h>
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wingdi.h"
32 #include "wine/wingdi16.h"
33 #include "winuser.h"
34 #include "winreg.h"
35 #include "psdrv.h"
36 #include "wine/debug.h"
37 #include "winspool.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
41 BOOL flush_spool( print_ctx *ctx )
43 DWORD written;
45 if (ctx->job.data_cnt)
47 if (!WritePrinter(ctx->job.hprinter, ctx->job.data, ctx->job.data_cnt, &written) ||
48 written != ctx->job.data_cnt)
49 return FALSE;
51 ctx->job.data_cnt = 0;
52 return TRUE;
55 DWORD write_spool( print_ctx *ctx, const void *data, DWORD num )
57 DWORD written;
59 if (ctx->job.data_cnt + num > ARRAY_SIZE(ctx->job.data))
61 if (!flush_spool(ctx))
62 return SP_OUTOFDISK;
65 if (ctx->job.data_cnt + num > ARRAY_SIZE(ctx->job.data))
67 if (!WritePrinter(ctx->job.hprinter, (LPBYTE) data, num, &written) ||
68 written != num)
69 return SP_OUTOFDISK;
71 else
73 memcpy(ctx->job.data + ctx->job.data_cnt, data, num);
74 ctx->job.data_cnt += num;
76 return num;
79 /**********************************************************************
80 * ExtEscape
82 INT PSDRV_ExtEscape( print_ctx *ctx, INT nEscape, INT cbInput, LPCVOID in_data,
83 INT cbOutput, LPVOID out_data )
85 TRACE("%p,%d,%d,%p,%d,%p\n",
86 ctx->hdc, nEscape, cbInput, in_data, cbOutput, out_data);
88 switch(nEscape)
90 case POSTSCRIPT_DATA:
91 case PASSTHROUGH:
92 case POSTSCRIPT_PASSTHROUGH:
94 /* Write directly to spool file, bypassing normal PS driver
95 * processing that is done along with writing PostScript code
96 * to the spool.
97 * We have a WORD before the data counting the size, but
98 * cbInput is just this +2.
99 * However Photoshop 7 has a bug that sets cbInput to 2 less than the
100 * length of the string, rather than 2 more. So we'll use the WORD at
101 * in_data[0] instead.
103 passthrough_enter(ctx);
104 return write_spool(ctx, ((char*)in_data) + 2, *(const WORD*)in_data);
107 case POSTSCRIPT_IGNORE:
109 BOOL ret = ctx->job.quiet;
110 TRACE("POSTSCRIPT_IGNORE %d\n", *(const short*)in_data);
111 ctx->job.quiet = *(const short*)in_data;
112 return ret;
115 case BEGIN_PATH:
116 TRACE("BEGIN_PATH\n");
117 if(ctx->pathdepth)
118 FIXME("Nested paths not yet handled\n");
119 return ++ctx->pathdepth;
121 case END_PATH:
123 const struct PATH_INFO *info = (const struct PATH_INFO*)in_data;
125 TRACE("END_PATH\n");
126 if(!ctx->pathdepth) {
127 ERR("END_PATH called without a BEGIN_PATH\n");
128 return -1;
130 TRACE("RenderMode = %d, FillMode = %d, BkMode = %d\n",
131 info->RenderMode, info->FillMode, info->BkMode);
132 switch(info->RenderMode) {
133 case RENDERMODE_NO_DISPLAY:
134 PSDRV_WriteClosePath(ctx); /* not sure if this is necessary, but it can't hurt */
135 break;
136 case RENDERMODE_OPEN:
137 case RENDERMODE_CLOSED:
138 default:
139 FIXME("END_PATH: RenderMode %d, not yet supported\n", info->RenderMode);
140 break;
142 return --ctx->pathdepth;
145 case CLIP_TO_PATH:
147 WORD mode = *(const WORD*)in_data;
149 switch(mode) {
150 case CLIP_SAVE:
151 TRACE("CLIP_TO_PATH: CLIP_SAVE\n");
152 PSDRV_WriteGSave(ctx);
153 return 1;
154 case CLIP_RESTORE:
155 TRACE("CLIP_TO_PATH: CLIP_RESTORE\n");
156 PSDRV_WriteGRestore(ctx);
157 return 1;
158 case CLIP_INCLUSIVE:
159 TRACE("CLIP_TO_PATH: CLIP_INCLUSIVE\n");
160 /* FIXME to clip or eoclip ? (see PATH_INFO.FillMode) */
161 PSDRV_WriteClip(ctx);
162 PSDRV_WriteNewPath(ctx);
163 return 1;
164 case CLIP_EXCLUSIVE:
165 FIXME("CLIP_EXCLUSIVE: not implemented\n");
166 return 0;
167 default:
168 FIXME("Unknown CLIP_TO_PATH mode %d\n", mode);
169 return 0;
173 default:
174 return 0;
178 /************************************************************************
179 * PSDRV_StartPage
181 INT PSDRV_StartPage( print_ctx *ctx )
183 TRACE("%p\n", ctx->hdc);
185 if(!ctx->job.OutOfPage) {
186 FIXME("Already started a page?\n");
187 return 1;
190 ctx->job.PageNo++;
192 if(!PSDRV_WriteNewPage( ctx ))
193 return 0;
194 ctx->job.OutOfPage = FALSE;
195 return 1;
199 /************************************************************************
200 * PSDRV_EndPage
202 INT PSDRV_EndPage( print_ctx *ctx )
204 TRACE("%p\n", ctx->hdc);
206 if(ctx->job.OutOfPage) {
207 FIXME("Already ended a page?\n");
208 return 1;
211 passthrough_leave(ctx);
212 if(!PSDRV_WriteEndPage( ctx ))
213 return 0;
214 PSDRV_EmptyDownloadList(ctx, FALSE);
215 ctx->job.OutOfPage = TRUE;
216 return 1;