1
/* gcw-lib - Library routines for the Gnome Canvas Widget device driver.
3
Copyright (C) 2005 Thomas J. Duck
9
This library is free software; you can redistribute it and/or
10
modify it under the terms of the GNU Lesser General Public
11
License as published by the Free Software Foundation; either
12
version 2.1 of the License, or (at your option) any later version.
14
This library is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
Lesser General Public License for more details.
19
You should have received a copy of the GNU Lesser General Public
20
License along with this library; if not, write to the Free Software
21
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
26
The gcw-lib API allows users to interact with the GCW driver. The
27
library routines are also invoked by the driver itself when needed.
33
extern PLStream *pls[];
35
void gcw_debug(char* msg)
42
/*--------------------------------------------------------------------------*\
45
* Sets the gdk foreground color for drawing in the current device
46
* according to the current drawing color.
48
\*--------------------------------------------------------------------------*/
50
void gcw_set_gdk_color()
53
gcw_debug("<gcw_set_gdk_color>\n");
56
GcwPLdev* dev = plsc->dev;
59
color.red=(guint16)(plsc->curcolor.r/255.*65535);
60
color.green=(guint16)(plsc->curcolor.g/255.*65535);
61
color.blue=(guint16)(plsc->curcolor.b/255.*65535);
63
if(!gdk_colormap_alloc_color(dev->colormap,&color,FALSE,TRUE))
64
plwarn("GCW driver <set_gdk_color>: Could not allocate color.");
66
gdk_gc_set_foreground(dev->gc,&color);
69
gcw_debug("</gcw_set_gdk_color>\n");
74
/*--------------------------------------------------------------------------*\
75
* gcw_clear_background()
77
* Clears the background pixmap for the current gcw device with the
80
\*--------------------------------------------------------------------------*/
82
void gcw_clear_background()
84
GcwPLdev* dev = plsc->dev;
89
gcw_debug("<clear_background>\n");
92
/* Retrieve the device width and height */
93
width = *(PLINT*)g_object_get_data(G_OBJECT(dev->canvas),"canvas-width");
94
height = *(PLINT*)g_object_get_data(G_OBJECT(dev->canvas),"canvas-height");
96
/* Allocate the background color*/
97
gdk_colormap_alloc_color(dev->colormap,&(dev->bgcolor),FALSE,TRUE);
99
/* Clear the background pixmap with the background color. Note that
100
* we are going to reset the current gdk drawing color below, so we
101
* can reuse the gc. */
102
gdk_gc_set_foreground(dev->gc,&(dev->bgcolor));
103
gdk_draw_rectangle(dev->background,dev->gc,TRUE,0,0,width,height);
105
/* Note that our pixmap is currently clear */
106
dev->pixmap_has_data = FALSE;
108
/* Reset the current gdk drawing color */
112
gcw_debug("</clear_background>\n");
117
/*--------------------------------------------------------------------------*\
120
* Initializes a canvas for use with this driver, and installs it into
121
* the current gcw device.
123
\*--------------------------------------------------------------------------*/
125
void gcw_init_canvas(GnomeCanvas* canvas)
127
GcwPLdev* dev = plsc->dev;
130
gcw_debug("<gcw_init_canvas>\n");
133
if(!GNOME_IS_CANVAS(canvas)) plexit("GCW driver: Canvas not found");
135
/* Add the canvas to the device */
138
/* Get the colormap */
139
dev->colormap = gtk_widget_get_colormap(GTK_WIDGET(dev->canvas));
141
/* Size the canvas */
142
gcw_set_canvas_size(canvas,dev->width,dev->height);
144
/* Create the persistent group, which is always visible */
145
if(!GNOME_IS_CANVAS_ITEM(
146
dev->group_persistent = GNOME_CANVAS_GROUP(gnome_canvas_item_new(
147
gnome_canvas_root(canvas),
148
gnome_canvas_clipgroup_get_type(),
153
plexit("GCW driver <gcw_init_canvas>: Canvas group cannot be created");
156
/* Set the clip to NULL */
157
g_object_set(G_OBJECT(dev->group_persistent),"path",NULL,NULL);
160
gcw_debug("</gcw_init_canvas>\n");
165
/*--------------------------------------------------------------------------*\
166
* gcw_install_canvas()
168
* Installs a canvas into the current gcw device's window. The canvas is
169
* created if necessary. A variety of callbacks are defined for actions
172
\*--------------------------------------------------------------------------*/
174
/*******************************
175
* Main window event callbacks *
176
*******************************/
178
/* Delete event callback */
179
gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data ) {
180
return FALSE; /* FALSE follows with the destroy signal */
183
/* Destroy event calback */
184
void destroy(GtkWidget *widget, gpointer data) {
192
/* All-purpose zoom callback. Referred to by specific zoom callbacks given
195
void zoom(gpointer data, gint flag) {
200
GtkWidget *scrolled_window;
203
GcwPLdev* dev = data;
207
/* Get the current canvas */
208
n = gtk_notebook_get_current_page(GTK_NOTEBOOK(dev->notebook));
209
scrolled_window = gtk_notebook_get_nth_page(GTK_NOTEBOOK(dev->notebook),n);
210
canvas = GNOME_CANVAS(gtk_container_get_children(
211
GTK_CONTAINER(gtk_container_get_children(
212
GTK_CONTAINER(scrolled_window))->data))->data);
214
/* Determine the new magnification */
215
if(flag==2) /* Zoom in */
216
gcw_set_canvas_zoom(canvas,ZOOMSTEP);
217
else if(flag==0) { /* Zoom out */
219
/* Don't zoom smaller than the original size: this causes GDK pixmap
222
gnome_canvas_c2w(canvas,1,0,&curmag,&dum);
224
if(curmag/ZOOMSTEP>1.) {
225
gcw_set_canvas_zoom(canvas,1./ZOOMSTEP);
228
gcw_set_canvas_zoom(canvas,(PLFLT)(ZOOM100/curmag));
231
else { /* Zoom 100 */
232
/* Get current magnification */
233
gnome_canvas_c2w(canvas,1,0,&curmag,&dum);
235
gcw_set_canvas_zoom(canvas,(PLFLT)(ZOOM100/curmag));
238
/* Set the focus on the notebook */
239
gtk_window_set_focus(GTK_WINDOW(dev->window),dev->notebook);
243
/* Callback when zoom in button is pressed */
244
void zoom_in(GtkWidget *widget, gpointer data ) {
248
/* Callback when zoom 100 button is pressed */
249
void zoom_100(GtkWidget *widget, gpointer data ) {
253
/* Callback when zoom out button is pressed */
254
void zoom_out(GtkWidget *widget, gpointer data ) {
258
/*****************************
259
* File selection callbacks. *
260
*****************************/
262
/* Callback to OK file selection. Retrieves the selected filename and
263
* replays the plot buffer to it through the associated driver.
265
void file_ok_sel(GtkWidget *w, gpointer data)
267
GcwPLdev* dev = data;
269
GtkWidget *scrolled_window;
275
char devname[10],str[100];
277
PLINT cur_strm, new_strm;
284
PLINT icol0,icol1,ncol0,ncol1;
285
PLColor *cmap0,*cmap1;
287
gboolean errflag = FALSE;
292
GtkWidget *hbox,*message,*icon;
297
/* Get the file name */
299
strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(dev->filew))))
301
plabort("GCW driver <file_ok_sel>: Cannot obtain filename");
303
/* Check to see if the file already exists, and respond appropriately */
304
if(stat(fname,&buf)==0) {
306
/* Confirm the user wants to overwrite the existing file */
308
dialog = GTK_DIALOG(gtk_dialog_new_with_buttons("",
309
GTK_WINDOW(dev->filew),
310
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
311
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
312
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL));
314
message = gtk_label_new("");
315
gtk_label_set_markup(GTK_LABEL(message),
316
"<span size=\"large\"><b>File exists. "
317
"Overwrite?</b></span>");
319
icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION,
320
GTK_ICON_SIZE_DIALOG);
322
hbox = gtk_hbox_new(FALSE,0);
323
gtk_box_pack_start(GTK_BOX(hbox), icon, TRUE, TRUE, 10);
324
gtk_box_pack_start(GTK_BOX(hbox), message, TRUE, TRUE, 10);
325
gtk_container_add(GTK_CONTAINER(dialog->vbox),hbox);
327
gtk_widget_show_all(GTK_WIDGET(dialog));
329
result = gtk_dialog_run(dialog);
330
gtk_widget_destroy(GTK_WIDGET(dialog));
331
if(result==GTK_RESPONSE_REJECT) return;
334
/* Hide the file selection widget */
335
gtk_widget_hide(dev->filew);
337
/* Put the focus back on the notebook */
338
gtk_window_set_focus(GTK_WINDOW(dev->window),dev->notebook);
340
/* Test that we can open and write to the file */
341
if((f=fopen(fname,"w"))==NULL)
342
plabort("GCW driver <file_ok_sel>: Cannot open output file");
344
remove(fname); /* Otherwise, we may leave behind a zero-length file */
346
/* Get the file extension and make sure we recognize it. Allow names
347
* of display devices as well.
349
* Note that we can't replot to xwin or tk devices, which can't open a
350
* display for some reason.
354
if (strcasecmp(&fname[n-3],"png")==0) sprintf(devname,"png");
355
else if(strcasecmp(&fname[n-3],"gif")==0) sprintf(devname,"gif");
356
else if(strcasecmp(&fname[n-3],"jpg")==0) sprintf(devname,"jpg");
357
else if(strcasecmp(&fname[n-4],"jpeg")==0) sprintf(devname,"jpeg");
358
else if(strcasecmp(&fname[n-2],"ps")==0) sprintf(devname,"ps");
359
else if(strcasecmp(&fname[n-3],"psc")==0) sprintf(devname,"psc");
360
else if(strcasecmp(&fname[n-4],"xwin")==0) sprintf(devname,"xwin");
361
else if(strcasecmp(&fname[n-3],"gcw")==0) sprintf(devname,"gcw");
362
else if(strcasecmp(&fname[n-2],"tk")==0) sprintf(devname,"tk");
364
if(dev->statusbar!=NULL) {
365
context=gtk_statusbar_get_context_id(GTK_STATUSBAR(dev->statusbar),
367
gtk_statusbar_push(GTK_STATUSBAR(dev->statusbar), context,
368
" WARNING: File type not recognized (unknown "
369
"extension). Use one of ps, psc, png, jpg, or "
374
else plabort("GCW driver <file_ok_sel>: File type not recognized");
377
/* Check that we are set up appropriately for device */
378
if( strcmp(devname,"ps")==0 || strcmp(devname,"psc")==0 ) {
379
if(plsc->dev_hrshsym != 1)
380
if(dev->statusbar!=NULL) {
381
context=gtk_statusbar_get_context_id(GTK_STATUSBAR(dev->statusbar),
384
gtk_statusbar_push(GTK_STATUSBAR(dev->statusbar),context,
385
" NOTE: Use '-drvopt hrshsym' on command-line "
386
"for complete symbol set in PostScript files."
390
plwarn("GCW driver: Use '-drvopt hrshsym' if symbols are missing in "
391
"saved PostScript files.");
393
if( strcmp(devname,"xwin")==0 || strcmp(devname,"tk")==0 ) {
394
if(plsc->dev_text != 0)
395
plwarn("GCW driver: Use '-drvopt text=0'");
398
/* Get the current canvas */
399
n = gtk_notebook_get_current_page(GTK_NOTEBOOK(dev->notebook));
400
scrolled_window = gtk_notebook_get_nth_page(GTK_NOTEBOOK(dev->notebook),n);
401
canvas = GNOME_CANVAS(gtk_container_get_children(
402
GTK_CONTAINER(gtk_container_get_children(
403
GTK_CONTAINER(scrolled_window))->data))->data);
405
/* Hack: Swap in the saved tempfile and colormaps */
407
plsc->plbufFile = g_object_get_data(G_OBJECT(canvas),"plotbuf");
408
if(plsc->plbufFile == NULL) errflag=TRUE;
411
if( g_object_get_data(G_OBJECT(canvas),"icol0") != NULL )
412
plsc->icol0 = *(PLINT*)g_object_get_data(G_OBJECT(canvas),"icol0");
416
if( g_object_get_data(G_OBJECT(canvas),"ncol0") != NULL )
417
plsc->ncol0 = *(PLINT*)g_object_get_data(G_OBJECT(canvas),"ncol0");
421
if( g_object_get_data(G_OBJECT(canvas),"cmap0") )
422
plsc->cmap0 = (PLColor*)g_object_get_data(G_OBJECT(canvas),"cmap0");
426
if( g_object_get_data(G_OBJECT(canvas),"icol1") != NULL )
427
plsc->icol1 = *(PLINT*)g_object_get_data(G_OBJECT(canvas),"icol1");
431
if( g_object_get_data(G_OBJECT(canvas),"ncol1") != NULL )
432
plsc->ncol1 = *(PLINT*)g_object_get_data(G_OBJECT(canvas),"ncol1");
436
if( g_object_get_data(G_OBJECT(canvas),"cmap1") != NULL )
437
plsc->cmap1 = (PLColor*)g_object_get_data(G_OBJECT(canvas),"cmap1");
442
plsetopt ("drvopt","text"); /* Blank out the drvopts (not needed here) */
444
/* Get the current stream and make a new one */
446
plsr = plsc; /* Save a pointer to the current stream */
449
plsfnam(fname); /* Set the file name */
450
plsdev(devname); /* Set the device */
452
/* Copy the current stream to the new stream. */
453
plcpstrm(cur_strm, 0);
455
plreplot(); /* do the save by replaying the plot buffer */
457
plend1(); /* finish the device */
459
plsstrm(cur_strm); /* return to previous stream */
461
else plwarn("GCW driver <file_ok_sel>: Cannot set up output stream.");
475
/* Callback to cancel file selection */
476
void file_cancel_sel(GtkWidget *w, gpointer data)
478
GcwPLdev* dev = data;
480
/* Hide the file selection widget */
481
gtk_widget_hide(dev->filew);
483
/* Put the focus back on the notebook */
484
gtk_window_set_focus(GTK_WINDOW(dev->window),dev->notebook);
487
/* Callback to create file selection dialog */
488
void filesel(GtkWidget *widget, gpointer data ) {
490
GtkWidget *scrolled_window;
493
GcwPLdev* dev = data;
497
/* Get the current canvas */
498
n = gtk_notebook_get_current_page(GTK_NOTEBOOK(dev->notebook));
499
scrolled_window = gtk_notebook_get_nth_page(GTK_NOTEBOOK(dev->notebook),n);
500
canvas = GNOME_CANVAS(gtk_container_get_children(
501
GTK_CONTAINER(gtk_container_get_children(
502
GTK_CONTAINER(scrolled_window))->data))->data);
504
/* Create a new file dialog if it doesn't already exist */
505
if(dev->filew == NULL) {
507
/* Create a new file selection widget */
508
dev->filew = gtk_file_selection_new ("File selection");
510
/* Connect the ok_button to file_ok_sel function */
511
g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(dev->filew)->ok_button),
512
"clicked", G_CALLBACK(file_ok_sel), (gpointer)dev);
514
/* Connect the cancel_button to destroy the widget */
515
g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(dev->filew)->cancel_button),
516
"clicked", G_CALLBACK(file_cancel_sel), (gpointer)dev);
518
/* Lets set the filename, as if this were a save dialog, and we are giving
519
a default filename */
520
gtk_file_selection_set_filename(GTK_FILE_SELECTION(dev->filew),
524
gtk_widget_show(dev->filew);
527
/**************************
528
* Key release callbacks. *
529
**************************/
531
void key_release(GtkWidget *widget, GdkEventKey *event, gpointer data ) {
532
if(event->keyval == '+') zoom(data,2);
533
if(event->keyval == '=') zoom(data,1);
534
if(event->keyval == '-') zoom(data,0);
535
if(event->keyval == 'q') destroy(widget,data);
538
/**********************
539
* gcw_install_canvas *
540
**********************/
542
void gcw_install_canvas(GnomeCanvas *canvas)
544
GcwPLdev* dev = plsc->dev;
545
GtkWidget *vbox,*hbox,*button,*image,*scrolled_window;
547
gboolean flag = FALSE;
552
gcw_debug("<gcw_install_canvas>\n");
555
/* Create a new canvas if needed */
556
if(!GNOME_IS_CANVAS(canvas)) {
557
if( !GNOME_IS_CANVAS(canvas = GNOME_CANVAS(gnome_canvas_new_aa())) )
558
plexit("GCW driver <gcw_install_canvas>: Could not create Canvas");
561
/* Initialize canvas */
562
gcw_init_canvas(canvas);
564
if(dev->window==NULL) { /* Create a new window and install a notebook */
568
/* Create a new window */
569
dev->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
570
gtk_window_set_title(GTK_WINDOW(dev->window),"PLplot");
572
/* Connect the signal handlers to the window decorations */
573
g_signal_connect(G_OBJECT(dev->window),"delete_event",
574
G_CALLBACK(delete_event),NULL);
575
g_signal_connect(G_OBJECT(dev->window),"destroy",G_CALLBACK(destroy),NULL);
578
/* Create a vbox and put it into the window */
579
vbox = gtk_vbox_new(FALSE,2);
580
gtk_container_add(GTK_CONTAINER(dev->window),vbox);
582
/* Create a hbox and put it into the vbox */
583
hbox = gtk_hbox_new(FALSE,0);
584
gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0);
586
/* Create a statusbar and put it into the vbox */
587
dev->statusbar = gtk_statusbar_new();
588
gtk_box_pack_start(GTK_BOX(vbox),dev->statusbar,FALSE,FALSE,0);
590
/* Add an vbox to the hbox */
591
vbox = gtk_vbox_new(FALSE,5);
592
gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
593
gtk_box_pack_start(GTK_BOX(hbox),vbox,FALSE,FALSE,0);
595
/* Create the new notebook and add it to the hbox*/
596
dev->notebook = gtk_notebook_new();
597
gtk_notebook_set_scrollable(GTK_NOTEBOOK(dev->notebook),TRUE);
598
gtk_box_pack_start(GTK_BOX(hbox),dev->notebook,TRUE,TRUE,0);
599
g_signal_connect(G_OBJECT(dev->notebook), "key_release_event",
600
G_CALLBACK(key_release), G_OBJECT(dev->notebook));
602
/* Use a few labels as spacers */
603
gtk_box_pack_start(GTK_BOX(vbox),gtk_label_new(" "),FALSE,FALSE,0);
604
gtk_box_pack_start(GTK_BOX(vbox),gtk_label_new(" "),FALSE,FALSE,0);
606
/* Add buttons to the vbox */
608
/* Add zoom in button and create callbacks */
609
image = gtk_image_new_from_stock(GTK_STOCK_ZOOM_IN,
610
GTK_ICON_SIZE_SMALL_TOOLBAR);
611
button = gtk_button_new();
612
gtk_container_add(GTK_CONTAINER(button),image);
613
gtk_box_pack_start(GTK_BOX(vbox),button,FALSE,FALSE,0);
614
g_signal_connect (G_OBJECT(button), "clicked",
615
G_CALLBACK(zoom_in), (gpointer)dev);
616
g_signal_connect(G_OBJECT(button), "key_release_event",
617
G_CALLBACK(key_release), (gpointer)dev);
619
/* Add zoom100 button and create callbacks */
620
image = gtk_image_new_from_stock(GTK_STOCK_ZOOM_100,
621
GTK_ICON_SIZE_SMALL_TOOLBAR);
622
button = gtk_button_new();
623
gtk_container_add(GTK_CONTAINER(button),image);
624
gtk_box_pack_start(GTK_BOX(vbox),button,FALSE,FALSE,0);
625
g_signal_connect (G_OBJECT(button), "clicked",
626
G_CALLBACK(zoom_100), (gpointer)dev);
628
/* Add zoom out button and create callbacks */
629
image = gtk_image_new_from_stock(GTK_STOCK_ZOOM_OUT,
630
GTK_ICON_SIZE_SMALL_TOOLBAR);
631
button = gtk_button_new();
632
gtk_container_add(GTK_CONTAINER(button),image);
633
gtk_box_pack_start(GTK_BOX(vbox),button,FALSE,FALSE,0);
634
g_signal_connect (G_OBJECT(button), "clicked",
635
G_CALLBACK(zoom_out), (gpointer)dev);
636
g_signal_connect(G_OBJECT(button), "key_release_event",
637
G_CALLBACK(key_release), (gpointer)dev);
639
/* Add save button and create callbacks */
640
if(plsc->plbuf_write) {
641
image = gtk_image_new_from_stock(GTK_STOCK_SAVE,
642
GTK_ICON_SIZE_SMALL_TOOLBAR);
643
button = gtk_button_new();
644
gtk_container_add(GTK_CONTAINER(button),image);
645
gtk_box_pack_start(GTK_BOX(vbox),button,FALSE,FALSE,0);
646
g_signal_connect (G_OBJECT(button), "clicked",
647
G_CALLBACK(filesel), (gpointer)dev);
649
} /* if(dev->window==NULL) */
651
/* Put the canvas in a scrolled window */
652
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
653
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
654
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
655
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),
658
/* Install the scrolled window in the notebook */
659
gtk_notebook_append_page(GTK_NOTEBOOK(dev->notebook),scrolled_window, NULL);
663
/* Set the focus on the notebook */
664
gtk_window_set_focus(GTK_WINDOW(dev->window),dev->notebook);
666
/* Retrieve the canvas width and height */
667
width = *(PLINT*)g_object_get_data(G_OBJECT(canvas),"canvas-width");
668
height = *(PLINT*)g_object_get_data(G_OBJECT(canvas),"canvas-height");
670
/* Size the window */
671
gtk_window_resize(GTK_WINDOW(dev->window),width*ZOOM100+65,
675
/* Display everything */
676
gtk_widget_show_all(dev->window);
679
gcw_debug("</gcw_install_canvas>\n");
684
/*--------------------------------------------------------------------------*\
685
* gcw_set_device_size()
687
* Sets the page size for this device.
689
* Width and height are both measured in device coordinate units.
691
* Note that coordinates in driver-space are measured in device units,
692
* which correspond to the pixel size on a typical screen. The coordinates
693
* reported and received from the PLplot core, however, are in virtual
694
* coordinates, which is just a scaled version of the device coordinates.
695
* This strategy is used so that the calculations in the PLplot
696
* core are performed at reasonably high resolution.
698
\*--------------------------------------------------------------------------*/
700
void gcw_set_device_size(PLINT width,PLINT height) {
701
GcwPLdev* dev = plsc->dev;
704
/* Set the number of virtual coordinate units per mm */
705
plP_setpxl((PLFLT)VIRTUAL_PIXELS_PER_MM,(PLFLT)VIRTUAL_PIXELS_PER_MM);
707
/* Set up physical limits of plotting device, in virtual coord units */
708
w = (PLINT)(width*VSCALE);
709
h = (PLINT)(height*VSCALE);
710
plP_setphy((PLINT)0,w,(PLINT)0,h);
712
/* Save the width and height for the device, in device units */
714
dev->height = height;
717
/*--------------------------------------------------------------------------*\
718
* gcw_set_canvas_size()
720
* Sets the canvas size. If resizing is not allowed, this function
721
* ensures that the canvas size matches the physical page size.
723
\*--------------------------------------------------------------------------*/
727
void gcw_set_canvas_size(GnomeCanvas* canvas,PLINT width,PLINT height)
729
GcwPLdev* dev = plsc->dev;
739
GdkPixmap *background;
742
gcw_debug("<gcw_set_canvas_size>\n");
745
/* Set the device size, if resizing is allowed. */
746
if(dev->allow_resize) gcw_set_device_size(width,height);
749
height = dev->height;
750
if(plsc->portrait) { /* Swap width and height of display */
756
/* The width and height need to be enlarged by 1 pixel for the canvas */
760
/* Attach the width and height to the canvas */
761
if((w=(PLINT*)malloc(sizeof(gint)))==NULL)
762
plwarn("GCW driver <gcw_set_canvas_size>: Insufficient memory.");
763
if((h=(PLINT*)malloc(sizeof(gint)))==NULL)
764
plwarn("GCW driver <gcw_set_canvas_size>: Insufficient memory.");
767
g_object_set_data(G_OBJECT(canvas),"canvas-width",(gpointer)w);
768
g_object_set_data(G_OBJECT(canvas),"canvas-height",(gpointer)h);
770
/* Size the canvas appropriately */
771
gtk_widget_set_size_request(GTK_WIDGET(canvas),(gint)(width),
774
/* Position the canvas appropriately */
775
gnome_canvas_set_scroll_region(canvas,0.,(gdouble)(-height),
776
(gdouble)(width),1.);
778
/* Set up the background pixmap */
779
if(dev->background==NULL || dev->allow_resize) {
781
if(GDK_IS_PIXMAP(dev->background)) g_object_unref(dev->background);
783
/* Why does this next *useless* command speed up the animation demo?
784
* If we unref the allocated pixmaps, the benefit goes away!! */
786
/* gdk_pixmap_new(NULL,width,height,gdk_visual_get_best_depth()); */
787
/* printf("Count %d\n",count); */
790
/* else { printf("Count %d\n",count); count ++; } */
792
dev->background = gdk_pixmap_new(NULL,width,height,
793
gtk_widget_get_visual(GTK_WIDGET(canvas))->depth);
796
/* Set up the drawing context for the background pixmap */
797
if(dev->gc==NULL || dev->allow_resize) {
799
/* Maintain the old values for pen width, color, etc */
800
if(GDK_IS_GC(dev->gc)) {
801
gdk_gc_get_values(dev->gc,&values);
802
gdk_gc_unref(dev->gc);
803
dev->gc = gdk_gc_new_with_values(dev->background,&values,
804
GDK_GC_FOREGROUND | GDK_GC_LINE_WIDTH |
805
GDK_GC_LINE_STYLE | GDK_GC_CAP_STYLE |
808
else dev->gc = gdk_gc_new(dev->background);
811
/* Clear the background pixmap */
812
gcw_clear_background(dev);
814
/* Advance the page if we are allowing resizing. This ensures that
815
* the physical coordinate system is set up correctly.
817
if(dev->allow_resize) pladv(0);
820
gcw_debug("</gcw_set_canvas_size>\n");
825
/*--------------------------------------------------------------------------*\
826
* gcw_set_canvas_zoom()
828
* Sets the zoom magnification on the canvas and resizes the widget
830
\*--------------------------------------------------------------------------*/
832
void gcw_set_canvas_zoom(GnomeCanvas* canvas,PLFLT magnification)
834
gdouble curmag=1.,dum;
839
gcw_debug("<gcw_set_canvas_zoom>\n");
842
/* Retrieve the device width and height */
843
width = *(PLINT*)g_object_get_data(G_OBJECT(canvas),"canvas-width");
844
height = *(PLINT*)g_object_get_data(G_OBJECT(canvas),"canvas-height");
846
/* Get the current magnification */
847
gnome_canvas_c2w(canvas,1,0,&curmag,&dum);
850
/* Apply the new magnification */
851
gnome_canvas_set_pixels_per_unit(canvas,magnification*curmag);
853
/* Size the canvas appropriately */
854
gtk_widget_set_size_request(GTK_WIDGET(canvas),
855
(gint)((width)*magnification*curmag),
856
(gint)((height)*magnification*curmag));
858
/* Position the canvas appropriately */
859
gnome_canvas_set_scroll_region(canvas,0.,(gdouble)(-height),
860
(gdouble)(width),1.);
863
gcw_debug("</gcw_set_canvas_zoom>\n");
868
/*--------------------------------------------------------------------------*\
871
* Used to turn text usage on and off for the current device.
872
\*--------------------------------------------------------------------------*/
874
void gcw_use_text(PLINT use_text)
876
GcwPLdev* dev = plsc->dev;
879
gcw_debug("<gcw_use_text>\n");
884
if(use_text) plsc->dev_text = 1; /* Allow text handling */
885
else plsc->dev_text = 0; /* Disallow text handling */
890
gcw_debug("</gcw_use_text>\n");
895
/*--------------------------------------------------------------------------*\
898
* Used to turn pixmap usage on and off for the current device.
899
* This is relevant for polygon fills (used during shading calls).
900
\*--------------------------------------------------------------------------*/
902
void gcw_use_pixmap(PLINT use_pixmap)
904
GcwPLdev* dev = plsc->dev;
907
gcw_debug("<gcw_use_pixmap>\n");
910
dev->use_pixmap = (gboolean)use_pixmap;
913
gcw_debug("</gcw_use_pixmap>\n");
918
/*--------------------------------------------------------------------------*\
921
* Used to turn hershey symbol usage on and off for the current device.
922
\*--------------------------------------------------------------------------*/
924
void gcw_use_hrshsym(PLINT use_hrshsym)
926
GcwPLdev* dev = plsc->dev;
929
gcw_debug("<gcw_use_hrshsym>\n");
932
plsc->dev_hrshsym = use_hrshsym;
935
gcw_debug("</gcw_use_hrshsym>\n");
940
/*--------------------------------------------------------------------------*\
941
* gcw_use_persistence
943
* Directs the GCW driver whether or not the subsequent drawing operations
944
* should be persistent.
945
\*--------------------------------------------------------------------------*/
947
void gcw_use_persistence(PLINT use_persistence)
949
GcwPLdev* dev = plsc->dev;
952
gcw_debug("<gcw_use_persistence>\n");
955
dev->use_persistence = (gboolean)use_persistence;
958
gcw_debug("</gcw_use_persistence>\n");