~ubuntu-branches/ubuntu/intrepid/plplot/intrepid

« back to all changes in this revision

Viewing changes to bindings/gnome2/lib/gcw-lib.c

  • Committer: Bazaar Package Importer
  • Author(s): Rafael Laboissiere
  • Date: 2006-11-04 10:19:34 UTC
  • mfrom: (2.1.8 edgy)
  • Revision ID: james.westby@ubuntu.com-20061104101934-mlirvdg4gpwi6i5q
Tags: 5.6.1-10
* Orphaning the package
* debian/control: Changed the maintainer to the Debian QA Group

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* gcw-lib - Library routines for the Gnome Canvas Widget device driver.
 
2
 
 
3
  Copyright (C) 2005  Thomas J. Duck
 
4
  All rights reserved.
 
5
 
 
6
 
 
7
NOTICE
 
8
 
 
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.
 
13
 
 
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.
 
18
 
 
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
 
22
  USA 
 
23
 
 
24
DESCRIPTION
 
25
 
 
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.
 
28
 
 
29
*/
 
30
 
 
31
#include "gcw.h"
 
32
 
 
33
extern PLStream *pls[];
 
34
 
 
35
void gcw_debug(char* msg)
 
36
{
 
37
  fprintf(stderr,msg);
 
38
  fflush(stderr);
 
39
}
 
40
 
 
41
 
 
42
/*--------------------------------------------------------------------------*\
 
43
 * gcw_set_gdk_color()
 
44
 *
 
45
 * Sets the gdk foreground color for drawing in the current device 
 
46
 * according to the current drawing color.
 
47
 *
 
48
\*--------------------------------------------------------------------------*/
 
49
 
 
50
void gcw_set_gdk_color()
 
51
{
 
52
#ifdef DEBUG_GCW_1
 
53
  gcw_debug("<gcw_set_gdk_color>\n");
 
54
#endif
 
55
 
 
56
  GcwPLdev* dev = plsc->dev;
 
57
  GdkColor color;
 
58
 
 
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);
 
62
  
 
63
  if(!gdk_colormap_alloc_color(dev->colormap,&color,FALSE,TRUE))
 
64
    plwarn("GCW driver <set_gdk_color>: Could not allocate color.");
 
65
  
 
66
  gdk_gc_set_foreground(dev->gc,&color);
 
67
 
 
68
#ifdef DEBUG_GCW_1
 
69
  gcw_debug("</gcw_set_gdk_color>\n");
 
70
#endif
 
71
}
 
72
 
 
73
 
 
74
/*--------------------------------------------------------------------------*\
 
75
 * gcw_clear_background()
 
76
 *
 
77
 * Clears the background pixmap for the current gcw device with the 
 
78
 * background color.
 
79
 *
 
80
\*--------------------------------------------------------------------------*/
 
81
 
 
82
void gcw_clear_background()
 
83
{
 
84
  GcwPLdev* dev = plsc->dev;
 
85
 
 
86
  PLINT width,height;
 
87
 
 
88
#ifdef DEBUG_GCW_1
 
89
  gcw_debug("<clear_background>\n");
 
90
#endif
 
91
 
 
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");
 
95
 
 
96
  /* Allocate the background color*/
 
97
  gdk_colormap_alloc_color(dev->colormap,&(dev->bgcolor),FALSE,TRUE);
 
98
 
 
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);
 
104
 
 
105
  /* Note that our pixmap is currently clear */
 
106
  dev->pixmap_has_data = FALSE;
 
107
 
 
108
  /* Reset the current gdk drawing color */
 
109
  gcw_set_gdk_color();
 
110
 
 
111
#ifdef DEBUG_GCW_1
 
112
  gcw_debug("</clear_background>\n");
 
113
#endif
 
114
}
 
115
 
 
116
 
 
117
/*--------------------------------------------------------------------------*\
 
118
 * gcw_init_canvas()
 
119
 *
 
120
 * Initializes a canvas for use with this driver, and installs it into
 
121
 * the current gcw device.
 
122
 *
 
123
\*--------------------------------------------------------------------------*/
 
124
 
 
125
void gcw_init_canvas(GnomeCanvas* canvas)
 
