PLplot  5.10.0
gcw-lib.c
Go to the documentation of this file.
00001 // gcw-lib - Library routines for the Gnome Canvas Widget device driver.
00002 //
00003 // Copyright (C) 2005  Thomas J. Duck
00004 // All rights reserved.
00005 //
00006 //
00007 // NOTICE
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2.1 of the License, or (at your option) any later version.
00013 //
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Lesser General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
00022 // USA
00023 //
00024 // DESCRIPTION
00025 //
00026 // The gcw-lib API allows users to interact with the GCW driver.  The
00027 // library routines are also invoked by the driver itself when needed.
00028 //
00029 //
00030 
00031 #include "gcw.h"
00032 
00033 extern PLStream *pls[];
00034 
00035 void gcw_debug( char* msg )
00036 {
00037     fputs( msg, stderr );
00038     fflush( stderr );
00039 }
00040 
00041 
00042 //--------------------------------------------------------------------------
00043 // gcw_set_gdk_color()
00044 //
00045 // Sets the gdk foreground color for drawing in the current device
00046 // according to the current drawing color.
00047 //
00048 //--------------------------------------------------------------------------
00049 
00050 void gcw_set_gdk_color()
00051 {
00052 #ifdef DEBUG_GCW_1
00053     gcw_debug( "<gcw_set_gdk_color>\n" );
00054 #endif
00055 
00056     GcwPLdev * dev = plsc->dev;
00057     GdkColor color;
00058 
00059     color.red   = (guint16) ( plsc->curcolor.r / 255. * 65535 );
00060     color.green = (guint16) ( plsc->curcolor.g / 255. * 65535 );
00061     color.blue  = (guint16) ( plsc->curcolor.b / 255. * 65535 );
00062 
00063     if ( !gdk_colormap_alloc_color( dev->colormap, &color, FALSE, TRUE ) )
00064         plwarn( "GCW driver <set_gdk_color>: Could not allocate color." );
00065 
00066     gdk_gc_set_foreground( dev->gc, &color );
00067 
00068 #ifdef DEBUG_GCW_1
00069     gcw_debug( "</gcw_set_gdk_color>\n" );
00070 #endif
00071 }
00072 
00073 
00074 //--------------------------------------------------------------------------
00075 // gcw_clear_background()
00076 //
00077 // Clears the background pixmap for the current gcw device with the
00078 // background color.
00079 //
00080 //--------------------------------------------------------------------------
00081 
00082 void gcw_clear_background()
00083 {
00084     GcwPLdev* dev = plsc->dev;
00085 
00086     PLINT   width, height;
00087 
00088 #ifdef DEBUG_GCW_1
00089     gcw_debug( "<clear_background>\n" );
00090 #endif
00091 
00092     // Retrieve the device width and height
00093     width  = *(PLINT *) g_object_get_data( G_OBJECT( dev->canvas ), "canvas-width" );
00094     height = *(PLINT *) g_object_get_data( G_OBJECT( dev->canvas ), "canvas-height" );
00095 
00096     // Allocate the background color
00097     gdk_colormap_alloc_color( dev->colormap, &( dev->bgcolor ), FALSE, TRUE );
00098 
00099     // Clear the background pixmap with the background color.  Note that
00100     // we are going to reset the current gdk drawing color below, so we
00101     // can reuse the gc.
00102     gdk_gc_set_foreground( dev->gc, &( dev->bgcolor ) );
00103     gdk_draw_rectangle( dev->background, dev->gc, TRUE, 0, 0, width, height );
00104 
00105     // Note that our pixmap is currently clear
00106     dev->pixmap_has_data = FALSE;
00107 
00108     // Reset the current gdk drawing color
00109     gcw_set_gdk_color();
00110 
00111 #ifdef DEBUG_GCW_1
00112     gcw_debug( "</clear_background>\n" );
00113 #endif
00114 }
00115 
00116 
00117 //--------------------------------------------------------------------------
00118 // gcw_init_canvas()
00119 //
00120 // Initializes a canvas for use with this driver, and installs it into
00121 // the current gcw device.
00122 //
00123 //--------------------------------------------------------------------------
00124 
00125 void gcw_init_canvas( GnomeCanvas* canvas )
00126 {
00127     GcwPLdev* dev = plsc->dev;
00128 
00129 #ifdef DEBUG_GCW_1
00130     gcw_debug( "<gcw_init_canvas>\n" );
00131 #endif
00132 
00133     if ( !GNOME_IS_CANVAS( canvas ) )
00134         plexit( "GCW driver: Canvas not found" );
00135 
00136     // Add the canvas to the device
00137     dev->canvas = canvas;
00138 
00139     // Get the colormap
00140     dev->colormap = gtk_widget_get_colormap( GTK_WIDGET( dev->canvas ) );
00141 
00142     // Size the canvas
00143     gcw_set_canvas_size( canvas, dev->width, dev->height );
00144 
00145     // Create the persistent group, which is always visible
00146     if ( !GNOME_IS_CANVAS_ITEM(
00147              dev->group_persistent = GNOME_CANVAS_GROUP( gnome_canvas_item_new(
00148                      gnome_canvas_root( canvas ),
00149                      gnome_canvas_clipgroup_get_type(),
00150                      "x", 0.,
00151                      "y", 0.,
00152                      NULL ) )
00153              ) )
00154     {
00155         plexit( "GCW driver <gcw_init_canvas>: Canvas group cannot be created" );
00156     }
00157 
00158     // Set the clip to NULL
00159     g_object_set( G_OBJECT( dev->group_persistent ), "path", NULL, NULL );
00160 
00161 #ifdef DEBUG_GCW1
00162     gcw_debug( "</gcw_init_canvas>\n" );
00163 #endif
00164 }
00165 
00166 
00167 //--------------------------------------------------------------------------
00168 // gcw_install_canvas()
00169 //
00170 // Installs a canvas into the current gcw device's window.  The canvas is
00171 // created if necessary.  A variety of callbacks are defined for actions
00172 // in the window.
00173 //
00174 //--------------------------------------------------------------------------
00175 
00176 //******************************
00177 // Main window event callbacks *
00178 //*****************************
00179 
00180 // Delete event callback
00181 gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
00182 {
00183     return FALSE; // FALSE follows with the destroy signal
00184 }
00185 
00186 // Destroy event calback
00187 void destroy( GtkWidget *widget, gpointer data )
00188 {
00189     gtk_main_quit();
00190 }
00191 
00192 //*****************
00193 // Zoom callbacks *
00194 //****************
00195 
00196 // All-purpose zoom callback.  Referred to by specific zoom callbacks given
00197 //  below.
00198 //
00199 void zoom( gpointer data, gint flag )
00200 {
00201     gint        n;
00202 
00203     GnomeCanvas *canvas;
00204     GtkWidget   *scrolled_window;
00205     GList       *list;
00206 
00207     GcwPLdev    * dev = data;
00208 
00209     gdouble     curmag, dum;
00210 
00211     // Get the current canvas
00212     n = gtk_notebook_get_current_page( GTK_NOTEBOOK( dev->notebook ) );
00213     scrolled_window = gtk_notebook_get_nth_page( GTK_NOTEBOOK( dev->notebook ), n );
00214     canvas          = GNOME_CANVAS( gtk_container_get_children(
00215             GTK_CONTAINER( gtk_container_get_children(
00216                     GTK_CONTAINER( scrolled_window ) )->data ) )->data );
00217 
00218     // Determine the new magnification
00219     if ( flag == 2 )      // Zoom in
00220         gcw_set_canvas_zoom( canvas, ZOOMSTEP );
00221     else if ( flag == 0 ) // Zoom out
00222 
00223     {                     // Don't zoom smaller than the original size: this causes GDK pixmap
00224         // errors.
00225         //
00226         gnome_canvas_c2w( canvas, 1, 0, &curmag, &dum );
00227         curmag = 1. / curmag;
00228         if ( curmag / ZOOMSTEP > 1. )
00229         {
00230             gcw_set_canvas_zoom( canvas, 1. / ZOOMSTEP );
00231         }
00232         else
00233         {
00234             gcw_set_canvas_zoom( canvas, (PLFLT) ( ZOOM100 / curmag ) );
00235         }
00236     }
00237     else // Zoom 100
00238     {
00239         // Get current magnification
00240         gnome_canvas_c2w( canvas, 1, 0, &curmag, &dum );
00241         curmag = 1. / curmag;
00242         gcw_set_canvas_zoom( canvas, (PLFLT) ( ZOOM100 / curmag ) );
00243     }
00244 
00245     // Set the focus on the notebook
00246     gtk_window_set_focus( GTK_WINDOW( dev->window ), dev->notebook );
00247 }
00248 
00249 
00250 // Callback when zoom in button is pressed
00251 void zoom_in( GtkWidget *widget, gpointer data )
00252 {
00253     zoom( data, 2 );
00254 }
00255 
00256 // Callback when zoom 100 button is pressed
00257 void zoom_100( GtkWidget *widget, gpointer data )
00258 {
00259     zoom( data, 1 );
00260 }
00261 
00262 // Callback when zoom out button is pressed
00263 void zoom_out( GtkWidget *widget, gpointer data )
00264 {
00265     zoom( data, 0 );
00266 }
00267 
00268 //****************************
00269 // File selection callbacks. *
00270 //***************************
00271 
00272 // Callback to OK file selection.  Retrieves the selected filename and
00273 // replays the plot buffer to it through the associated driver.
00274 //
00275 void file_ok_sel( GtkWidget *w, gpointer data )
00276 {
00277     GcwPLdev    * dev = data;
00278 
00279     GtkWidget   *scrolled_window;
00280     GnomeCanvas *canvas;
00281 
00282     gchar       *fname;
00283     guint       n;
00284     char        devname[10], str[100];
00285 
00286     void        *save_state;
00287     void        *new_state;
00288 
00289     PLINT       cur_strm, new_strm;
00290     PLStream    *plsr;
00291 
00292     GtkWidget   *fs;
00293 
00294     gdouble     curmag, dum;
00295 
00296     gboolean    errflag = FALSE;
00297 
00298     struct stat buf;
00299 
00300     GtkDialog   *dialog;
00301     GtkWidget   *hbox, *message, *icon;
00302     gint        result;
00303 
00304     guint       context;
00305 
00306     FILE        *f;
00307 
00308     // Get the file name
00309     if ( ( fname =
00310                strdup( gtk_file_selection_get_filename( GTK_FILE_SELECTION( dev->filew ) ) ) )
00311          == NULL )
00312         plabort( "GCW driver <file_ok_sel>: Cannot obtain filename" );
00313 
00314     // Check to see if the file already exists, and respond appropriately
00315     if ( stat( fname, &buf ) == 0 )
00316     {
00317         // Confirm the user wants to overwrite the existing file
00318 
00319         dialog = GTK_DIALOG( gtk_dialog_new_with_buttons( "",
00320                 GTK_WINDOW( dev->filew ),
00321                 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
00322                 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
00323                 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL ) );
00324 
00325         message = gtk_label_new( "" );
00326         gtk_label_set_markup( GTK_LABEL( message ),
00327             "<span size=\"large\"><b>File exists.  "
00328             "Overwrite?</b></span>" );
00329 
00330         icon = gtk_image_new_from_stock( GTK_STOCK_DIALOG_QUESTION,
00331             GTK_ICON_SIZE_DIALOG );
00332 
00333         hbox = gtk_hbox_new( FALSE, 0 );
00334         gtk_box_pack_start( GTK_BOX( hbox ), icon, TRUE, TRUE, 10 );
00335         gtk_box_pack_start( GTK_BOX( hbox ), message, TRUE, TRUE, 10 );
00336         gtk_container_add( GTK_CONTAINER( dialog->vbox ), hbox );
00337 
00338         gtk_widget_show_all( GTK_WIDGET( dialog ) );
00339 
00340         result = gtk_dialog_run( dialog );
00341         gtk_widget_destroy( GTK_WIDGET( dialog ) );
00342         if ( result == GTK_RESPONSE_REJECT )
00343             return;
00344     }
00345 
00346     // Hide the file selection widget
00347     gtk_widget_hide( dev->filew );
00348 
00349     // Put the focus back on the notebook
00350     gtk_window_set_focus( GTK_WINDOW( dev->window ), dev->notebook );
00351 
00352     // Test that we can open and write to the file
00353     if ( ( f = fopen( fname, "w" ) ) == NULL )
00354         plabort( "GCW driver <file_ok_sel>: Cannot open output file" );
00355     fclose( f );
00356     remove( fname ); // Otherwise, we may leave behind a zero-length file
00357 
00358     // Get the file extension and make sure we recognize it.  Allow names
00359     // of display devices as well.
00360     //
00361     // Note that we can't replot to xwin or tk devices, which can't open a
00362     // display for some reason.
00363     //
00364     //
00365     n = strlen( fname );
00366     if ( strcasecmp( &fname[n - 3], "png" ) == 0 )
00367         sprintf( devname, "png" );
00368     else if ( strcasecmp( &fname[n - 3], "gif" ) == 0 )
00369         sprintf( devname, "gif" );
00370     else if ( strcasecmp( &fname[n - 3], "jpg" ) == 0 )
00371         sprintf( devname, "jpg" );
00372     else if ( strcasecmp( &fname[n - 4], "jpeg" ) == 0 )
00373         sprintf( devname, "jpeg" );
00374     else if ( strcasecmp( &fname[n - 2], "ps" ) == 0 )
00375         sprintf( devname, "ps" );
00376     else if ( strcasecmp( &fname[n - 3], "psc" ) == 0 )
00377         sprintf( devname, "psc" );
00378     else if ( strcasecmp( &fname[n - 4], "xwin" ) == 0 )
00379         sprintf( devname, "xwin" );
00380     else if ( strcasecmp( &fname[n - 3], "gcw" ) == 0 )
00381         sprintf( devname, "gcw" );
00382     else if ( strcasecmp( &fname[n - 2], "tk" ) == 0 )
00383         sprintf( devname, "tk" );
00384     else
00385     {
00386         if ( dev->statusbar != NULL )
00387         {
00388             context = gtk_statusbar_get_context_id( GTK_STATUSBAR( dev->statusbar ),
00389                 "PLplot" );
00390             gtk_statusbar_push( GTK_STATUSBAR( dev->statusbar ), context,
00391                 " WARNING: File type not recognized (unknown "
00392                 "extension).  Use one of ps, psc, png, jpg, or "
00393                 "gif."
00394                 );
00395             return;
00396         }
00397         else
00398             plabort( "GCW driver <file_ok_sel>: File type not recognized" );
00399     }
00400 
00401     // Check that we are set up appropriately for device
00402     if ( strcmp( devname, "ps" ) == 0 || strcmp( devname, "psc" ) == 0 )
00403     {
00404         if ( plsc->dev_hrshsym != 1 )
00405             if ( dev->statusbar != NULL )
00406             {
00407                 context = gtk_statusbar_get_context_id( GTK_STATUSBAR( dev->statusbar ),
00408                     "PLplot" );
00409 
00410                 gtk_statusbar_push( GTK_STATUSBAR( dev->statusbar ), context,
00411                     " NOTE: Use '-drvopt hrshsym' on command-line "
00412                     "for complete symbol set in PostScript files."
00413                     );
00414             }
00415             else
00416                 plwarn( "GCW driver: Use '-drvopt hrshsym' if symbols are missing in "
00417                     "saved PostScript files." );
00418     }
00419     if ( strcmp( devname, "xwin" ) == 0 || strcmp( devname, "tk" ) == 0 )
00420     {
00421         if ( plsc->dev_text != 0 )
00422             plwarn( "GCW driver: Use '-drvopt text=0'" );
00423     }
00424 
00425     // Get the current canvas
00426     n = gtk_notebook_get_current_page( GTK_NOTEBOOK( dev->notebook ) );
00427     scrolled_window = gtk_notebook_get_nth_page( GTK_NOTEBOOK( dev->notebook ), n );
00428     canvas          = GNOME_CANVAS( gtk_container_get_children(
00429             GTK_CONTAINER( gtk_container_get_children(
00430                     GTK_CONTAINER( scrolled_window ) )->data ) )->data );
00431 
00432     // Switch in the previously saved plot state
00433     new_state = g_object_get_data( G_OBJECT( canvas ), "plotbuf" );
00434 
00435     if ( new_state != NULL )
00436     {
00437         save_state = (void *) plbuf_switch( plsc, new_state );
00438 
00439         plsetopt( "drvopt", "text" ); // Blank out the drvopts (not needed here)
00440 
00441         // Get the current stream and make a new one
00442         plgstrm( &cur_strm );
00443         plsr = plsc; // Save a pointer to the current stream
00444 
00445         plmkstrm( &new_strm );
00446         plsfnam( fname );  // Set the file name
00447         plsdev( devname ); // Set the device
00448 
00449         // Copy the current stream to the new stream.
00450         plcpstrm( cur_strm, 0 );
00451 
00452         plreplot();          // do the save by replaying the plot buffer
00453 
00454         plend1();            // finish the device
00455 
00456         plsstrm( cur_strm ); // return to previous stream
00457 
00458         plbuf_restore( plsc, save_state );
00459         free( save_state );
00460     }
00461     else
00462     {
00463         plwarn( "GCW driver <file_ok_sel>: Cannot set up output stream." );
00464     }
00465 }
00466 
00467 // Callback to cancel file selection
00468 void file_cancel_sel( GtkWidget *w, gpointer data )
00469 {
00470     GcwPLdev* dev = data;
00471 
00472     // Hide the file selection widget
00473     gtk_widget_hide( dev->filew );
00474 
00475     // Put the focus back on the notebook
00476     gtk_window_set_focus( GTK_WINDOW( dev->window ), dev->notebook );
00477 }
00478 
00479 // Callback to create file selection dialog
00480 void filesel( GtkWidget *widget, gpointer data )
00481 {
00482     GtkWidget   *scrolled_window;
00483     GnomeCanvas *canvas;
00484 
00485     GcwPLdev    * dev = data;
00486 
00487     guint       n;
00488 
00489     // Get the current canvas
00490     n = gtk_notebook_get_current_page( GTK_NOTEBOOK( dev->notebook ) );
00491     scrolled_window = gtk_notebook_get_nth_page( GTK_NOTEBOOK( dev->notebook ), n );
00492     canvas          = GNOME_CANVAS( gtk_container_get_children(
00493             GTK_CONTAINER( gtk_container_get_children(
00494                     GTK_CONTAINER( scrolled_window ) )->data ) )->data );
00495 
00496     // Create a new file dialog if it doesn't already exist
00497     if ( dev->filew == NULL )
00498     {
00499         // Create a new file selection widget
00500         dev->filew = gtk_file_selection_new( "File selection" );
00501 
00502         // Connect the ok_button to file_ok_sel function
00503         g_signal_connect( G_OBJECT( GTK_FILE_SELECTION( dev->filew )->ok_button ),
00504             "clicked", G_CALLBACK( file_ok_sel ), (gpointer) dev );
00505 
00506         // Connect the cancel_button to destroy the widget
00507         g_signal_connect( G_OBJECT( GTK_FILE_SELECTION( dev->filew )->cancel_button ),
00508             "clicked", G_CALLBACK( file_cancel_sel ), (gpointer) dev );
00509 
00510         // Lets set the filename, as if this were a save dialog, and we are giving
00511         // a default filename
00512         gtk_file_selection_set_filename( GTK_FILE_SELECTION( dev->filew ),
00513             "plot.psc" );
00514     }
00515 
00516     gtk_widget_show( dev->filew );
00517 }
00518 
00519 //*************************
00520 // Key release callbacks. *
00521 //************************
00522 
00523 void key_release( GtkWidget *widget, GdkEventKey  *event, gpointer data )
00524 {
00525     if ( event->keyval == '+' )
00526         zoom( data, 2 );
00527     if ( event->keyval == '=' )
00528         zoom( data, 1 );
00529     if ( event->keyval == '-' )
00530         zoom( data, 0 );
00531     if ( event->keyval == 'q' )
00532         destroy( widget, data );
00533 }
00534 
00535 //*********************
00536 // gcw_install_canvas *
00537 //********************
00538 
00539 void gcw_install_canvas( GnomeCanvas *canvas )
00540 {
00541     GcwPLdev  * dev = plsc->dev;
00542     GtkWidget *vbox, *hbox, *button, *image, *scrolled_window;
00543 
00544     gboolean  flag = FALSE;
00545 
00546     PLINT     width, height;
00547 
00548 #ifdef DEBUG_GCW_1
00549     gcw_debug( "<gcw_install_canvas>\n" );
00550 #endif
00551 
00552     // Create a new canvas if needed
00553     if ( !GNOME_IS_CANVAS( canvas ) )
00554     {
00555         if ( !GNOME_IS_CANVAS( canvas = GNOME_CANVAS( gnome_canvas_new_aa() ) ) )
00556             plexit( "GCW driver <gcw_install_canvas>: Could not create Canvas" );
00557     }
00558 
00559     // Initialize canvas
00560     gcw_init_canvas( canvas );
00561 
00562     if ( dev->window == NULL ) // Create a new window and install a notebook
00563 
00564     {
00565         flag = TRUE;
00566 
00567         // Create a new window
00568         dev->window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
00569         gtk_window_set_title( GTK_WINDOW( dev->window ), "PLplot" );
00570 
00571         // Connect the signal handlers to the window decorations
00572         g_signal_connect( G_OBJECT( dev->window ), "delete_event",
00573             G_CALLBACK( delete_event ), NULL );
00574         g_signal_connect( G_OBJECT( dev->window ), "destroy", G_CALLBACK( destroy ), NULL );
00575 
00576 
00577         // Create a vbox and put it into the window
00578         vbox = gtk_vbox_new( FALSE, 2 );
00579         gtk_container_add( GTK_CONTAINER( dev->window ), vbox );
00580 
00581         // Create a hbox and put it into the vbox
00582         hbox = gtk_hbox_new( FALSE, 0 );
00583         gtk_box_pack_start( GTK_BOX( vbox ), hbox, TRUE, TRUE, 0 );
00584 
00585         // Create a statusbar and put it into the vbox
00586         dev->statusbar = gtk_statusbar_new();
00587         gtk_box_pack_start( GTK_BOX( vbox ), dev->statusbar, FALSE, FALSE, 0 );
00588 
00589         // Add an vbox to the hbox
00590         vbox = gtk_vbox_new( FALSE, 5 );
00591         gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
00592         gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 0 );
00593 
00594         // Create the new notebook and add it to the hbox
00595         dev->notebook = gtk_notebook_new();
00596         gtk_notebook_set_scrollable( GTK_NOTEBOOK( dev->notebook ), TRUE );
00597         gtk_box_pack_start( GTK_BOX( hbox ), dev->notebook, TRUE, TRUE, 0 );
00598         g_signal_connect( G_OBJECT( dev->notebook ), "key_release_event",
00599             G_CALLBACK( key_release ), G_OBJECT( dev->notebook ) );
00600 
00601         // Use a few labels as spacers
00602         gtk_box_pack_start( GTK_BOX( vbox ), gtk_label_new( " " ), FALSE, FALSE, 0 );
00603         gtk_box_pack_start( GTK_BOX( vbox ), gtk_label_new( " " ), FALSE, FALSE, 0 );
00604 
00605         // Add buttons to the vbox
00606 
00607         // Add zoom in button and create callbacks
00608         image = gtk_image_new_from_stock( GTK_STOCK_ZOOM_IN,
00609             GTK_ICON_SIZE_SMALL_TOOLBAR );
00610         button = gtk_button_new();
00611         gtk_container_add( GTK_CONTAINER( button ), image );
00612         gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
00613         g_signal_connect( G_OBJECT( button ), "clicked",
00614             G_CALLBACK( zoom_in ), (gpointer) dev );
00615         g_signal_connect( G_OBJECT( button ), "key_release_event",
00616             G_CALLBACK( key_release ), (gpointer) dev );
00617 
00618         // Add zoom100 button and create callbacks
00619         image = gtk_image_new_from_stock( GTK_STOCK_ZOOM_100,
00620             GTK_ICON_SIZE_SMALL_TOOLBAR );
00621         button = gtk_button_new();
00622         gtk_container_add( GTK_CONTAINER( button ), image );
00623         gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
00624         g_signal_connect( G_OBJECT( button ), "clicked",
00625             G_CALLBACK( zoom_100 ), (gpointer) dev );
00626 
00627         // Add zoom out button and create callbacks
00628         image = gtk_image_new_from_stock( GTK_STOCK_ZOOM_OUT,
00629             GTK_ICON_SIZE_SMALL_TOOLBAR );
00630         button = gtk_button_new();
00631         gtk_container_add( GTK_CONTAINER( button ), image );
00632         gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
00633         g_signal_connect( G_OBJECT( button ), "clicked",
00634             G_CALLBACK( zoom_out ), (gpointer) dev );
00635         g_signal_connect( G_OBJECT( button ), "key_release_event",
00636             G_CALLBACK( key_release ), (gpointer) dev );
00637 
00638         // Add save button and create callbacks
00639         if ( plsc->plbuf_write )
00640         {
00641             image = gtk_image_new_from_stock( GTK_STOCK_SAVE,
00642                 GTK_ICON_SIZE_SMALL_TOOLBAR );
00643             button = gtk_button_new();
00644             gtk_container_add( GTK_CONTAINER( button ), image );
00645             gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 );
00646             g_signal_connect( G_OBJECT( button ), "clicked",
00647                 G_CALLBACK( filesel ), (gpointer) dev );
00648         }
00649     } // if(dev->window==NULL)
00650 
00651     // Put the canvas in a scrolled window
00652     scrolled_window = gtk_scrolled_window_new( NULL, NULL );
00653     gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolled_window ),
00654         GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
00655     gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled_window ),
00656         GTK_WIDGET( canvas ) );
00657 
00658     // Install the scrolled window in the notebook
00659     gtk_notebook_append_page( GTK_NOTEBOOK( dev->notebook ), scrolled_window, NULL );
00660 
00661     if ( flag )
00662     {
00663         // Set the focus on the notebook
00664         gtk_window_set_focus( GTK_WINDOW( dev->window ), dev->notebook );
00665 
00666         // Retrieve the canvas width and height
00667         width  = *(PLINT *) g_object_get_data( G_OBJECT( canvas ), "canvas-width" );
00668         height = *(PLINT *) g_object_get_data( G_OBJECT( canvas ), "canvas-height" );
00669 
00670         // Size the window
00671         gtk_window_resize( GTK_WINDOW( dev->window ), width * ZOOM100 + 65,
00672             height * ZOOM100 + 75 );
00673     }
00674 
00675     // Display everything
00676     gtk_widget_show_all( dev->window );
00677 
00678 #ifdef DEBUG_GCW_1
00679     gcw_debug( "</gcw_install_canvas>\n" );
00680 #endif
00681 }
00682 
00683 
00684 //--------------------------------------------------------------------------
00685 // gcw_set_device_size()
00686 //
00687 // Sets the page size for this device.
00688 //
00689 // Width and height are both measured in device coordinate units.
00690 //
00691 // Note that coordinates in driver-space are measured in device units,
00692 // which correspond to the pixel size on a typical screen.  The coordinates
00693 // reported and received from the PLplot core, however, are in virtual
00694 // coordinates, which is just a scaled version of the device coordinates.
00695 // This strategy is used so that the calculations in the PLplot
00696 // core are performed at reasonably high resolution.
00697 //
00698 //--------------------------------------------------------------------------
00699 
00700 void gcw_set_device_size( PLINT width, PLINT height )
00701 {
00702     GcwPLdev* dev = plsc->dev;
00703     PLINT   w, h;
00704 
00705     // Set the number of virtual coordinate units per mm
00706     plP_setpxl( (PLFLT) VIRTUAL_PIXELS_PER_MM, (PLFLT) VIRTUAL_PIXELS_PER_MM );
00707 
00708     // Set up physical limits of plotting device, in virtual coord units
00709     w = (PLINT) ( width * VSCALE );
00710     h = (PLINT) ( height * VSCALE );
00711     plP_setphy( (PLINT) 0, w, (PLINT) 0, h );
00712 
00713     // Save the width and height for the device, in device units
00714     dev->width  = width;
00715     dev->height = height;
00716 }
00717 
00718 //--------------------------------------------------------------------------
00719 // gcw_set_canvas_size()
00720 //
00721 // Sets the canvas size.  If resizing is not allowed, this function
00722 // ensures that the canvas size matches the physical page size.
00723 //
00724 //--------------------------------------------------------------------------
00725 
00726 gint count = 0;
00727 
00728 void gcw_set_canvas_size( GnomeCanvas* canvas, PLINT width, PLINT height )
00729 {
00730     GcwPLdev    * dev = plsc->dev;
00731     PLINT       tmp;
00732 
00733     PLINT       *w, *h;
00734 
00735     GdkGC       *gc_new;
00736     GdkGCValues values;
00737 
00738     PLINT       strm;
00739 
00740     GdkPixmap   *background;
00741 
00742 #ifdef DEBUG_GCW_1
00743     gcw_debug( "<gcw_set_canvas_size>\n" );
00744 #endif
00745 
00746     // Set the device size, if resizing is allowed.
00747     if ( dev->allow_resize )
00748         gcw_set_device_size( width, height );
00749 
00750     width  = dev->width;
00751     height = dev->height;
00752     if ( plsc->portrait ) // Swap width and height of display
00753     {
00754         tmp    = width;
00755         width  = height;
00756         height = tmp;
00757     }
00758 
00759     // The width and height need to be enlarged by 1 pixel for the canvas
00760     width  += 1;
00761     height += 1;
00762 
00763     // Attach the width and height to the canvas
00764     if ( ( w = (PLINT *) malloc( sizeof ( gint ) ) ) == NULL )
00765         plwarn( "GCW driver <gcw_set_canvas_size>: Insufficient memory." );
00766     if ( ( h = (PLINT *) malloc( sizeof ( gint ) ) ) == NULL )
00767         plwarn( "GCW driver <gcw_set_canvas_size>: Insufficient memory." );
00768     *w = width;
00769     *h = height;
00770     g_object_set_data( G_OBJECT( canvas ), "canvas-width", (gpointer) w );
00771     g_object_set_data( G_OBJECT( canvas ), "canvas-height", (gpointer) h );
00772 
00773     // Size the canvas appropriately
00774     gtk_widget_set_size_request( GTK_WIDGET( canvas ), (gint) ( width ),
00775         (gint) ( height ) );
00776 
00777     // Position the canvas appropriately
00778     gnome_canvas_set_scroll_region( canvas, 0., (gdouble) ( -height ),
00779         (gdouble) ( width ), 1. );
00780 
00781     // Set up the background pixmap
00782     if ( dev->background == NULL || dev->allow_resize )
00783     {
00784         if ( GDK_IS_PIXMAP( dev->background ) )
00785             g_object_unref( dev->background );
00786 
00787         // Why does this next *useless* command speed up the animation demo?
00788         // If we unref the allocated pixmaps, the benefit goes away!!
00789 //     if(count<2) {
00790 //       gdk_pixmap_new(NULL,width,height,gdk_visual_get_best_depth());
00791 //       printf("Count %d\n",count);
00792 //       count++;
00793 //     }
00794 //     else { printf("Count %d\n",count); count ++; }
00795 
00796         dev->background = gdk_pixmap_new( NULL, width, height,
00797             gtk_widget_get_visual( GTK_WIDGET( canvas ) )->depth );
00798     }
00799 
00800     // Set up the drawing context for the background pixmap
00801     if ( dev->gc == NULL || dev->allow_resize )
00802     {
00803         // Maintain the old values for pen width, color, etc
00804         if ( GDK_IS_GC( dev->gc ) )
00805         {
00806             gdk_gc_get_values( dev->gc, &values );
00807             gdk_gc_unref( dev->gc );
00808             dev->gc = gdk_gc_new_with_values( dev->background, &values,
00809                 GDK_GC_FOREGROUND | GDK_GC_LINE_WIDTH |
00810                 GDK_GC_LINE_STYLE | GDK_GC_CAP_STYLE |
00811                 GDK_GC_JOIN_STYLE );
00812         }
00813         else
00814             dev->gc = gdk_gc_new( dev->background );
00815     }
00816 
00817     // Clear the background pixmap
00818     gcw_clear_background( dev );
00819 
00820     // Advance the page if we are allowing resizing.  This ensures that
00821     // the physical coordinate system is set up correctly.
00822     //
00823     if ( dev->allow_resize )
00824         pladv( 0 );
00825 
00826 #ifdef DEBUG_GCW_1
00827     gcw_debug( "</gcw_set_canvas_size>\n" );
00828 #endif
00829 }
00830 
00831 
00832 //--------------------------------------------------------------------------
00833 // gcw_set_canvas_zoom()
00834 //
00835 // Sets the zoom magnification on the canvas and resizes the widget
00836 // appropriately.
00837 //--------------------------------------------------------------------------
00838 
00839 void gcw_set_canvas_zoom( GnomeCanvas* canvas, PLFLT magnification )
00840 {
00841     gdouble curmag = 1., dum;
00842 
00843     PLINT   width, height;
00844 
00845 #ifdef DEBUG_GCW_1
00846     gcw_debug( "<gcw_set_canvas_zoom>\n" );
00847 #endif
00848 
00849     // Retrieve the device width and height
00850     width  = *(PLINT *) g_object_get_data( G_OBJECT( canvas ), "canvas-width" );
00851     height = *(PLINT *) g_object_get_data( G_OBJECT( canvas ), "canvas-height" );
00852 
00853     // Get the current magnification
00854     gnome_canvas_c2w( canvas, 1, 0, &curmag, &dum );
00855     curmag = 1. / curmag;
00856 
00857     // Apply the new magnification
00858     gnome_canvas_set_pixels_per_unit( canvas, magnification * curmag );
00859 
00860     // Size the canvas appropriately
00861     gtk_widget_set_size_request( GTK_WIDGET( canvas ),
00862         (gint) ( ( width ) * magnification * curmag ),
00863         (gint) ( ( height ) * magnification * curmag ) );
00864 
00865     // Position the canvas appropriately
00866     gnome_canvas_set_scroll_region( canvas, 0., (gdouble) ( -height ),
00867         (gdouble) ( width ), 1. );
00868 
00869 #ifdef DEBUG_GCW_1
00870     gcw_debug( "</gcw_set_canvas_zoom>\n" );
00871 #endif
00872 }
00873 
00874 
00875 //--------------------------------------------------------------------------
00876 // gcw_use_text()
00877 //
00878 // Used to turn text usage on and off for the current device.
00879 //--------------------------------------------------------------------------
00880 
00881 void gcw_use_text( PLINT use_text )
00882 {
00883     GcwPLdev* dev = plsc->dev;
00884 
00885 #ifdef DEBUG_GCW_1
00886     gcw_debug( "<gcw_use_text>\n" );
00887 #endif
00888 
00889 #ifdef PL_HAVE_FREETYPE
00890 
00891     if ( use_text )
00892         plsc->dev_text = 1;             // Allow text handling
00893     else
00894         plsc->dev_text = 0;             // Disallow text handling
00895 
00896 #endif
00897 
00898 #ifdef DEBUG_GCW_1
00899     gcw_debug( "</gcw_use_text>\n" );
00900 #endif
00901 }
00902 
00903 
00904 //--------------------------------------------------------------------------
00905 // gcw_use_pixmap()
00906 //
00907 // Used to turn pixmap usage on and off for the current device.
00908 // This is relevant for polygon fills (used during shading calls).
00909 //--------------------------------------------------------------------------
00910 
00911 void gcw_use_pixmap( PLINT use_pixmap )
00912 {
00913     GcwPLdev* dev = plsc->dev;
00914 
00915 #ifdef DEBUG_GCW_1
00916     gcw_debug( "<gcw_use_pixmap>\n" );
00917 #endif
00918 
00919     dev->use_pixmap = (gboolean) use_pixmap;
00920 
00921 #ifdef DEBUG_GCW_1
00922     gcw_debug( "</gcw_use_pixmap>\n" );
00923 #endif
00924 }
00925 
00926 
00927 //--------------------------------------------------------------------------
00928 // gcw_use_hrshsym()
00929 //
00930 // Used to turn hershey symbol usage on and off for the current device.
00931 //--------------------------------------------------------------------------
00932 
00933 void gcw_use_hrshsym( PLINT use_hrshsym )
00934 {
00935     GcwPLdev* dev = plsc->dev;
00936 
00937 #ifdef DEBUG_GCW_1
00938     gcw_debug( "<gcw_use_hrshsym>\n" );
00939 #endif
00940 
00941     plsc->dev_hrshsym = use_hrshsym;
00942 
00943 #ifdef DEBUG_GCW_1
00944     gcw_debug( "</gcw_use_hrshsym>\n" );
00945 #endif
00946 }
00947 
00948 
00949 //--------------------------------------------------------------------------
00950 // gcw_use_persistence
00951 //
00952 // Directs the GCW driver whether or not the subsequent drawing operations
00953 // should be persistent.
00954 //--------------------------------------------------------------------------
00955 
00956 void gcw_use_persistence( PLINT use_persistence )
00957 {
00958     GcwPLdev* dev = plsc->dev;
00959 
00960 #ifdef DEBUG_GCW_1
00961     gcw_debug( "<gcw_use_persistence>\n" );
00962 #endif
00963 
00964     dev->use_persistence = (gboolean) use_persistence;
00965 
00966 #ifdef DEBUG_GCW_1
00967     gcw_debug( "</gcw_use_persistence>\n" );
00968 #endif
00969 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines