1 /*
2 * Copyright (c) Tony Bybell 1999-2012
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 */
9
10 #include "globals.h"
11 #include <config.h>
12 #include "currenttime.h"
13 #include "print.h"
14 #include "menu.h"
15 #include <errno.h>
16
17 #ifdef WAVE_GTK_UNIX_PRINT
18 /* #include <gtk/gtkunixprint.h> */
19 #include <gtk/gtkprintunixdialog.h>
20 #endif
21
22 static char *render_targets[]=
23 {"PDF", "PS", "MIF", "UNIX"};
24
25 static char *page_size[]=
26 {"Letter (8.5\" x 11\")", "A4 (11.68\" x 8.26\")", "Legal (14\" x 8.5\")", "Letter Prop (6.57\" x 8.5\")", "A4 Prop (8.26\" x 5.84\")"};
27
28 static char *render_type[]=
29 {"Full", "Minimal"};
30
31 static gdouble px[]={11.00, 11.68, 14.00, 8.50, 8.26};
32 static gdouble py[]={ 8.50, 8.26, 8.50, 6.57, 5.84};
33
34
35 /*
36 * button/menu/entry activations..
37 */
render_clicked(GtkWidget * widget,gpointer which)38 static void render_clicked(GtkWidget *widget, gpointer which)
39 {
40 (void)widget;
41
42 int i;
43
44 for(i=0;i<4;i++) GLOBALS->target_mutex_renderopt_c_1[i]=0;
45
46 i = (int)((intptr_t)which);
47 GLOBALS->target_mutex_renderopt_c_1[i] = 1; /* mark our choice */
48
49 DEBUG(printf("picked: %s\n", render_targets[i]));
50 }
51
pagesize_clicked(GtkWidget * widget,gpointer which)52 static void pagesize_clicked(GtkWidget *widget, gpointer which)
53 {
54 (void)widget;
55
56 int i;
57
58 for(i=0;i<5;i++) GLOBALS->page_mutex_renderopt_c_1[i]=0;
59
60 GLOBALS->page_size_type_renderopt_c_1 = (int)((intptr_t)which);
61 GLOBALS->page_mutex_renderopt_c_1[GLOBALS->page_size_type_renderopt_c_1] = 1; /* mark our choice */
62
63 DEBUG(printf("picked: %s\n", page_size[GLOBALS->page_size_type_renderopt_c_1]));
64 }
65
rendertype_clicked(GtkWidget * widget,gpointer which)66 static void rendertype_clicked(GtkWidget *widget, gpointer which)
67 {
68 (void)widget;
69
70 int i;
71
72 for(i=0;i<3;i++) GLOBALS->render_mutex_renderopt_c_1[i]=0;
73
74 i = (int)((intptr_t)which);
75 GLOBALS->render_mutex_renderopt_c_1[i] = 1; /* mark our choice */
76
77 DEBUG(printf("picked: %s\n", render_type[i]));
78 }
79
80
81 static void
ps_print_cleanup(GtkWidget * widget,gpointer data)82 ps_print_cleanup(GtkWidget *widget, gpointer data)
83 {
84 (void)widget;
85 (void)data;
86
87 FILE *wave;
88
89 if(GLOBALS->filesel_ok)
90 {
91 DEBUG(printf("PS Print Fini: %s\n", *GLOBALS->fileselbox_text));
92
93 if(!(wave=fopen(*GLOBALS->fileselbox_text,"wb")))
94 {
95 fprintf(stderr, "Error opening PS output file '%s' for writing.\n",*GLOBALS->fileselbox_text);
96 perror("Why");
97 errno=0;
98 }
99 else
100 {
101 print_ps_image(wave,px[GLOBALS->page_size_type_renderopt_c_1],py[GLOBALS->page_size_type_renderopt_c_1]);
102 fclose(wave);
103 }
104 }
105 }
106
107 static void
pdf_print_cleanup(GtkWidget * widget,gpointer data)108 pdf_print_cleanup(GtkWidget *widget, gpointer data)
109 {
110 (void)widget;
111 (void)data;
112
113 FILE *wave;
114 FILE *wave2;
115
116 if(GLOBALS->filesel_ok)
117 {
118 DEBUG(printf("PDF Print Fini: %s\n", *GLOBALS->fileselbox_text));
119
120 if(!(wave=fopen(*GLOBALS->fileselbox_text,"wb")))
121 {
122 fprintf(stderr, "Error opening PDF output file '%s' for writing.\n",*GLOBALS->fileselbox_text);
123 perror("Why");
124 errno=0;
125 }
126 else
127 {
128 int len = strlen(*GLOBALS->fileselbox_text) ;
129 char *zname = malloc_2(len + 4);
130 strcpy(zname, *GLOBALS->fileselbox_text);
131
132 #ifdef MAC_INTEGRATION
133 if((len > 4)&&(!strcmp(".pdf", zname+len-4)))
134 {
135 zname[len-4] = 0;
136 len-=4;
137 }
138 #endif
139 strcpy(zname+len, ".ps");
140
141 if(!(wave2=fopen(zname,"wb")))
142 {
143 fprintf(stderr, "Error opening PS output tempfile '%s' for writing.\n",zname);
144 perror("Why");
145 fclose(wave);
146 unlink(*GLOBALS->fileselbox_text);
147 errno=0;
148 }
149 else
150 {
151 char *sysname = malloc_2(7 + 1 + len + 3 + 1 + len + 1);
152 int rc;
153
154 #ifdef MAC_INTEGRATION
155 sprintf(sysname, "pstopdf" /* 7 */
156 #else
157 sprintf(sysname, "ps2pdf" /* 6 */
158 #endif
159 " " /* 1 */
160 "%s" /* len + 3 */
161 " " /* 1 */
162 "%s" /* len */
163 , zname, *GLOBALS->fileselbox_text);
164 print_ps_image(wave2,px[GLOBALS->page_size_type_renderopt_c_1],py[GLOBALS->page_size_type_renderopt_c_1]);
165 fclose(wave2);
166 fclose(wave);
167 rc = system(sysname);
168 if(rc)
169 {
170 printf("GTKWAVE | ERROR: rc for '%s' = %d\n", sysname, rc);
171 unlink(*GLOBALS->fileselbox_text);
172 }
173 free_2(sysname);
174 unlink(zname);
175 }
176
177 free_2(zname);
178 }
179 }
180 }
181
182 static void
mif_print_cleanup(GtkWidget * widget,gpointer data)183 mif_print_cleanup(GtkWidget *widget, gpointer data)
184 {
185 (void)widget;
186 (void)data;
187
188 FILE *wave;
189
190 if(GLOBALS->filesel_ok)
191 {
192 DEBUG(printf("MIF Print Fini: %s\n", *GLOBALS->fileselbox_text));
193
194 if(!(wave=fopen(*GLOBALS->fileselbox_text,"wb")))
195 {
196 fprintf(stderr, "Error opening MIF output file '%s' for writing.\n",*GLOBALS->fileselbox_text);
197 perror("Why");
198 errno=0;
199 }
200 else
201 {
202 print_mif_image(wave,px[GLOBALS->page_size_type_renderopt_c_1],py[GLOBALS->page_size_type_renderopt_c_1]);
203 fclose(wave);
204 }
205 }
206 }
207
208
209 #ifdef WAVE_GTK_UNIX_PRINT
wave_GtkPrintJobCompleteFunc(GtkPrintJob * print_job,gpointer user_data,GError * error)210 static void wave_GtkPrintJobCompleteFunc(GtkPrintJob *print_job, gpointer user_data, GError *error)
211 {
212 (void)print_job;
213 (void)error;
214
215 if(user_data)
216 {
217 const char *ban = "Sent print job";
218 char *buf = wave_alloca(strlen(ban) + strlen(user_data) + 32);
219
220 sprintf(buf, "%s '%s'", ban, (char *)user_data);
221 status_text(buf);
222
223 unlink(user_data);
224 }
225 }
226 #endif
227
228 static void
unix_print_cleanup(GtkWidget * widget,gpointer data)229 unix_print_cleanup(GtkWidget *widget, gpointer data)
230 {
231 (void)widget;
232 (void)data;
233
234 #ifdef WAVE_GTK_UNIX_PRINT
235 GtkWidget *ropt = gtk_print_unix_dialog_new("GTK Print UNIX Options", GTK_WINDOW(GLOBALS->mainwindow));
236 gint gd_rc;
237
238 if(GLOBALS->gprs) { gtk_print_unix_dialog_set_settings(GTK_PRINT_UNIX_DIALOG(ropt), GLOBALS->gprs); }
239 if(GLOBALS->gps) { gtk_print_unix_dialog_set_page_setup(GTK_PRINT_UNIX_DIALOG(ropt), GLOBALS->gps); }
240
241 gtk_print_unix_dialog_set_manual_capabilities(GTK_PRINT_UNIX_DIALOG(ropt),
242 GTK_PRINT_CAPABILITY_GENERATE_PS |
243 GTK_PRINT_CAPABILITY_COPIES
244 );
245
246 #ifdef MAC_INTEGRATION
247 osx_menu_sensitivity(FALSE);
248 #endif
249
250 gd_rc = gtk_dialog_run(GTK_DIALOG (ropt));
251 if(gd_rc == GTK_RESPONSE_OK)
252 {
253 GtkPrinter *gp = gtk_print_unix_dialog_get_selected_printer(GTK_PRINT_UNIX_DIALOG(ropt));
254 GtkPrintSettings *gprs = gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(ropt));
255 GtkPageSetup *gps = gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(ropt));
256 GtkPrintJob *gpj = gtk_print_job_new(GLOBALS->loaded_file_name, gp, gprs, gps);
257 gboolean job_stat;
258 GError *job_error = NULL;
259 FILE *wave;
260 char *save_tmpfilename;
261 int fd_dummy = -1;
262
263 if(gtk_printer_accepts_ps(gp))
264 {
265 save_tmpfilename = tmpnam_2(NULL, &fd_dummy);
266
267 if(!(wave=fopen(save_tmpfilename, "r+b")))
268 {
269 fprintf(stderr, "Error opening PS output file '%s' for writing.\n", save_tmpfilename);
270 perror("Why");
271 errno=0;
272 }
273 else
274 {
275 if(GLOBALS->gp_tfn) free_2(GLOBALS->gp_tfn);
276 GLOBALS->gp_tfn = strdup_2(save_tmpfilename);
277
278 print_ps_image(wave,px[GLOBALS->page_size_type_renderopt_c_1],py[GLOBALS->page_size_type_renderopt_c_1]);
279 fflush(wave);
280 fclose(wave);
281 job_stat = gtk_print_job_set_source_file(gpj,
282 GLOBALS->gp_tfn,
283 &job_error);
284 if(job_stat)
285 {
286 gtk_print_job_send(gpj, wave_GtkPrintJobCompleteFunc,
287 GLOBALS->gp_tfn,
288 NULL);
289 GLOBALS->gprs = gtk_print_settings_copy(gprs);
290 GLOBALS->gps = gtk_page_setup_copy(gps);
291 }
292 else
293 {
294 unlink(GLOBALS->gp_tfn);
295 }
296 }
297
298 #if !defined _MSC_VER && !defined __MINGW32__
299 free_2(save_tmpfilename);
300 #endif
301 if(fd_dummy >=0) close(fd_dummy);
302 }
303 else
304 {
305 status_text("gtk_printer_accepts_ps() == FALSE, cannot print.");
306 }
307 }
308 else
309 if(gd_rc == GTK_RESPONSE_APPLY)
310 {
311 status_text("Preview not available.");
312 }
313
314 gtk_widget_destroy(ropt);
315
316 #ifdef MAC_INTEGRATION
317 osx_menu_sensitivity(TRUE);
318 #endif
319
320 #endif
321 }
322
323
324
ok_callback(void)325 static void ok_callback(void)
326 {
327 GLOBALS->ps_fullpage=GLOBALS->render_mutex_renderopt_c_1[0];
328 if(GLOBALS->target_mutex_renderopt_c_1[0])
329 {
330 fileselbox("Print To PDF File",&GLOBALS->filesel_print_pdf_renderopt_c_1,GTK_SIGNAL_FUNC(pdf_print_cleanup), GTK_SIGNAL_FUNC(NULL), "*.pdf", 1);
331 }
332 else
333 if(GLOBALS->target_mutex_renderopt_c_1[1])
334 {
335 fileselbox("Print To PS File",&GLOBALS->filesel_print_ps_renderopt_c_1,GTK_SIGNAL_FUNC(ps_print_cleanup), GTK_SIGNAL_FUNC(NULL), "*.ps", 1);
336 }
337 else
338 if(GLOBALS->target_mutex_renderopt_c_1[2])
339 {
340 fileselbox("Print To MIF File",&GLOBALS->filesel_print_mif_renderopt_c_1,GTK_SIGNAL_FUNC(mif_print_cleanup), GTK_SIGNAL_FUNC(NULL), "*.fm", 1);
341 }
342 else
343 {
344 unix_print_cleanup(NULL,NULL);
345 }
346 }
347
destroy_callback(GtkWidget * widget,GtkWidget * nothing)348 static void destroy_callback(GtkWidget *widget, GtkWidget *nothing)
349 {
350 (void)widget;
351 (void)nothing;
352
353 GLOBALS->is_active_renderopt_c_3=0;
354 gtk_widget_destroy(GLOBALS->window_renderopt_c_6);
355 GLOBALS->window_renderopt_c_6 = NULL;
356 }
357
358
renderbox(char * title)359 void renderbox(char *title)
360 {
361 GtkWidget *menu, *menuitem, *optionmenu;
362 GSList *group;
363 GtkWidget *vbox, *hbox, *small_hbox;
364 GtkWidget *button1, *button2;
365 int i;
366
367 /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */
368 if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); }
369
370 if(GLOBALS->wave_script_args)
371 {
372 char *s1 = NULL;
373 char *s2 = NULL;
374 char *s3 = NULL;
375
376 while((!s1)&&(GLOBALS->wave_script_args->curr)) s1 = wave_script_args_fgetmalloc_stripspaces(GLOBALS->wave_script_args);
377 while((!s2)&&(GLOBALS->wave_script_args->curr)) s2 = wave_script_args_fgetmalloc_stripspaces(GLOBALS->wave_script_args);
378 while((!s3)&&(GLOBALS->wave_script_args->curr)) s3 = wave_script_args_fgetmalloc_stripspaces(GLOBALS->wave_script_args);
379
380 if(s1 && s2 && s3)
381 {
382 memset(GLOBALS->target_mutex_renderopt_c_1, 0, 2); GLOBALS->target_mutex_renderopt_c_1[0] = 1; /* PS */
383 #ifdef WAVE_GTK_UNIX_PRINT
384 for(i=0;i<4;i++)
385 #else
386 for(i=0;i<3;i++)
387 #endif
388 {
389 if(!strcmp(s1, render_targets[i]))
390 {
391 fprintf(stderr, "GTKWAVE | Print using '%s'\n", render_targets[i]);
392 memset(GLOBALS->target_mutex_renderopt_c_1, 0, 4); GLOBALS->target_mutex_renderopt_c_1[i] = 1; break;
393 }
394 }
395
396 memset(GLOBALS->page_mutex_renderopt_c_1, 0, 5); GLOBALS->page_mutex_renderopt_c_1[0] = 1; /* 8.5 x 11 */
397 GLOBALS->page_size_type_renderopt_c_1 = 0;
398 for(i=0;i<5;i++)
399 {
400 if(!strcmp(s2, page_size[i]))
401 {
402 fprintf(stderr, "GTKWAVE | Print using '%s'\n", page_size[i]);
403 memset(GLOBALS->page_mutex_renderopt_c_1, 0, 5); GLOBALS->page_mutex_renderopt_c_1[i] = 1;
404 GLOBALS->page_size_type_renderopt_c_1 = i;
405 break;
406 }
407 }
408
409 memset(GLOBALS->render_mutex_renderopt_c_1, 0, 3); GLOBALS->render_mutex_renderopt_c_1[0] = 1; /* Full */
410 for(i=0;i<2;i++)
411 {
412 if(!strcmp(s3, render_type[i]))
413 {
414 fprintf(stderr, "GTKWAVE | Print using '%s'\n", render_type[i]);
415 memset(GLOBALS->render_mutex_renderopt_c_1, 0, 3); GLOBALS->render_mutex_renderopt_c_1[i] = 1; break;
416 }
417 }
418
419 free_2(s1); free_2(s2); free_2(s3);
420 ok_callback();
421 }
422 else
423 {
424 fprintf(stderr, "Missing script entries for renderbox, exiting.\n");
425 exit(255);
426 }
427
428 return;
429 }
430
431
432
433 if(GLOBALS->is_active_renderopt_c_3)
434 {
435 if(GLOBALS->window_renderopt_c_6)
436 {
437 gdk_window_raise(GLOBALS->window_renderopt_c_6->window);
438 }
439 return;
440 }
441
442 GLOBALS->is_active_renderopt_c_3=1;
443
444 /* create a new window */
445 GLOBALS->window_renderopt_c_6 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL);
446 install_focus_cb(GLOBALS->window_renderopt_c_6, ((char *)&GLOBALS->window_renderopt_c_6) - ((char *)GLOBALS));
447
448 gtk_window_set_title(GTK_WINDOW (GLOBALS->window_renderopt_c_6), title);
449 gtk_widget_set_usize( GTK_WIDGET (GLOBALS->window_renderopt_c_6), 420, -1);
450 gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_renderopt_c_6), "delete_event",(GtkSignalFunc) destroy_callback, NULL);
451 gtk_window_set_policy(GTK_WINDOW(GLOBALS->window_renderopt_c_6), FALSE, FALSE, FALSE);
452
453 vbox = gtk_vbox_new (FALSE, 0);
454 gtk_container_add (GTK_CONTAINER (GLOBALS->window_renderopt_c_6), vbox);
455 gtk_widget_show (vbox);
456
457 small_hbox = gtk_hbox_new (TRUE, 0);
458 gtk_widget_show (small_hbox);
459
460 menu = gtk_menu_new ();
461 group=NULL;
462
463 for(i=0;i<4;i++)
464 {
465 GLOBALS->target_mutex_renderopt_c_1[i]=0;
466
467 #ifndef WAVE_GTK_UNIX_PRINT
468 if(i==3)
469 {
470 break;
471 }
472 #endif
473
474 menuitem = gtk_radio_menu_item_new_with_label (group, render_targets[i]);
475 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
476 gtk_menu_append (GTK_MENU (menu), menuitem);
477 gtk_widget_show (menuitem);
478 gtkwave_signal_connect(GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC(render_clicked), (void *)((intptr_t)i));
479 }
480
481 GLOBALS->target_mutex_renderopt_c_1[0]=1; /* "ps" */
482
483 optionmenu = gtk_option_menu_new ();
484 gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
485 gtk_box_pack_start (GTK_BOX (small_hbox), optionmenu, TRUE, FALSE, 0);
486 gtk_widget_show (optionmenu);
487
488 menu = gtk_menu_new ();
489 group=NULL;
490
491 for(i=0;i<5;i++)
492 {
493 menuitem = gtk_radio_menu_item_new_with_label (group, page_size[i]);
494 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
495 gtk_menu_append (GTK_MENU (menu), menuitem);
496 gtk_widget_show (menuitem);
497 gtkwave_signal_connect(GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC(pagesize_clicked), (void *)((intptr_t)i));
498 GLOBALS->page_mutex_renderopt_c_1[i]=0;
499 }
500
501 GLOBALS->page_mutex_renderopt_c_1[0]=1; /* "letter" */
502
503 optionmenu = gtk_option_menu_new ();
504 gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
505 gtk_box_pack_start (GTK_BOX (small_hbox), optionmenu, TRUE, FALSE, 0);
506 gtk_widget_show (optionmenu);
507
508
509 gtk_box_pack_start (GTK_BOX (vbox), small_hbox, FALSE, FALSE, 0);
510
511 menu = gtk_menu_new ();
512 group=NULL;
513
514 for(i=0;i<2;i++)
515 {
516 menuitem = gtk_radio_menu_item_new_with_label (group, render_type[i]);
517 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
518 gtk_menu_append (GTK_MENU (menu), menuitem);
519 gtk_widget_show (menuitem);
520 gtkwave_signal_connect(GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC(rendertype_clicked), (void *)((intptr_t)i));
521 GLOBALS->render_mutex_renderopt_c_1[i]=0;
522 }
523
524 GLOBALS->render_mutex_renderopt_c_1[0]=1; /* "full" */
525
526 optionmenu = gtk_option_menu_new ();
527 gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
528 gtk_box_pack_start (GTK_BOX (small_hbox), optionmenu, TRUE, FALSE, 0);
529 gtk_widget_show (optionmenu);
530
531
532 hbox = gtk_hbox_new (TRUE, 0);
533 gtk_widget_show (hbox);
534
535 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
536
537 button1 = gtk_button_new_with_label ("Select Output File");
538 gtk_widget_set_usize(button1, 100, -1);
539 gtkwave_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(ok_callback), NULL);
540 gtk_widget_show (button1);
541 gtk_container_add (GTK_CONTAINER (hbox), button1);
542 GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
543 gtkwave_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1));
544
545 button2 = gtk_button_new_with_label ("Exit");
546 gtk_widget_set_usize(button2, 100, -1);
547 gtkwave_signal_connect(GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(destroy_callback), NULL);
548 GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
549 gtk_widget_show (button2);
550 gtk_container_add (GTK_CONTAINER (hbox), button2);
551
552 gtk_widget_show(GLOBALS->window_renderopt_c_6);
553 }
554