126
{
 
127
  GcwPLdev* dev = plsc->dev;
 
128
 
 
129
#ifdef DEBUG_GCW_1
 
130
  gcw_debug("<gcw_init_canvas>\n");
 
131
#endif
 
132
 
 
133
  if(!GNOME_IS_CANVAS(canvas)) plexit("GCW driver: Canvas not found");
 
134
 
 
135
  /* Add the canvas to the device */
 
136
  dev->canvas=canvas;
 
137
 
 
138
  /* Get the colormap */
 
139
  dev->colormap = gtk_widget_get_colormap(GTK_WIDGET(dev->canvas));
 
140
 
 
141
  /* Size the canvas */
 
142
  gcw_set_canvas_size(canvas,dev->width,dev->height);
 
143
 
 
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(),
 
149
                              "x",0.,
 
150
                              "y",0.,
 
151
                              NULL))
 
152
    )) {
 
153
    plexit("GCW driver <gcw_init_canvas>: Canvas group cannot be created");
 
154
  }
 
155
 
 
156
  /* Set the clip to NULL */
 
157
  g_object_set(G_OBJECT(dev->group_persistent),"path",NULL,NULL);
 
158
 
 
159
#ifdef DEBUG_GCW1
 
160
  gcw_debug("</gcw_init_canvas>\n");
 
161
#endif
 
162
}
 
163
 
 
164
 
 
165
/*--------------------------------------------------------------------------*\
 
166
 * gcw_install_canvas()
 
167
 *
 
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
 
170
 * in the window.
 
171
 *
 
172
\*--------------------------------------------------------------------------*/
 
173
 
 
174
/*******************************
 
175
 * Main window event callbacks *
 
176
 *******************************/
 
177
 
 
178
/* Delete event callback */
 
179
gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data ) {
 
180
  return FALSE; /* FALSE follows with the destroy signal */
 
181
}
 
182
 
 
183
/* Destroy event calback */
 
184
void destroy(GtkWidget *widget, gpointer data) {
 
185
  gtk_main_quit ();
 
186
}
 
187
 
 
188
/******************
 
189
 * Zoom callbacks *
 
190
 ******************/
 
191
 
 
192
/* All-purpose zoom callback.  Referred to by specific zoom callbacks given
 
193
 *  below.
 
194
 */
 
195
void zoom(gpointer data, gint flag) {
 
196
 
 
197
  gint n;
 
198
 
 
199
  GnomeCanvas *canvas;
 
200
  GtkWidget *scrolled_window;
 
201
  GList *list;
 
202
 
 
203
  GcwPLdev* dev = data;
 
204
 
 
205
  gdouble curmag,dum;
 
206
 
 
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);
 
213
 
 
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 */
 
218
 
 
219
    /* Don't zoom smaller than the original size: this causes GDK pixmap
 
220
     * errors.
 
221
     */
 
222
    gnome_canvas_c2w(canvas,1,0,&curmag,&dum); 
 
223
    curmag = 1./curmag;
 
224
    if(curmag/ZOOMSTEP>1.) {
 
225
      gcw_set_canvas_zoom(canvas,1./ZOOMSTEP);
 
226
    }
 
227
    else {
 
228
      gcw_set_canvas_zoom(canvas,(PLFLT)(ZOOM100/curmag));
 
229
    }
 
230
  }
 
231
  else { /* Zoom 100 */
 
232
    /* Get current magnification */
 
233
    gnome_canvas_c2w(canvas,1,0,&curmag,&dum); 
 
234
    curmag = 1./curmag;
 
235
    gcw_set_canvas_zoom(canvas,(PLFLT)(ZOOM100/curmag));
 
236
  }
 
237
 
 
238
  /* Set the focus on the notebook */
 
239
  gtk_window_set_focus(GTK_WINDOW(dev->window),dev->notebook);
 
240
}
 
241
 
 
242
 
 
243
/* Callback when zoom in button is pressed */
 
244
void zoom_in(GtkWidget *widget, gpointer data ) {
 
245
  zoom(data,2);
 
246
}
 
247
 
 
248
/* Callback when zoom 100 button is pressed */
 
249
void zoom_100(GtkWidget *widget, gpointer data ) {
 
250
  zoom(data,1);
 
251
}
 
252
 
 
253
/* Callback when zoom out button is pressed */
 
254
void zoom_out(GtkWidget *widget, gpointer data ) {
 
255
  zoom(data,0);
 
256
}
 
257
 
 
258
/*****************************
 
259
 * File selection callbacks. *
 
260
 *****************************/
 
261
 
 
262
/* Callback to OK file selection.  Retrieves the selected filename and 
 
263
 * replays the plot buffer to it through the associated driver. 
 
264
 */
 
