Fix a bug in counting DATA chunks.
[obnox/wireshark/wip.git] / gtk / print_mswin.c
1 /* print_mswin.c
2  * Printing support for MSWindows
3  *
4  * $Id$
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 2002, Jeffrey C. Foster <jfoste@woodward.com>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  *
24  *
25  * This original code was from the Technet Article Q139652 :
26  *       HOWTO: Print a Document
27  */
28
29
30 #include <string.h>
31 #include <stdio.h>
32
33 #include <windows.h>
34 #include <commdlg.h>
35
36 #ifdef __WIN32__
37 #include <winspool.h>
38 #endif
39
40 /*
41 Some thoughts about a GTK win32 printer dialog:
42
43 "EnumPrinters()", asking for information level 2 - the PRINTER_INFO_2
44 structure contains a pLocation string pointer, along with other
45 information.
46  
47 "PrinterProperties", could be used to show a native printer property page?!?
48
49 See
50  
51         http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_62ia.asp
52  
53 for information on printer APIs. 
54
55 */
56 BOOL CALLBACK abort_proc( HDC hDC, int Error );
57 HDC get_printer_dc(void);
58 void init_doc_struct( DOCINFO* di, char* docname);
59 void print_file( char* file_name, HDC hdc);
60
61 void print_mswin(char *file_name)
62
63    {
64        HDC        hDC;
65        DOCINFO    di;
66
67         HWND hWndParent = HWND_DESKTOP; /* would be better to be a real window */
68
69        /* Need a printer DC to print to. */
70        hDC = get_printer_dc();
71
72        /* Did you get a good DC?, Cancel will return NULL also, so what to do? */
73        if( !hDC)
74        {
75            return;
76        }
77
78        /* You always have to use an AbortProc(). */
79        if( SetAbortProc( hDC, abort_proc ) == SP_ERROR )
80        {
81            MessageBox( NULL, "Error setting up AbortProc",
82                                        "Error", MB_APPLMODAL | MB_OK);
83            return;
84        }
85
86        /* Init the DOCINFO and start the document. */
87        init_doc_struct( &di, "MyDoc");
88        StartDoc( hDC, &di );
89
90        /* Print one page. */
91        StartPage( hDC );
92        print_file(file_name, hDC );
93        EndPage( hDC );
94
95        /* Indicate end of document. */
96        EndDoc( hDC );
97
98        /* Clean up */
99        DeleteDC( hDC );
100    }
101
102    /*===============================*/
103    /* Obtain printer device context */
104    /* ==============================*/
105    HDC get_printer_dc(void)
106    {
107        PRINTDLG pdlg;
108
109        /*
110         * XXX - can this be done without a Windows print dialog?
111         *
112         * "CreateDC()" creates a device context, and you can
113         * apparently specify WINSPL16 as the driver name on
114         * Windows OT, or ther name of a "print provider", such as
115         * "WINSPOOL" on Windows NT, to get a context for a printer.
116         *
117         * The device name would be the printer name as shown by the
118         * Print Manager; is there a way to enumerate those?
119         */
120
121        /* Initialize the PRINTDLG structure. */
122        memset( &pdlg, 0, sizeof( PRINTDLG ) );
123        pdlg.lStructSize = sizeof( PRINTDLG );
124        /* Set the flag to return printer DC. */
125        pdlg.Flags =  
126            /* return the device context we need */
127            PD_RETURNDC |        
128            /* disable the "Pages" radio button */
129            PD_NOPAGENUMS |      
130            /* disable the "Selection" radio button */
131            PD_NOSELECTION |     
132            /* let device print multiple pages (if requested) */
133            PD_USEDEVMODECOPIESANDCOLLATE; 
134
135        /* Invoke the printer dialog box. */
136        PrintDlg( &pdlg );
137
138        /* hDC member of the PRINTDLG structure contains the printer DC. */
139        return pdlg.hDC;
140    }
141
142    /*===============================*/
143    /* The Abort Procudure           */
144    /* ==============================*/
145    BOOL CALLBACK abort_proc( HDC hDC, int Error )
146    {
147        MSG   msg;
148        while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
149        {
150            TranslateMessage( &msg );
151            DispatchMessage( &msg );
152        }
153        return TRUE;
154    }
155
156    /*===============================*/
157    /* Initialize DOCINFO structure  */
158    /* ==============================*/
159    void init_doc_struct( DOCINFO* di, char* docname)
160    {
161        /* Always zero it before using it. */
162        memset( di, 0, sizeof( DOCINFO ) );
163        /* Fill in the required members. */
164        di->cbSize = sizeof( DOCINFO );
165        di->lpszDocName = docname;
166    }
167
168    /*===============================*/
169    /* Drawing on the DC             */
170    /* ==============================*/
171 void print_file( char *file_name, HDC hdc) {
172
173     #define max_buf_size 1024
174     #define max_lines 66
175     #define y_offset 5
176     #define x_offset 5
177
178     FILE* fh1;
179     int results, cnt=0, y_pos = y_offset, y_cnt = 0;
180     char buf[ max_buf_size];
181     char ch;
182     TEXTMETRIC tm;
183
184     GetTextMetrics(hdc, &tm);
185     SetMapMode (hdc, MM_TEXT);
186
187
188     fh1 = fopen( file_name, "r" );
189     if( !fh1 )
190         perror( "open failed on input file" );
191
192      else {
193         while ((results = fread( &ch, 1, 1, fh1 )) != 0) {
194
195 /* if end of line send buffer and more y position */
196
197             if ( ch == 0x0a){
198                 buf[ cnt] = 0;
199                 TextOut(hdc, x_offset,y_pos, buf, strlen(buf));
200                 y_pos += tm.tmHeight;
201                 cnt = 0;
202                 if ( ++y_cnt == max_lines){
203        /* Print one page. */
204                     EndPage( hdc );
205                     StartPage( hdc );
206                     y_pos = y_offset;
207                     y_cnt = 0;
208                 }
209
210 /* if line buffer is full, dump it */
211             }else { if ( cnt == ( max_buf_size - 1)) {
212                 buf[ cnt] = 0;
213                 TextOut(hdc, x_offset, y_pos, buf, strlen(buf));
214                 y_pos += tm.tmHeight;
215                 cnt = 0;
216
217                 if ( ++y_cnt == max_lines){
218        /* Print one page. */
219                     EndPage( hdc );
220                     StartPage( hdc );
221                     y_pos = y_offset;
222                     y_cnt = 0;
223                 }
224             }
225
226             buf[ cnt++] = ch;
227         }
228     }
229 /*XXX  need feof test here ? */
230
231 /* Print the last text if needed */
232     if ( cnt > 0) {
233         buf[ cnt] = 0;
234         TextOut(hdc, 0,y_pos, buf, strlen(buf));
235     }
236     fclose(fh1);
237 }
238 }