265
void file_ok_sel(GtkWidget *w, gpointer data)
 
266
{
 
267
  GcwPLdev* dev = data;
 
268
 
 
269
  GtkWidget *scrolled_window;
 
270
  GnomeCanvas *canvas;
 
271
 
 
272
  gchar *fname;
 
273
  FILE *f;
 
274
  guint n;
 
275
  char devname[10],str[100];
 
276
 
 
277
  PLINT cur_strm, new_strm;
 
278
  PLStream *plsr;
 
279
 
 
280
  GtkWidget *fs;
 
281
 
 
282
  gdouble curmag,dum;
 
283
 
 
284
  PLINT icol0,icol1,ncol0,ncol1;
 
285
  PLColor *cmap0,*cmap1;
 
286
 
 
287
  gboolean errflag = FALSE;
 
288
 
 
289
  struct stat buf;
 
290
 
 
291
  GtkDialog *dialog;
 
292
  GtkWidget *hbox,*message,*icon;
 
293
  gint result;
 
294
 
 
295
  guint context;
 
296
  
 
297
  /* Get the file name */
 
298
  if( (fname = 
 
299
       strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(dev->filew))))
 
300
      ==NULL )
 
301
    plabort("GCW driver <file_ok_sel>: Cannot obtain filename");
 
302
 
 
303
  /* Check to see if the file already exists, and respond appropriately */
 
304
  if(stat(fname,&buf)==0) {
 
305
 
 
306
    /* Confirm the user wants to overwrite the existing file */
 
307
 
 
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));
 
313
 
 
314
    message = gtk_label_new("");
 
315
    gtk_label_set_markup(GTK_LABEL(message),
 
316
                         "<span size=\"large\"><b>File exists.  "
 
317
                         "Overwrite?</b></span>");
 
318
 
 
319
    icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION,
 
320
                                    GTK_ICON_SIZE_DIALOG);
 
321
 
 
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);
 
326
 
 
327
    gtk_widget_show_all(GTK_WIDGET(dialog));
 
328
 
 
329
    result = gtk_dialog_run(dialog);
 
330
    gtk_widget_destroy(GTK_WIDGET(dialog));
 
331
    if(result==GTK_RESPONSE_REJECT) return;
 
332
  }
 
333
 
 
334
  /* Hide the file selection widget */
 
335
  gtk_widget_hide(dev->filew);
 
336
 
 
337
  /* Put the focus back on the notebook */
 
338
  gtk_window_set_focus(GTK_WINDOW(dev->window),dev->notebook);
 
339
 
 
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");
 
343
  fclose(f);
 
344
  remove(fname); /* Otherwise, we may leave behind a zero-length file */
 
345
 
 
346
  /* Get the file extension and make sure we recognize it.  Allow names
 
347
   * of display devices as well.
 
348
   *
 
349
   * Note that we can't replot to xwin or tk devices, which can't open a
 
350
   * display for some reason.
 
351
   *
 
352
   */
 
353
  n = strlen(fname);
 
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");
 
363
  else {
 
364
    if(dev->statusbar!=NULL) {
 
365
      context=gtk_statusbar_get_context_id(GTK_STATUSBAR(dev->statusbar),
 
366
                                           "PLplot");
 
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 "
 
370
                         "gif."
 
371
                         );
 
372
      return;
 
373
    }
 
374
    else plabort("GCW driver <file_ok_sel>: File type not recognized");
 
375
  }
 
376
 
 
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),
 
382
                                             "PLplot");
 
383
 
 
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."
 
387
                           );
 
388
      }
 
389
      else
 
390
        plwarn("GCW driver: Use '-drvopt hrshsym' if symbols are missing in "
 
391
               "saved PostScript files.");
 
392
  }
 
393
  if( strcmp(devname,"xwin")==0 || strcmp(devname,"tk")==0 ) {
 
394
    if(plsc->dev_text != 0)
 
395
      plwarn("GCW driver: Use '-drvopt text=0'");
 
396
  }
 
397
 
 
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);
 
404
 
 
405
  /* Hack: Swap in the saved tempfile and colormaps */
 
406
  f = plsc->plbufFile;
 
407
  plsc->plbufFile = g_object_get_data(G_OBJECT(canvas),"plotbuf");
 
408
  if(plsc->plbufFile == NULL) errflag=TRUE;
 
409
 
 
410
  icol0=plsc->icol0;
 
411
  if( g_object_get_data(G_OBJECT(canvas),"icol0") != NULL )
 
412
    plsc->icol0 = *(PLINT*)g_object_get_data(G_OBJECT(canvas),"icol0");
 
413
  else errflag=TRUE;
 
414
 
 
415
  ncol0=plsc->ncol0;
 
416
  if( g_object_get_data(G_OBJECT(canvas),"ncol0") != NULL )
 
417
    plsc->ncol0 = *(PLINT*)g_object_get_data(G_OBJECT(canvas),"ncol0");
 
418
  else errflag=TRUE;
 
419
    
 
420
  cmap0=plsc->cmap0;
 
421
  if( g_object_get_data(G_OBJECT(canvas),"cmap0") )
 
422
    plsc->cmap0 = (PLColor*)g_object_get_data(G_OBJECT(canvas),"cmap0");
 
423
  else errflag=TRUE;
 
424
 
 
425
  icol1=plsc->icol1;
 
426
  if( g_object_get_data(G_OBJECT(canvas),"icol1") != NULL )
 
427
    plsc->icol1 = *(PLINT*)g_object_get_data(G_OBJECT(canvas),"icol1");
 
428
  else errflag=TRUE;
 
429
 
 
430
  ncol1=plsc->ncol1;
 
431
  if( g_object_get_data(G_OBJECT(canvas),"ncol1") != NULL )
 
432
    plsc->ncol1 = *(PLINT*)g_object_get_data(G_OBJECT(canvas),"ncol1");
 
433
  else errflag=TRUE;
 
434
 
 
435
  cmap1=plsc->cmap1;
 
436
  if( g_object_get_data(G_OBJECT(canvas),"cmap1") != NULL )
 
437
    plsc->cmap1 = (PLColor*)g_object_get_data(G_OBJECT(canvas),"cmap1");
 
438
  else errflag=TRUE;
 
439
 
 
440
  if(!errflag) {
 
441
 
 
442
    plsetopt ("drvopt","text"); /* Blank out the drvopts (not needed here) */
 
443
 
 
444
    /* Get the current stream and make a new one */
 
445
    plgstrm(&cur_strm);
 
446
    plsr = plsc; /* Save a pointer to the current stream */
 
447
 
 
448
    plmkstrm(&new_strm);
 
449
    plsfnam(fname); /* Set the file name */
 
450
    plsdev(devname); /* Set the device */
 
451
 
 
452
    /* Copy the current stream to the new stream. */
 
453
    plcpstrm(cur_strm, 0); 
 
454
 
 
455
    plreplot();            /* do the save by replaying the plot buffer */
 
456
 
 
457
    plend1();              /* finish the device */
 
458
 
 
459
    plsstrm(cur_strm);     /* return to previous stream */
 
460
  }
 
461
  else plwarn("GCW driver <file_ok_sel>: Cannot set up output stream.");
 
462
 
 
463
 
 
464
  /* Restore */
 
465
 
 
466
  plsc->plbufFile = f;
 
467
  plsc->icol0 = icol0;
 
468
  plsc->ncol0 = ncol0;
 
469
  plsc->cmap0 = cmap0;
 
470
  plsc->icol1 = icol1;
 
471
  plsc->ncol1 = ncol1;
 
472
  plsc->cmap1 = cmap1;
 
473
}
 
474
 
 
475
/* Callback to cancel file selection */
 
476
void file_cancel_sel(GtkWidget *w, gpointer data)
 
477
{
 
478
  GcwPLdev* dev = data;
 
479
  
 
480
  /* Hide the file selection widget */
 
481
  gtk_widget_hide(dev->filew);
 
482
 
 
483
  /* Put the focus back on the notebook */
 
484
  gtk_window_set_focus(GTK_WINDOW(dev->window),dev->notebook);
 
485
}
 
486
 
 
487
/* Callback to create file selection dialog */
 
488
void filesel(GtkWidget *widget, gpointer data ) {
 
489
 
 
490
  GtkWidget *scrolled_window;
 
491
  GnomeCanvas *canvas;
 
492
 
 
493
  GcwPLdev* dev = data;
 
494
 
 
495
  guint n;
 
496
 
 
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);
 
503
 
 
504
  /* Create a new file dialog if it doesn't already exist */
 
505
  if(dev->filew == NULL) {
 
506
 
 
507
    /* Create a new file selection widget */
 
508
    dev->filew = gtk_file_selection_new ("File selection");
 
509
    
 
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);
 
513
    
 
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);
 
517
    
 
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), 
 
521
                                    "plot.psc");
 
522
  }
 
523
    
 
524
  gtk_widget_show(dev->filew);
 
525
}
 
526
 
 
527
/**************************
 
528
 * Key release callbacks. *
 
529
 **************************/
 
530
 
 
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);
 
536
}
 
537
 
 
538
/**********************
 
539
 * gcw_install_canvas *
 
540
 **********************/
 
541
 
 
542
void gcw_install_canvas(GnomeCanvas *canvas)
 
543
{
 
544
  GcwPLdev* dev = plsc->dev;
 
545
  GtkWidget *vbox,*hbox,*button,*image,*scrolled_window;
 
546
 
 
547
  gboolean flag = FALSE;
 
548
 
 
549
  PLINT width,height;
 
550
 
 
551
#ifdef DEBUG_GCW_1
 
552
  gcw_debug("<gcw_install_canvas>\n");
 
553
#endif
 
554
 
 
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");
 
559
  }
 
560
 
 
561
  /* Initialize canvas */
 
562
  gcw_init_canvas(canvas);
 
563
 
 
564
  if(dev->window==NULL) { /* Create a new window and install a notebook */
 
565
 
 
566
    flag = TRUE;
 
567
    
 
568
    /* Create a new window */
 
569
    dev->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
570
    gtk_window_set_title(GTK_WINDOW(dev->window),"PLplot");
 
571
 
 
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);
 
576
 
 
577
 
 
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);
 
581
 
 
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);
 
585
 
 
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);
 
589
 
 
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);
 
594
 
 
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));
 
601
 
 
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);
 
605
 
 
606
    /* Add buttons to the vbox */
 
607
 
 
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);
 
618
 
 
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);
 
627
 
 
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);
 
638
 
 
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);
 
648
    }
 
649
  } /* if(dev->window==NULL) */
 
650
 
 
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), 
 
656
                                        GTK_WIDGET(canvas));
 
657
 
 
658
  /* Install the scrolled window in the notebook */
 
659
  gtk_notebook_append_page(GTK_NOTEBOOK(dev->notebook),scrolled_window, NULL);
 
660
 
 
661
  if(flag) {
 
662
 
 
663
    /* Set the focus on the notebook */
 
664
    gtk_window_set_focus(GTK_WINDOW(dev->window),dev->notebook);
 
665
 
 
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");
 
669
 
 
670
    /* Size the window */
 
671
    gtk_window_resize(GTK_WINDOW(dev->window),width*ZOOM100+65,
 
672
                      height*ZOOM100+75);
 
673
  }
 
674
 
 
675
  /* Display everything */
 
676
  gtk_widget_show_all(dev->window);
 
677
 
 
678
#ifdef DEBUG_GCW_1
 
679
  gcw_debug("</gcw_install_canvas>\n");
 
680
#endif
 
681
}
 
682
 
 
683
 
 
684
/*--------------------------------------------------------------------------*\
 
685
 * gcw_set_device_size()
 
686
 *
 
687
 * Sets the page size for this device.
 
688
 *
 
689
 * Width and height are both measured in device coordinate units.
 
690
 *
 
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.
 
697
 *
 
698
\*--------------------------------------------------------------------------*/
 
699
 
 
700
void gcw_set_device_size(PLINT width,PLINT height) {
 
701
  GcwPLdev* dev = plsc->dev;
 
702
  PLINT w, h;
 
703
 
 
704
  /* Set the number of virtual coordinate units per mm */
 
705
  plP_setpxl((PLFLT)VIRTUAL_PIXELS_PER_MM,(PLFLT)VIRTUAL_PIXELS_PER_MM);
 
706
  
 
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);
 
711
  
 
712
  /* Save the width and height for the device, in device units */
 
713
  dev->width = width;
 
714
  dev->height = height;
 
715
}
 
716
 
 
717
/*--------------------------------------------------------------------------*\
 
718
 * gcw_set_canvas_size()
 
719
 *
 
720
 * Sets the canvas size.  If resizing is not allowed, this function
 
721
 * ensures that the canvas size matches the physical page size.
 
722
 *
 
723
\*--------------------------------------------------------------------------*/
 
724
 
 
725
gint count = 0;
 
726
 
 
727
void gcw_set_canvas_size(GnomeCanvas* canvas,PLINT width,PLINT height)
 
728
{
 
729
  GcwPLdev* dev = plsc->dev;
 
730
  PLINT tmp;
 
731
 
 
732
  PLINT *w,*h;
 
733
 
 
734
  GdkGC *gc_new;
 
735
  GdkGCValues values;
 
736
 
 
737
  PLINT strm;
 
738
 
 
739
  GdkPixmap *background;
 
740
 
 
741
#ifdef DEBUG_GCW_1
 
742
  gcw_debug("<gcw_set_canvas_size>\n");
 
743
#endif
 
744
 
 
745
  /* Set the device size, if resizing is allowed. */
 
746
  if(dev->allow_resize) gcw_set_device_size(width,height);
 
747
 
 
748
  width = dev->width;
 
749
  height = dev->height;
 
750
  if(plsc->portrait) { /* Swap width and height of display */
 
751
    tmp=width;
 
752
    width=height;
 
753
    height=tmp;
 
754
  }
 
755
 
 
756
  /* The width and height need to be enlarged by 1 pixel for the canvas */
 
757
  width += 1;
 
758
  height += 1;
 
759
 
 
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.");
 
765
  *w = width;
 
766
  *h = height;
 
767
  g_object_set_data(G_OBJECT(canvas),"canvas-width",(gpointer)w);
 
768
  g_object_set_data(G_OBJECT(canvas),"canvas-height",(gpointer)h);
 
769
 
 
770
  /* Size the canvas appropriately */
 
771
  gtk_widget_set_size_request(GTK_WIDGET(canvas),(gint)(width),
 
772
                              (gint)(height));
 
773
 
 
774
  /* Position the canvas appropriately */
 
775
  gnome_canvas_set_scroll_region(canvas,0.,(gdouble)(-height),
 
776
                                 (gdouble)(width),1.);
 
777
 
 
778
  /* Set up the background pixmap */
 
779
  if(dev->background==NULL || dev->allow_resize) { 
 
780
 
 
781
    if(GDK_IS_PIXMAP(dev->background)) g_object_unref(dev->background);
 
782
 
 
783
    /* Why does this next *useless* command speed up the animation demo?
 
784
     * If we unref the allocated pixmaps, the benefit goes away!! */
 
785
/*     if(count<2) { */
 
786
/*       gdk_pixmap_new(NULL,width,height,gdk_visual_get_best_depth()); */
 
787
/*       printf("Count %d\n",count); */
 
788
/*       count++; */
 
789
/*     } */
 
790
/*     else { printf("Count %d\n",count); count ++; } */
 
791
 
 
792
    dev->background = gdk_pixmap_new(NULL,width,height,
 
793
                            gtk_widget_get_visual(GTK_WIDGET(canvas))->depth);
 
794
  }
 
795
 
 
796
  /* Set up the drawing context for the background pixmap */
 
797
  if(dev->gc==NULL || dev->allow_resize) {
 
798
 
 
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 |
 
806
                                       GDK_GC_JOIN_STYLE);
 
807
    }
 
808
    else dev->gc = gdk_gc_new(dev->background);
 
809
  }
 
810
 
 
811
  /* Clear the background pixmap */
 
812
  gcw_clear_background(dev);
 
813
 
 
814
  /* Advance the page if we are allowing resizing.  This ensures that
 
815
   * the physical coordinate system is set up correctly.
 
816
   */
 
817
  if(dev->allow_resize) pladv(0);
 
818
 
 
819
#ifdef DEBUG_GCW_1
 
820
  gcw_debug("</gcw_set_canvas_size>\n");
 
821
#endif
 
822
}
 
823
 
 
824
 
 
825
/*--------------------------------------------------------------------------*\
 
826
 * gcw_set_canvas_zoom()
 
827
 *
 
828
 * Sets the zoom magnification on the canvas and resizes the widget
 
829
 * appropriately.
 
830
\*--------------------------------------------------------------------------*/
 
831
 
 
832
void gcw_set_canvas_zoom(GnomeCanvas* canvas,PLFLT magnification)
 
833
{
 
834
  gdouble curmag=1.,dum;
 
835
 
 
836
  PLINT width,height;
 
837
 
 
838
#ifdef DEBUG_GCW_1
 
839
  gcw_debug("<gcw_set_canvas_zoom>\n");
 
840
#endif
 
841
 
 
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");
 
845
 
 
846
  /* Get the current magnification */
 
847
  gnome_canvas_c2w(canvas,1,0,&curmag,&dum);
 
848
  curmag = 1./curmag;
 
849
 
 
850
  /* Apply the new magnification */
 
851
  gnome_canvas_set_pixels_per_unit(canvas,magnification*curmag);
 
852
 
 
853
  /* Size the canvas appropriately */
 
854
  gtk_widget_set_size_request(GTK_WIDGET(canvas),
 
855
                              (gint)((width)*magnification*curmag),
 
856
                              (gint)((height)*magnification*curmag));
 
857
 
 
858
  /* Position the canvas appropriately */
 
859
  gnome_canvas_set_scroll_region(canvas,0.,(gdouble)(-height),
 
860
                                 (gdouble)(width),1.);
 
861
 
 
862
#ifdef DEBUG_GCW_1
 
863
  gcw_debug("</gcw_set_canvas_zoom>\n");
 
864
#endif
 
865
}
 
866
 
 
867
 
 
868
/*--------------------------------------------------------------------------*\
 
869
 * gcw_use_text()
 
870
 *
 
871
 * Used to turn text usage on and off for the current device.
 
872
\*--------------------------------------------------------------------------*/
 
873
 
 
874
void gcw_use_text(PLINT use_text)
 
875
{
 
876
  GcwPLdev* dev = plsc->dev;
 
877
 
 
878
#ifdef DEBUG_GCW_1
 
879
  gcw_debug("<gcw_use_text>\n");
 
880
#endif
 
881
 
 
882
#ifdef HAVE_FREETYPE
 
883
 
 
884
  if(use_text) plsc->dev_text = 1; /* Allow text handling */
 
885
  else plsc->dev_text = 0; /* Disallow text handling */
 
886
 
 
887
#endif
 
888
 
 
889
#ifdef DEBUG_GCW_1
 
890
  gcw_debug("</gcw_use_text>\n");
 
891
#endif
 
892
}
 
893
 
 
894
 
 
895
/*--------------------------------------------------------------------------*\
 
896
 * gcw_use_pixmap()
 
897
 *
 
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
\*--------------------------------------------------------------------------*/
 
901
 
 
902
void gcw_use_pixmap(PLINT use_pixmap)
 
903
{
 
904
  GcwPLdev* dev = plsc->dev;
 
905
 
 
906
#ifdef DEBUG_GCW_1
 
907
  gcw_debug("<gcw_use_pixmap>\n");
 
908
#endif
 
909
 
 
910
  dev->use_pixmap = (gboolean)use_pixmap;
 
911
 
 
912
#ifdef DEBUG_GCW_1
 
913
  gcw_debug("</gcw_use_pixmap>\n");
 
914
#endif
 
915
}
 
916
 
 
917
 
 
918
/*--------------------------------------------------------------------------*\
 
919
 * gcw_use_hrshsym()
 
920
 *
 
921
 * Used to turn hershey symbol usage on and off for the current device.
 
922
\*--------------------------------------------------------------------------*/
 
923
 
 
924
void gcw_use_hrshsym(PLINT use_hrshsym)
 
925
{
 
926
  GcwPLdev* dev = plsc->dev;
 
927
 
 
928
#ifdef DEBUG_GCW_1
 
929
  gcw_debug("<gcw_use_hrshsym>\n");
 
930
#endif
 
931
 
 
932
  plsc->dev_hrshsym = use_hrshsym;
 
933
 
 
934
#ifdef DEBUG_GCW_1
 
935
  gcw_debug("</gcw_use_hrshsym>\n");
 
936
#endif
 
937
}
 
938
 
 
939
 
 
940
/*--------------------------------------------------------------------------*\
 
941
 * gcw_use_persistence
 
942
 *
 
943
 * Directs the GCW driver whether or not the subsequent drawing operations
 
944
 * should be persistent.
 
945
\*--------------------------------------------------------------------------*/
 
946
 
 
947
void gcw_use_persistence(PLINT use_persistence)
 
948
{
 
949
  GcwPLdev* dev = plsc->dev;
 
950
 
 
951
#ifdef DEBUG_GCW_1
 
952
  gcw_debug("<gcw_use_persistence>\n");
 
953
#endif
 
954
 
 
955
  dev->use_persistence = (gboolean)use_persistence;
 
956
 
 
957
#ifdef DEBUG_GCW_1
 
958
  gcw_debug("</gcw_use_persistence>\n");
 
959
#endif
 
960
}