The R Project SVN R

Rev

Rev 13974 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 13974 Rev 16018
Line 17... Line 17...
17
 *  along with this program; if not, write to the Free Software
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
19
 */
20
 
20
 
21
#include <gnome.h>
21
#include <gnome.h>
-
 
22
#include <math.h>
22
 
23
 
23
#include "Defn.h"
24
#include "Defn.h"
24
#include "Graphics.h"
25
#include "Graphics.h"
25
#include "Rdevices.h"
26
#include "Rdevices.h"
26
#include "devGNOME.h"
27
#include "devGNOME.h"
27
#include "terminal.h"
28
#include "terminal.h"
-
 
29
#include "device-support.h"
28
 
30
 
29
#define CURSOR		GDK_CROSSHAIR		/* Default cursor */
31
#define CURSOR		GDK_CROSSHAIR		/* Default cursor */
30
#define MM_PER_INCH	25.4			/* mm -> inch conversion */
32
#define MM_PER_INCH	25.4			/* mm -> inch conversion */
31
 
33
 
32
typedef struct {
34
typedef struct {
33
    /* R Graphics Parameters */
35
  /* R Graphics Parameters */
34
    /* local device copy so that we can detect */
36
  /* local device copy so that we can detect */
35
    /* when parameter changes */
37
  /* when parameter changes */
36
 
38
 
37
    double cex;				/* Character expansion */
39
  double cex;				/* Character expansion */
38
    double srt;				/* String rotation */
40
  double srt;				/* String rotation */
39
 
41
 
-
 
42
  int fontface;                         /* Typeface */
40
    gint bg;				/* Background */
43
  int fontsize;                         /* Size in points */
41
 
44
 
42
    int fontface;			/* Typeface */
-
 
43
    int fontsize;			/* Size in points */
45
  gint lty, lwd;                        /* line params */
44
 
46
 
45
    /* GNOME Driver Specific */
47
  /* GNOME Driver Specific */
46
 
48
 
47
    int windowWidth;			/* Window width (pixels) */
-
 
48
    int windowHeight;			/* Window height (pixels) */
-
 
49
    Rboolean resize;			/* Window resized */
-
 
50
    GtkWidget *window;			/* Graphics Window */
-
 
51
    GtkWidget *canvas;
49
  GdkGC *wgc;
52
 
50
 
-
 
51
  int windowWidth;			/* Window width (pixels) */
-
 
52
  int windowHeight;			/* Window height (pixels) */
53
    GdkColor *gcol_bg;
53
  Rboolean resize;			/* Window resized */
-
 
54
  GtkWidget *window;			/* Graphics Window */
54
 
55
 
-
 
56
  GtkWidget *canvas;                    /* Gnome canvas */
-
 
57
  GnomeCanvasGroup *group;              /* Canvas group for plotting */
55
    GdkCursor *gcursor;
58
  GnomeCanvasItem *plotarea;            /* Plotting area */
56
 
59
 
-
 
60
  GdkCursor *gcursor;
-
 
61
 
57
    Rboolean usefixed;/* not yet used (??) */
62
  Rboolean usefixed;                    /* not yet used (??) */
58
    GdkFont *fixedfont;
63
  GdkFont *fixedfont;
59
    GdkFont *font;
64
  GdkFont *font;
60
 
65
 
61
} gnomeDesc;
66
} gnomeDesc;
62
 
67
 
63
/* routines from here */
68
/* routines from here */
64
Rboolean GnomeDeviceDriver(DevDesc *dd, char *display, 
69
Rboolean GnomeDeviceDriver(DevDesc *dd, char *display, 
Line 68... Line 73...
68
static void   GNOME_Activate(DevDesc *);
73
static void   GNOME_Activate(DevDesc *);
69
static void   GNOME_Circle(double, double, int, double, int, int, DevDesc*);
74
static void   GNOME_Circle(double, double, int, double, int, int, DevDesc*);
70
static void   GNOME_Clip(double, double, double, double, DevDesc*);
75
static void   GNOME_Clip(double, double, double, double, DevDesc*);
71
static void   GNOME_Close(DevDesc*);
76
static void   GNOME_Close(DevDesc*);
72
static void   GNOME_Deactivate(DevDesc *);
77
static void   GNOME_Deactivate(DevDesc *);
73
static void   GNOME_Hold(DevDesc*);
78
static void   GNOME_old(DevDesc*);
74
static void   GNOME_Line(double, double, double, double, int, DevDesc*);
79
static void   GNOME_Line(double, double, double, double, int, DevDesc*);
75
static Rboolean GNOME_Locator(double*, double*, DevDesc*);
80
static Rboolean GNOME_Locator(double*, double*, DevDesc*);
76
static void   GNOME_Mode(int);
81
static void   GNOME_Mode(int);
77
static void   GNOME_NewPage(DevDesc*);
82
static void   GNOME_NewPage(DevDesc*);
78
static Rboolean GNOME_Open(DevDesc*, gnomeDesc*, char*, double, double);
83
static Rboolean GNOME_Open(DevDesc*, gnomeDesc*, char*, double, double);
Line 102... Line 107...
102
    return ((double)heightMM / (double)height) / MM_PER_INCH;
107
    return ((double)heightMM / (double)height) / MM_PER_INCH;
103
}
108
}
104
 
109
 
105
/* font stuff */
110
/* font stuff */
106
 
111
 
-
 
112
static char *fontname_R6 = "-adobe-helvetica-%s-%s-*-*-*-%d-*-*-*-*-*-*";
-
 
113
static char *symbolname = "-adobe-symbol-*-*-*-*-*-%d-*-*-*-*-*-*";
-
 
114
static char *fixedname = "fixed";
-
 
115
 
-
 
116
static char *slant[] = {"r", "o"};
-
 
117
static char *weight[] = {"medium", "bold"};
107
 
118
 
-
 
119
static char *fontname = NULL;
-
 
120
static GHashTable *font_htab = NULL;
108
 
121
 
109
/* set the r, g, b, and pixel values of gcol to color */
-
 
110
static void SetColor(GdkColor *gcol, int color)
122
static GdkFont *RGTKLoadFont(char *font)
111
{
123
{
-
 
124
  GdkFont *tmp_font;
-
 
125
  
-
 
126
  g_return_val_if_fail(font_htab, NULL);
-
 
127
  tmp_font = g_hash_table_lookup(font_htab, (gpointer) font);
-
 
128
 
-
 
129
  if(!tmp_font)
-
 
130
    {
-
 
131
      if((tmp_font = gdk_font_load(font)))
-
 
132
	{
-
 
133
	  g_hash_table_insert(font_htab, (gpointer) g_strdup(font),
112
    int red, green, blue;
134
			      (gpointer) tmp_font);
-
 
135
	}
-
 
136
    }
113
 
137
 
114
    red = R_RED(color);
138
  return tmp_font;
115
    green = R_GREEN(color);
-
 
116
    blue = R_BLUE(color);
-
 
117
    gcol->red = red * 257;
-
 
118
    gcol->green = green * 257;
-
 
119
    gcol->blue = blue * 257;
-
 
120
    gcol->pixel = gdk_rgb_xpixel_from_rgb((red << 16)|(green << 8)|(blue));
-
 
121
}
139
}
122
 
140
 
123
/* line type */
-
 
124
static void SetLineType(GdkBitmap *stipple, int newlty, int newlwd)
141
static gboolean SetBaseFont (gnomeDesc *gd)
125
{
142
{
126
  /*  static gchar dashlist[8];
143
  gd->fontface = 1;
127
  gint i, j;
144
  gd->fontsize = 12;
-
 
145
  gd->usefixed = 0;
-
 
146
  
-
 
147
  if (font_htab == NULL)
-
 
148
    {
-
 
149
      font_htab = g_hash_table_new(g_str_hash, g_str_equal);
-
 
150
    }
128
 
151
 
-
 
152
  fontname = g_strdup_printf(fontname_R6, weight[0], slant[0], 
129
  if(newlwd < 1)
153
			     gd->fontsize * 10);
-
 
154
  gd->font = RGTKLoadFont(fontname);
130
    newlwd = 1;
155
  g_free(fontname);
131
 
156
 
132
  for(i = 0; (i < 8) && (newlty != 0); i++) {
157
  if(gd->font)
133
    j = newlty & 15;
158
    return TRUE;
134
 
159
 
135
    if(j == 0)
160
  gd->usefixed = 1;
136
      j = 1;
161
  gd->font = RGTKLoadFont(fixedname);
137
 
162
 
-
 
163
  if(gd->font)
138
    j = j * newlwd;
164
    return TRUE;
-
 
165
  
-
 
166
  return FALSE;
-
 
167
}
139
 
168
 
140
    if(j > 255)
169
#define SMALLEST 8
141
      j = 255;
170
#define LARGEST 24
142
 
171
 
-
 
172
static void SetFont(DevDesc *dd, gint face, gint size)
-
 
173
{
-
 
174
  GdkFont *tmp_font;
-
 
175
  gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
-
 
176
 
-
 
177
  if (face < 1 || face > 5)
143
    dashlist[i] = j;
178
    face = 1;
-
 
179
  
144
    newlty = newlty >> 4;
180
  size = 2 * size / 2;
-
 
181
  if (size < SMALLEST)
-
 
182
    size = SMALLEST;
-
 
183
  else if (size > LARGEST)
-
 
184
    size = LARGEST;
145
  }
185
  
-
 
186
  if (!gd->usefixed)
146
  */
187
    {
147
  /*  set dashes */
188
      if (face == 5)
-
 
189
	fontname = g_strdup_printf(symbolname, 10 * size);
-
 
190
      else
-
 
191
	fontname = g_strdup_printf(fontname_R6,
-
 
192
				   weight[(face-1)%2],
-
 
193
				   slant[((face-1)/2)%2],
-
 
194
				   10 * size);
-
 
195
      
148
  /*  gdk_gc_set_dashes(gc, 0, dashlist, i);*/
196
      tmp_font = RGTKLoadFont(fontname);
-
 
197
      g_free(fontname);
-
 
198
 
-
 
199
      if (tmp_font)
-
 
200
	{
-
 
201
	  gd->font = tmp_font;
-
 
202
	  gd->fontface = face;
-
 
203
	  gd->fontsize = size;
-
 
204
	}
-
 
205
      else
-
 
206
	{
-
 
207
	  error("gdk font at size %d could not be loaded", size);
-
 
208
	}
-
 
209
    }
149
}
210
}
150
 
211
 
-
 
212
/* Get GNOME color specification from R color  */
-
 
213
static guint32 Color_RGBA(int color)
-
 
214
{
-
 
215
  int red, green, blue, alpha;
-
 
216
  
151
/* signal functions */
217
  red = R_RED(color);
-
 
218
  green = R_GREEN(color);
-
 
219
  blue = R_BLUE(color);
-
 
220
  alpha = 255 - R_ALPHA(color);
-
 
221
 
-
 
222
  return GNOME_CANVAS_COLOR_A(red, green, blue, alpha);
-
 
223
}
152
 
224
 
-
 
225
/* line type */
-
 
226
/* fixme: not currently used */
153
static gint configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data) 
227
static void SetLineType(DevDesc *dd, int newlty, int newlwd)
154
{
228
{
-
 
229
  static gchar dashlist[8];
-
 
230
  gint i, j;
-
 
231
  gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
-
 
232
  
-
 
233
  if (newlty != gd->lty || newlwd != gd->lwd)
-
 
234
    {
-
 
235
      if (newlty == 0)
-
 
236
	{
-
 
237
	  if(newlwd <= 1)
155
    DevDesc *dd;
238
	    newlwd = 0;
-
 
239
	  
-
 
240
	  gdk_gc_set_line_attributes(gd->wgc, newlwd,
-
 
241
				     GDK_LINE_SOLID,
-
 
242
				     GDK_CAP_BUTT,
-
 
243
				     GDK_JOIN_ROUND);
-
 
244
	}
-
 
245
      else
-
 
246
	{
-
 
247
	  if (newlwd < 1)
156
    gnomeDesc *gtkd;
248
	    newlwd = 1;
-
 
249
 
-
 
250
	  for(i = 0; (i < 8) && (newlty != 0); i++) {
-
 
251
	    j = newlty & 15;
-
 
252
	    if(j == 0) j = 1;
-
 
253
	    j = j * newlwd;
-
 
254
	    if(j > 255) j = 255;
-
 
255
	    dashlist[i] = j;
-
 
256
	    newlty = newlty >> 4;
-
 
257
	  }
-
 
258
 
-
 
259
	  /*  set dashes */
-
 
260
	  gdk_gc_set_dashes(gd->wgc, 0, dashlist, i);
-
 
261
	  gdk_gc_set_line_attributes(gd->wgc, newlwd,
-
 
262
				     GDK_LINE_ON_OFF_DASH,
-
 
263
				     GDK_CAP_BUTT,
-
 
264
				     GDK_JOIN_ROUND);
-
 
265
	}
-
 
266
    }
-
 
267
}
157
 
268
 
158
    /*  g_print("configure\n"); */
269
/* signal functions */
159
 
270
 
-
 
271
static gint configure_event(GtkWidget *widget, GdkEventConfigure *event,
-
 
272
			    gpointer data) 
-
 
273
{
160
    dd = (DevDesc *) data;
274
  DevDesc *dd;
161
    g_return_val_if_fail(dd != NULL, FALSE);
275
  gnomeDesc *gd;
162
 
276
 
163
    gtkd = (gnomeDesc *) dd->deviceSpecific;
-
 
164
    g_return_val_if_fail(gtkd != NULL, FALSE);
-
 
165
    g_return_val_if_fail(gtkd->canvas != NULL, FALSE);
-
 
166
    g_return_val_if_fail(GNOME_IS_CANVAS(gtkd->canvas), FALSE);
-
 
167
 
-
 
168
    /* resize */
277
  /*  g_print("configure\n"); */
169
    if((gtkd->windowWidth != event->width) || (gtkd->windowHeight != event->height)) {
-
 
170
	gtkd->windowWidth = event->width;
-
 
171
	gtkd->windowHeight = event->height;
-
 
172
 
278
 
-
 
279
  dd = (DevDesc *) data;
-
 
280
  g_return_val_if_fail(dd != NULL, FALSE);
-
 
281
 
-
 
282
  gd = (gnomeDesc *) dd->deviceSpecific;
-
 
283
  g_return_val_if_fail(gd != NULL, FALSE);
-
 
284
  g_return_val_if_fail(gd->canvas != NULL, FALSE);
-
 
285
  g_return_val_if_fail(GNOME_IS_CANVAS(gd->canvas), FALSE);
-
 
286
 
-
 
287
  /* resize */
-
 
288
  if((gd->windowWidth != event->width) || (gd->windowHeight != event->height))
-
 
289
    {
-
 
290
      gd->windowWidth = event->width;
-
 
291
      gd->windowHeight = event->height;
-
 
292
      
173
	gtkd->resize = TRUE;
293
      gd->resize = TRUE;
174
    }
294
    }
175
 
295
 
176
    return FALSE;
296
  return FALSE;
177
}
297
}
178
 
298
 
179
static gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) 
299
static gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) 
180
{
300
{
181
    DevDesc *dd;
301
    DevDesc *dd;
Line 186... Line 306...
186
    KillDevice(dd);
306
    KillDevice(dd);
187
 
307
 
188
    return TRUE;
308
    return TRUE;
189
}
309
}
190
 
310
 
191
static void tb_activate_cb(GtkWidget *widget, gpointer data) 
311
static void toolbar_activate_cb(GtkWidget *widget, gpointer data) 
192
{
312
{
193
    DevDesc *dd;
313
    DevDesc *dd;
194
 
314
 
195
    dd = (DevDesc *) data;
315
    dd = (DevDesc *) data;
196
    g_return_if_fail(dd != NULL);
316
    g_return_if_fail(dd != NULL);
197
 
317
 
198
    selectDevice(deviceNumber(dd));
318
    selectDevice(deviceNumber(dd));
199
}
319
}
200
 
320
 
201
static void tb_close_cb(GtkWidget *widget, gpointer data) 
321
static void toolbar_close_cb(GtkWidget *widget, gpointer data) 
202
{
322
{
203
    DevDesc *dd;
323
    DevDesc *dd;
204
 
324
 
205
    dd = (DevDesc *) data;
325
    dd = (DevDesc *) data;
206
    g_return_if_fail(dd != NULL);
326
    g_return_if_fail(dd != NULL);
207
 
327
 
208
    KillDevice(dd);
328
    KillDevice(dd);
209
}
329
}
210
 
330
 
-
 
331
static void
-
 
332
save_ok (GtkWidget *ok_button, gpointer data)
-
 
333
{
-
 
334
  GtkFileSelection *fsel = GTK_FILE_SELECTION(data);
-
 
335
  char *filename = gtk_file_selection_get_filename(fsel);
-
 
336
  DevDesc *dd;
-
 
337
 
-
 
338
  if (!filename)
-
 
339
    return;
-
 
340
  dd = gtk_object_get_user_data(GTK_OBJECT(fsel));
-
 
341
  SaveAsPostscript(dd, filename);
-
 
342
  gtk_widget_destroy (GTK_WIDGET(fsel));
-
 
343
}
-
 
344
 
-
 
345
 
-
 
346
static void toolbar_save_as_cb(GtkWidget *widget, gpointer data)
-
 
347
{
-
 
348
  DevDesc *dd = (DevDesc*) data;
-
 
349
  gnomeDesc *gd = (gnomeDesc*) dd->deviceSpecific;
-
 
350
 
-
 
351
  GtkFileSelection *fsel = 
-
 
352
    GTK_FILE_SELECTION(gtk_file_selection_new("Save as PostScript"));
-
 
353
 
-
 
354
  gtk_object_set_user_data(GTK_OBJECT(fsel), dd);
-
 
355
 
-
 
356
  gtk_signal_connect(GTK_OBJECT(fsel->ok_button), "clicked",
-
 
357
                     GTK_SIGNAL_FUNC(save_ok), fsel);
-
 
358
  gtk_signal_connect_object(GTK_OBJECT(fsel->cancel_button), "clicked",
-
 
359
                            GTK_SIGNAL_FUNC(gtk_widget_destroy),
-
 
360
                            GTK_OBJECT(fsel));
-
 
361
 
-
 
362
 
-
 
363
  gtk_window_position(GTK_WINDOW(fsel), GTK_WIN_POS_MOUSE);
-
 
364
  gtk_window_set_transient_for(GTK_WINDOW(fsel), GTK_WINDOW(gd->window));
-
 
365
  gtk_widget_show(GTK_WIDGET(fsel));
-
 
366
 
-
 
367
}
-
 
368
 
-
 
369
static void toolbar_print_cb (GtkWidget *widget, gpointer data)
-
 
370
{
-
 
371
  DevDesc *dd = (DevDesc*) data;
-
 
372
  SaveAsPostscript(dd, "");
-
 
373
}
-
 
374
 
211
static GnomeUIInfo graphics_toolbar[] =
375
static GnomeUIInfo graphics_toolbar[] =
212
{
376
{
213
    { GNOME_APP_UI_ITEM, "Activate", "Make this window the current device", tb_activate_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_JUMP_TO, 0, (GdkModifierType) 0, NULL },
377
  { GNOME_APP_UI_ITEM, "Activate", "Make this window the current device",
-
 
378
    toolbar_activate_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK,
-
 
379
    GNOME_STOCK_PIXMAP_JUMP_TO, 0, (GdkModifierType) 0, NULL },
214
    GNOMEUIINFO_SEPARATOR,
380
  GNOMEUIINFO_SEPARATOR,
-
 
381
  { GNOME_APP_UI_ITEM, "Save As", "Save as a PostScript file", 
-
 
382
    toolbar_save_as_cb, NULL, NULL, 
215
    { GNOME_APP_UI_ITEM, "Save As", "Save as a PS file", NULL, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_SAVE_AS, 0, (GdkModifierType) 0, NULL },
383
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_SAVE_AS, 0, 
-
 
384
    (GdkModifierType) 0, NULL },
-
 
385
  { GNOME_APP_UI_ITEM, "Print", "Print graphics", 
-
 
386
    toolbar_print_cb, NULL, NULL, 
216
    { GNOME_APP_UI_ITEM, "Print", "Print graphics", NULL, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_PRINT, 0, (GdkModifierType) 0, NULL },
387
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_PRINT, 0, 
-
 
388
    (GdkModifierType) 0, NULL },
217
    GNOMEUIINFO_SEPARATOR,
389
  GNOMEUIINFO_SEPARATOR,
218
    { GNOME_APP_UI_ITEM, "Close", "Close this graphics device", tb_close_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_CLOSE, 0, (GdkModifierType) 0, NULL },
390
  { GNOME_APP_UI_ITEM, "Close", "Close this graphics device",
-
 
391
    toolbar_close_cb, NULL, NULL,
-
 
392
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_CLOSE, 0, 
-
 
393
    (GdkModifierType) 0, NULL },
219
    GNOMEUIINFO_END
394
  GNOMEUIINFO_END
220
};
395
};
221
 
396
 
-
 
397
static void GNOME_NewPage(DevDesc *dd)
-
 
398
{
-
 
399
  GnomeCanvasItem *group;
-
 
400
  gnomeDesc *gd = (gnomeDesc*) dd->deviceSpecific;
-
 
401
 
-
 
402
  g_return_if_fail(gd->canvas);
-
 
403
 
-
 
404
  if (gd->group)
-
 
405
    {
-
 
406
      gtk_object_destroy(GTK_OBJECT(gd->group));
-
 
407
      gd->plotarea = NULL;
-
 
408
    }
-
 
409
  
-
 
410
  /* create group for plotting objects */
-
 
411
  group = gnome_canvas_item_new (gnome_canvas_root(GNOME_CANVAS(gd->canvas)),
-
 
412
				 gnome_canvas_group_get_type(),
-
 
413
				 "x", (double) 0.0,
-
 
414
				 "y", (double) 0.0,
-
 
415
				 NULL);
-
 
416
  gd->group = GNOME_CANVAS_GROUP(group);
-
 
417
  
-
 
418
  /* create plotting area */
-
 
419
  gd->plotarea = 
-
 
420
    gnome_canvas_item_new (gd->group,
-
 
421
			   gnome_canvas_rect_get_type(),
-
 
422
			   "x1", (double) 0.0,
-
 
423
			   "y1", (double) 0.0,
-
 
424
			   "x2", (double) gd->windowWidth,
-
 
425
			   "y2", (double) gd->windowHeight,
-
 
426
			   "fill_color_rgba", Color_RGBA(dd->dp.bg),
-
 
427
			   NULL);
-
 
428
}
-
 
429
 
222
/* create window etc */
430
/* create window etc */
223
static Rboolean
431
static Rboolean
224
GNOME_Open(DevDesc *dd, gnomeDesc *gtkd, char *dsp, double w, double h)
432
GNOME_Open(DevDesc *dd, gnomeDesc *gd, char *dsp, double w, double h)
225
{
433
{
226
    GdkColor bg;
-
 
227
    GtkStyle *wstyle;
434
    GnomeCanvasItem *group;
228
 
435
 
229
    gint iw, ih;
436
    gint iw, ih;
230
 
437
 
231
    /*gdk_rgb_set_install(TRUE); */
438
    /*gdk_rgb_set_install(TRUE); */
232
    /* gdk_rgb_set_verbose(TRUE);*/
439
    /* gdk_rgb_set_verbose(TRUE);*/
233
    gdk_rgb_init();
440
    gdk_rgb_init();
234
    gtk_widget_push_visual(gdk_rgb_get_visual());
441
    gtk_widget_push_visual(gdk_rgb_get_visual());
235
    gtk_widget_push_colormap(gdk_rgb_get_cmap());
442
    gtk_widget_push_colormap(gdk_rgb_get_cmap());
236
 
443
 
237
    /* initialise pointers */
444
    /* initialise pointers */
238
    gtkd->canvas = NULL;
445
    gd->canvas = NULL;
-
 
446
    gd->group = NULL;
-
 
447
    gd->plotarea = NULL;
239
 
448
 
240
    /* FIXME: SetBaseFont */
449
    if(!SetBaseFont(gd))
-
 
450
      {
-
 
451
	Rprintf("can't find X11 font\n");
-
 
452
	return FALSE;
-
 
453
      }
241
 
454
 
242
    /* create window etc */
455
    /* create window etc */
243
    gtkd->windowWidth = iw = w / pixelWidth();
456
    gd->windowWidth = iw = w / pixelWidth();
244
    gtkd->windowHeight = ih = h / pixelHeight();
457
    gd->windowHeight = ih = h / pixelHeight();
245
 
458
 
246
    gtkd->window = gnome_app_new("R.gnome.graphics", "R Graphics");
459
    gd->window = gnome_app_new("R.gnome.graphics", "R Graphics");
247
 
460
 
248
    gtk_window_set_policy(GTK_WINDOW(gtkd->window), TRUE, TRUE, FALSE);
461
    gtk_window_set_policy(GTK_WINDOW(gd->window), TRUE, TRUE, FALSE);
249
    gtk_widget_realize(gtkd->window);
462
    gtk_widget_realize(gd->window);
250
 
463
 
251
    /* create toolbar */
464
    /* create toolbar */
252
    gnome_app_create_toolbar_with_data(GNOME_APP(gtkd->window), graphics_toolbar, (gpointer) dd);
465
    gnome_app_create_toolbar_with_data(GNOME_APP(gd->window), graphics_toolbar,
-
 
466
				       (gpointer) dd);
253
 
467
 
254
    /* create canvas */
468
    /* create canvas */
255
    gtkd->canvas = gnome_canvas_new_aa();
469
    gd->canvas = gnome_canvas_new_aa();
256
 
-
 
257
    /* set window background color */
-
 
258
    gtkd->bg = dd->dp.bg = R_RGB(255, 255, 255);
-
 
259
    gtkd->gcol_bg = gdk_color_copy(&bg);
-
 
260
    SetColor(gtkd->gcol_bg, gtkd->bg);
-
 
261
 
-
 
262
    wstyle = gtk_style_copy(gtk_widget_get_style(gtkd->canvas));
470
    gtk_widget_set_usize(gd->canvas, iw, ih);
263
    wstyle->bg[GTK_STATE_NORMAL] = *(gtkd->gcol_bg);
-
 
264
    gtk_widget_set_style(gtkd->canvas, wstyle);
471
    gnome_canvas_set_scroll_region(GNOME_CANVAS(gd->canvas), 0, 0, iw, ih);
265
 
472
 
266
    /* canvas properties */
473
    /* create new plot area on canvas */
267
    gtk_widget_set_usize(gtkd->canvas, iw, ih);
474
    dd->dp.bg = R_RGB(255,255,255);
268
    gnome_canvas_set_scroll_region(GNOME_CANVAS(gtkd->canvas), 0, 0, iw, ih);
475
    GNOME_NewPage(dd);
269
 
476
 
270
    /* place and realize the canvas */
477
    /* place and realize the canvas */
271
    gnome_app_set_contents(GNOME_APP(gtkd->window), gtkd->canvas);
478
    gnome_app_set_contents(GNOME_APP(gd->window), gd->canvas);
272
    gtk_widget_realize(gtkd->canvas);
479
    gtk_widget_realize(gd->canvas);
273
 
480
 
274
    /* same as XSynch() */
481
    /* same as XSynch() */
275
    gdk_flush();
482
    gdk_flush();
276
 
483
 
277
    /* set the cursor */
484
    /* set the cursor */
278
    gtkd->gcursor = gdk_cursor_new(GDK_CROSSHAIR);
485
    gd->gcursor = gdk_cursor_new(GDK_CROSSHAIR);
279
    gdk_window_set_cursor(gtkd->canvas->window, gtkd->gcursor);
486
    gdk_window_set_cursor(gd->canvas->window, gd->gcursor);
280
 
487
 
281
    /* connect to delete signal handler, etc */
488
    /* connect to delete signal handler, etc */
282
    gtk_signal_connect(GTK_OBJECT(gtkd->canvas), "configure_event",
489
    gtk_signal_connect(GTK_OBJECT(gd->canvas), "configure_event",
283
		       (GtkSignalFunc) configure_event, (gpointer) dd);
490
		       (GtkSignalFunc) configure_event, (gpointer) dd);
284
    gtk_signal_connect(GTK_OBJECT(gtkd->window), "delete_event",
491
    gtk_signal_connect(GTK_OBJECT(gd->window), "delete_event",
285
		       (GtkSignalFunc) delete_event, (gpointer) dd);
492
		       (GtkSignalFunc) delete_event, (gpointer) dd);
286
 
493
 
287
    /* show everything */
494
    /* show everything */
288
    gtk_widget_show_all(gtkd->window);
495
    gtk_widget_show_all(gd->window);
289
 
496
 
290
    /* let other widgets use the default settings */
497
    /* let other widgets use the default settings */
291
    gtk_widget_pop_visual();
498
    gtk_widget_pop_visual();
292
    gtk_widget_pop_colormap();
499
    gtk_widget_pop_colormap();
293
 
500
 
Line 295... Line 502...
295
    return TRUE;
502
    return TRUE;
296
}
503
}
297
 
504
 
298
static double GNOME_StrWidth(char *str, DevDesc *dd)
505
static double GNOME_StrWidth(char *str, DevDesc *dd)
299
{
506
{
300
    return 6.0;
507
  int size;
-
 
508
  gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
-
 
509
 
-
 
510
  size = dd->gp.cex * dd->gp.ps + 0.5;
-
 
511
  SetFont(dd, dd->gp.font, size);
-
 
512
 
-
 
513
  return (double) gdk_string_width(gd->font, str);
301
}
514
}
302
 
515
 
303
static void GNOME_MetricInfo(int c, double *ascent, double *descent, double *width, DevDesc *dd)
516
static void GNOME_MetricInfo(int c, double *ascent, double *descent,
-
 
517
			     double *width, DevDesc *dd)
304
{
518
{
-
 
519
  gint size;
305
    /* metric information not available => return 0,0,0 */
520
  gint lbearing, rbearing, iascent, idescent, iwidth;
-
 
521
  gint maxwidth;
306
    *ascent = 0.0;
522
  gchar tmp[2];
-
 
523
  gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
-
 
524
 
-
 
525
  size = dd->gp.cex * dd->gp.ps + 0.5;
-
 
526
  SetFont(dd, dd->gp.font, size);
-
 
527
 
307
    *descent = 0.0;
528
  if(c == 0) {
308
    *width = 0.0;
529
    maxwidth = 0;
-
 
530
 
-
 
531
    for(c = 0; c <= 255; c++) {
-
 
532
      g_snprintf(tmp, 2, "%c", (gchar) c);
-
 
533
      iwidth = gdk_string_width(gd->font, tmp);
-
 
534
      if (iwidth > maxwidth)
-
 
535
	maxwidth = iwidth;
-
 
536
    }
-
 
537
 
-
 
538
    *ascent = (double) gd->font->ascent;
-
 
539
    *descent = (double) gd->font->descent;
-
 
540
    *width = (double) maxwidth;
-
 
541
  }
-
 
542
  else {
-
 
543
    g_snprintf(tmp, 2, "%c", (gchar) c);
-
 
544
    gdk_string_extents(gd->font, tmp,
-
 
545
		       &lbearing, &rbearing,
-
 
546
		       &iwidth, &iascent, &idescent);
-
 
547
 
-
 
548
    *ascent = (double) iascent;
-
 
549
    *descent = (double) idescent;
-
 
550
    *width = (double) (lbearing+rbearing);
-
 
551
  }
309
}
552
}
310
 
553
 
311
static void GNOME_Clip(double x0, double x1, double y0, double y1, DevDesc *dd)
554
static void GNOME_Clip(double x0, double x1, double y0, double y1, DevDesc *dd)
312
{
555
{
-
 
556
  /* 
-
 
557
     Clipping is theoretically possible: there is an implementation of
-
 
558
     it in gnome-print-preview, which has a class called clipped-group. As
-
 
559
     the name suggests, this is a canvas group which defines a
-
 
560
     clipping path for the items it contains.  The notes say that this
-
 
561
     will be folded into the standard GnomeCanvasGroup, so I'm waiting
-
 
562
     for this to happen instead of duplicating it here. MTP 6/9/2001
-
 
563
  */
313
}
564
}
314
 
565
 
315
static void GNOME_Resize(DevDesc *dd)
566
static void GNOME_Resize(DevDesc *dd)
316
{
567
{
317
    gnomeDesc *gtkd = (gnomeDesc *) dd->deviceSpecific;
568
    gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
318
 
569
 
319
    if (gtkd->resize) {
570
    if (gd->resize) {
320
	dd->dp.left = dd->gp.left = 0.0;
571
	dd->dp.left = dd->gp.left = 0.0;
321
	dd->dp.right = dd->gp.right =  gtkd->windowWidth;
572
	dd->dp.right = dd->gp.right =  gd->windowWidth;
322
	dd->dp.bottom = dd->gp.bottom = gtkd->windowHeight;
573
	dd->dp.bottom = dd->gp.bottom = gd->windowHeight;
323
	dd->dp.top = dd->gp.top = 0.0;
574
	dd->dp.top = dd->gp.top = 0.0;
324
	gtkd->resize = FALSE;
575
	gd->resize = FALSE;
325
    }
576
    }
326
}
577
}
327
 
578
 
328
/* clear the drawing area */
-
 
329
void GNOME_NewPage_iterator(gpointer data, gpointer user_data)
-
 
330
{
-
 
331
    GList *list;
-
 
332
    GnomeCanvasItem *child;
-
 
333
 
-
 
334
    list = (GList *) data;
-
 
335
    child = (GnomeCanvasItem *) list->data;
-
 
336
 
-
 
337
    gtk_object_destroy(GTK_OBJECT(child));
-
 
338
}
-
 
339
 
-
 
340
static void GNOME_NewPage(DevDesc *dd)
-
 
341
{
-
 
342
    gnomeDesc *gtkd = (gnomeDesc *) dd->deviceSpecific;
-
 
343
 
-
 
344
    /* reset background color */
-
 
345
    if(gtkd->bg != dd->dp.bg) {
-
 
346
	gtkd->bg = dd->dp.bg;
-
 
347
	SetColor(gtkd->gcol_bg, gtkd->bg);
-
 
348
 
-
 
349
	/* FIXME: change window style */
-
 
350
    }
-
 
351
 
-
 
352
    /* clear off items */
-
 
353
    /*  list = GNOME_CANVAS_GROUP(gnome_canvas_root(GNOME_CANVAS(gtkd->canvas)))->item_list;
-
 
354
	if(list != NULL) {
-
 
355
	g_list_foreach(list, GNOME_NewPage_iterator, NULL);
-
 
356
	g_list_free(list);
-
 
357
	GNOME_CANVAS_GROUP(gnome_canvas_root(GNOME_CANVAS(gtkd->canvas)))->item_list = NULL;
-
 
358
	GNOME_CANVAS_GROUP(gnome_canvas_root(GNOME_CANVAS(gtkd->canvas)))->item_list_end = NULL;
-
 
359
	}*/
-
 
360
}
-
 
361
 
579
 
362
/* kill off the window etc */
580
/* kill off the window etc */
363
static void GNOME_Close(DevDesc *dd)
581
static void GNOME_Close(DevDesc *dd)
364
{
582
{
365
    gnomeDesc *gtkd = (gnomeDesc *) dd->deviceSpecific;
583
    gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
366
 
584
 
367
    gtk_widget_destroy(gtkd->window);
585
    gtk_widget_destroy(gd->window);
368
 
586
 
369
    free(gtkd);
587
    free(gd);
370
}
588
}
371
 
589
 
372
#define title_text_inactive "R graphics device %d"
590
#define title_text_inactive "R graphics device %d"
373
#define title_text_active "R graphics device %d - Active"
591
#define title_text_active "R graphics device %d - Active"
374
 
592
 
375
static void GNOME_Activate(DevDesc *dd)
593
static void GNOME_Activate(DevDesc *dd)
376
{
594
{
377
    gnomeDesc *gtkd;
595
    gnomeDesc *gd;
378
    gint devnum, numdigits;
596
    gint devnum, numdigits;
379
    gchar *title_text;
597
    gchar *title_text;
380
    gint text_len;
598
    gint text_len;
381
 
599
 
382
    text_len = strlen(title_text_active);
600
    text_len = strlen(title_text_active);
383
 
601
 
384
    gtkd = (gnomeDesc *) dd->deviceSpecific;
602
    gd = (gnomeDesc *) dd->deviceSpecific;
385
 
603
 
386
    g_return_if_fail(gtkd != NULL);
604
    g_return_if_fail(gd != NULL);
387
 
605
 
388
    devnum = deviceNumber(dd);
606
    devnum = deviceNumber(dd);
389
    devnum++;
607
    devnum++;
390
    numdigits = floor(R_Log10(devnum)) + 1;
608
    numdigits = floor(R_Log10(devnum)) + 1;
391
    title_text = g_malloc(text_len + numdigits + 1);
609
    title_text = g_malloc(text_len + numdigits + 1);
Line 393... Line 611...
393
    g_return_if_fail(title_text != NULL);
611
    g_return_if_fail(title_text != NULL);
394
 
612
 
395
    snprintf(title_text, text_len + numdigits + 1, title_text_active, devnum);
613
    snprintf(title_text, text_len + numdigits + 1, title_text_active, devnum);
396
    *(title_text + text_len + numdigits) = '\0';
614
    *(title_text + text_len + numdigits) = '\0';
397
 
615
 
398
    gtk_window_set_title(GTK_WINDOW(gtkd->window), title_text);
616
    gtk_window_set_title(GTK_WINDOW(gd->window), title_text);
399
 
617
 
400
    g_free(title_text);
618
    g_free(title_text);
-
 
619
 
-
 
620
    gtk_widget_set_sensitive(GTK_WIDGET(graphics_toolbar[0].widget),
-
 
621
			     FALSE);
401
}
622
}
402
 
623
 
403
static void GNOME_Deactivate(DevDesc *dd)
624
static void GNOME_Deactivate(DevDesc *dd)
404
{
625
{
405
    gnomeDesc *gtkd;
626
    gnomeDesc *gd;
406
    gint devnum, numdigits;
627
    gint devnum, numdigits;
407
    gchar *title_text;
628
    gchar *title_text;
408
    gint text_len;
629
    gint text_len;
-
 
630
    GtkWidget *button;
409
 
631
 
410
    text_len = strlen(title_text_inactive);
632
    text_len = strlen(title_text_inactive);
411
 
633
 
412
    gtkd = (gnomeDesc *) dd->deviceSpecific;
634
    gd = (gnomeDesc *) dd->deviceSpecific;
413
 
635
 
414
    g_return_if_fail(gtkd != NULL);
636
    g_return_if_fail(gd != NULL);
415
 
637
 
416
    devnum = deviceNumber(dd);
638
    devnum = deviceNumber(dd);
417
    devnum++;
639
    devnum++;
418
    numdigits = floor(R_Log10(devnum)) + 1;
640
    numdigits = floor(R_Log10(devnum)) + 1;
419
    title_text = g_malloc(text_len + numdigits + 1);
641
    title_text = g_malloc(text_len + numdigits + 1);
Line 421... Line 643...
421
    g_return_if_fail(title_text != NULL);
643
    g_return_if_fail(title_text != NULL);
422
 
644
 
423
    snprintf(title_text, text_len + numdigits + 1, title_text_inactive, devnum);
645
    snprintf(title_text, text_len + numdigits + 1, title_text_inactive, devnum);
424
    *(title_text + text_len + numdigits) = '\0';
646
    *(title_text + text_len + numdigits) = '\0';
425
 
647
 
426
    gtk_window_set_title(GTK_WINDOW(gtkd->window), title_text);
648
    gtk_window_set_title(GTK_WINDOW(gd->window), title_text);
427
 
649
 
428
    g_free(title_text);
650
    g_free(title_text);
-
 
651
 
-
 
652
    button = GTK_WIDGET(graphics_toolbar[0].widget);
-
 
653
    gtk_widget_set_sensitive(button, TRUE);
429
}
654
}
430
 
655
 
431
/* drawing stuff */
656
/* drawing stuff */
432
 
657
 
433
static void GNOME_Rect(double x0, double y0, double x1, double y1,
658
static void GNOME_Rect(double x0, double y0, double x1, double y1,
434
		     int coords, int bg, int fg, DevDesc *dd)
659
		     int coords, int bg, int fg, DevDesc *dd)
435
{
660
{
436
    double tmp;
661
    double tmp;
437
    gnomeDesc *gtkd = (gnomeDesc *) dd->deviceSpecific;
662
    gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
438
    GdkColor gcol_fill, gcol_outline;
663
    GdkColor gcol_fill, gcol_outline;
439
    GnomeCanvasItem *item;
664
    GnomeCanvasItem *item;
440
 
665
 
441
    GConvert(&x0, &y0, coords, DEVICE, dd);
666
    GConvert(&x0, &y0, coords, DEVICE, dd);
442
    GConvert(&x1, &y1, coords, DEVICE, dd);
667
    GConvert(&x1, &y1, coords, DEVICE, dd);
Line 450... Line 675...
450
	tmp = y0;
675
	tmp = y0;
451
	y0 = y1;
676
	y0 = y1;
452
	y1 = tmp;
677
	y1 = tmp;
453
    }
678
    }
454
 
679
 
455
    item = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(gtkd->canvas)),
680
    item = gnome_canvas_item_new(gd->group,
456
				 gnome_canvas_rect_get_type(),
681
				 gnome_canvas_rect_get_type(),
457
				 "x1", x0,
682
				 "x1", x0,
458
				 "y1", y0,
683
				 "y1", y0,
459
				 "x2", x1,
684
				 "x2", x1,
460
				 "y2", y1,
685
				 "y2", y1,
461
				 "width_pixels", (guint) dd->gp.lwd,
686
				 "width_units", (double) dd->gp.lwd,
462
				 NULL);
687
				 NULL);
463
 
688
 
464
    if(bg != NA_INTEGER) {
689
    if(bg != NA_INTEGER) {
465
	SetColor(&gcol_fill, bg);
-
 
466
	gnome_canvas_item_set(item,
690
	gnome_canvas_item_set(item,
467
			      "fill_color_gdk", &gcol_fill,
691
			      "fill_color_rgba", Color_RGBA(bg),
468
			      NULL);
692
			      NULL);
469
    }
693
    }
470
    if(fg != NA_INTEGER) {
694
    if(fg != NA_INTEGER) {
471
	SetColor(&gcol_outline, fg);
-
 
472
	gnome_canvas_item_set(item,
695
	gnome_canvas_item_set(item,
473
			      "outline_color_gdk", &gcol_outline,
696
			      "outline_color_rgba", Color_RGBA(fg),
474
			      NULL);
697
			      NULL);
475
    }
698
    }
476
}
699
}
477
 
700
 
478
static void GNOME_Circle(double x, double y, int coords,
701
static void GNOME_Circle(double x, double y, int coords,
479
		       double r, int col, int border, DevDesc *dd)
702
		       double r, int col, int border, DevDesc *dd)
480
{
703
{
481
    GdkColor gcol_fill, gcol_outline;
704
    GdkColor gcol_fill, gcol_outline;
482
    double x1, y1, x2, y2;
705
    double x1, y1, x2, y2;
483
    gnomeDesc *gtkd = (gnomeDesc *) dd->deviceSpecific;
706
    gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
484
    GnomeCanvasItem *item;
707
    GnomeCanvasItem *item;
485
 
708
 
486
    GConvert(&x, &y, coords, DEVICE, dd);
709
    GConvert(&x, &y, coords, DEVICE, dd);
487
 
710
 
488
    x1 = x - r;  y1 = y - r;
711
    x1 = x - r;  y1 = y - r;
489
    x2 = x + r;  y2 = y + r;
712
    x2 = x + r;  y2 = y + r;
490
 
713
 
491
    item = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(gtkd->canvas)),
714
    item = gnome_canvas_item_new(gd->group,
492
				 gnome_canvas_ellipse_get_type(),
715
				 gnome_canvas_ellipse_get_type(),
493
				 "x1", x1,
716
				 "x1", x1,
494
				 "y1", y1,
717
				 "y1", y1,
495
				 "x2", x2,
718
				 "x2", x2,
496
				 "y2", y2,
719
				 "y2", y2,
497
				 "width_pixels", (guint) dd->gp.lwd,
720
				 "width_units", (double) dd->gp.lwd,
498
				 NULL);
721
				 NULL);
499
 
722
 
500
    if(col != NA_INTEGER) {
723
    if(col != NA_INTEGER) {
501
	SetColor(&gcol_fill, col);
-
 
502
	gnome_canvas_item_set(item,
724
	gnome_canvas_item_set(item,
503
			      "fill_color_gdk", &gcol_fill,
725
			      "fill_color_rgba", Color_RGBA(col),
504
			      NULL);
726
			      NULL);
505
    }
727
    }
506
    if(border != NA_INTEGER) {
728
    if(border != NA_INTEGER) {
507
	SetColor(&gcol_outline, border);
-
 
508
	gnome_canvas_item_set(item,
729
	gnome_canvas_item_set(item,
509
			      "outline_color_gdk", &gcol_outline,
730
			      "outline_color_rgba", Color_RGBA(border),
510
			      NULL);
731
			      NULL);
511
    }
732
    }
512
}
733
}
513
 
734
 
514
static void GNOME_Line(double x1, double y1, double x2, double y2,
735
static void GNOME_Line(double x1, double y1, double x2, double y2,
515
		     int coords, DevDesc *dd)
736
		     int coords, DevDesc *dd)
516
{
737
{
517
    GnomeCanvasPoints *points;
738
    GnomeCanvasPoints *points;
518
    gnomeDesc *gtkd = (gnomeDesc *) dd->deviceSpecific;
739
    gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
519
    GnomeCanvasItem *item;
740
    GnomeCanvasItem *item;
520
    GdkColor gcol_fill;
741
    GdkColor gcol_fill;
521
 
742
 
522
    GConvert(&x1, &y1, coords, DEVICE, dd);
743
    GConvert(&x1, &y1, coords, DEVICE, dd);
523
    GConvert(&x2, &y2, coords, DEVICE, dd);
744
    GConvert(&x2, &y2, coords, DEVICE, dd);
Line 526... Line 747...
526
    points->coords[0] = x1;
747
    points->coords[0] = x1;
527
    points->coords[1] = y1;
748
    points->coords[1] = y1;
528
    points->coords[2] = x2;
749
    points->coords[2] = x2;
529
    points->coords[3] = y2;
750
    points->coords[3] = y2;
530
 
751
 
531
    item = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(gtkd->canvas)),
752
    item = gnome_canvas_item_new(gd->group,
532
				 gnome_canvas_line_get_type(),
753
				 gnome_canvas_line_get_type(),
533
				 "points", points,
754
				 "points", points,
534
				 "width_pixels", (guint) dd->gp.lwd,
755
				 "width_units", (double) dd->gp.lwd,
535
				 NULL);
756
				 NULL);
536
 
757
 
537
    if(dd->gp.col != NA_INTEGER) {
758
    if(dd->gp.col != NA_INTEGER) {
538
	SetColor(&gcol_fill, dd->gp.col);
-
 
539
	if(dd->gp.lty != 0) {
759
	if(dd->gp.lty != 0) {
540
	    /*SetLineType(GNOME_CANVAS_LINE(item)->gc, dd->gp.lty, dd->gp.lwd);*/
760
	    /*SetLineType(GNOME_CANVAS_LINE(item)->gc, dd->gp.lty, dd->gp.lwd);*/
541
	    gnome_canvas_item_set(item,
761
	    gnome_canvas_item_set(item,
542
				  "line_style", GDK_LINE_ON_OFF_DASH,
762
				  "line_style", GDK_LINE_ON_OFF_DASH,
543
				  NULL);
763
				  NULL);
544
	}
764
	}
545
	gnome_canvas_item_set(item,
765
	gnome_canvas_item_set(item,
546
			      "fill_color_gdk", &gcol_fill,
766
			      "fill_color_rgba", Color_RGBA(dd->gp.col),
547
			      NULL);
767
			      NULL);
548
    }
768
    }
549
 
769
 
550
    gnome_canvas_points_free(points);
770
    gnome_canvas_points_free(points);
551
}
771
}
Line 553... Line 773...
553
static void GNOME_Polyline(int n, double *x, double *y, int coords, DevDesc *dd)
773
static void GNOME_Polyline(int n, double *x, double *y, int coords, DevDesc *dd)
554
{
774
{
555
    double devx, devy;
775
    double devx, devy;
556
    int i;
776
    int i;
557
    GnomeCanvasPoints *points;
777
    GnomeCanvasPoints *points;
558
    gnomeDesc *gtkd = (gnomeDesc *) dd->deviceSpecific;
778
    gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
559
    GnomeCanvasItem *item;
779
    GnomeCanvasItem *item;
560
    GdkColor gcol_fill;
780
    GdkColor gcol_fill;
561
    GdkBitmap stipple;
781
    GdkBitmap stipple;
562
 
782
 
563
    points = gnome_canvas_points_new(n);
783
    points = gnome_canvas_points_new(n);
Line 567... Line 787...
567
	GConvert(&devx, &devy, coords, DEVICE, dd);
787
	GConvert(&devx, &devy, coords, DEVICE, dd);
568
	points->coords[i * 2] = devx;
788
	points->coords[i * 2] = devx;
569
	points->coords[i * 2 + 1] = devy;
789
	points->coords[i * 2 + 1] = devy;
570
    }
790
    }
571
 
791
 
572
    item = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(gtkd->canvas)),
792
    item = gnome_canvas_item_new(gd->group,
573
				 gnome_canvas_line_get_type(),
793
				 gnome_canvas_line_get_type(),
574
				 "points", points,
794
				 "points", points,
575
				 "width_pixels", (guint) dd->gp.lwd,
795
				 "width_units", (double) dd->gp.lwd,
576
				 NULL);
796
				 NULL);
577
 
797
 
578
    if(dd->gp.col != NA_INTEGER) {
798
    if(dd->gp.col != NA_INTEGER) {
579
	SetColor(&gcol_fill, dd->gp.col);
-
 
580
	if(dd->gp.lty != 0) {
799
	if(dd->gp.lty != 0) {
-
 
800
	  /*
581
	    SetLineType(&stipple, dd->gp.lty, dd->gp.lwd);
801
	    SetLineType(&stipple, dd->gp.lty, dd->gp.lwd);
582
	    gnome_canvas_item_set(item,
802
	    gnome_canvas_item_set(item,
583
				  "fill_stipple", &stipple,
803
				  "fill_stipple", &stipple,
584
				  NULL);
804
				  NULL);
-
 
805
	    */
-
 
806
	    gnome_canvas_item_set(item,
-
 
807
				  "line_style", GDK_LINE_ON_OFF_DASH,
-
 
808
				  NULL);
585
	}
809
	}
586
	gnome_canvas_item_set(item,
810
	gnome_canvas_item_set(item,
587
			      "fill_color_gdk", &gcol_fill,
811
			      "fill_color_rgba", Color_RGBA(dd->gp.col),
588
			      NULL);
812
			      NULL);
589
    }
813
    }
590
 
814
 
591
    gnome_canvas_points_free(points);
815
    gnome_canvas_points_free(points);
592
}
816
}
Line 595... Line 819...
595
			int bg, int fg, DevDesc *dd)
819
			int bg, int fg, DevDesc *dd)
596
{
820
{
597
    double devx, devy;
821
    double devx, devy;
598
    int i;
822
    int i;
599
    GnomeCanvasPoints *points;
823
    GnomeCanvasPoints *points;
600
    gnomeDesc *gtkd = (gnomeDesc *) dd->deviceSpecific;
824
    gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
601
    GnomeCanvasItem *item;
825
    GnomeCanvasItem *item;
602
    GdkColor gcol_fill, gcol_outline;
826
    GdkColor gcol_fill, gcol_outline;
603
 
827
 
604
    points = gnome_canvas_points_new(n);
828
    points = gnome_canvas_points_new(n);
605
 
829
 
Line 608... Line 832...
608
	GConvert(&devx, &devy, coords, DEVICE, dd);
832
	GConvert(&devx, &devy, coords, DEVICE, dd);
609
	points->coords[i * 2] = floor(devx);
833
	points->coords[i * 2] = floor(devx);
610
	points->coords[i * 2 + 1] = floor(devy);
834
	points->coords[i * 2 + 1] = floor(devy);
611
    }
835
    }
612
 
836
 
613
    item = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(gtkd->canvas)),
837
    item = gnome_canvas_item_new(gd->group,
614
				 gnome_canvas_polygon_get_type(),
838
				 gnome_canvas_polygon_get_type(),
615
				 "points", points,
839
				 "points", points,
616
				 "width_units", (double) 2,
840
				 "width_units", (double) 2,
617
				 NULL);
841
				 NULL);
618
 
842
 
619
    if(bg != NA_INTEGER) {
843
    if(bg != NA_INTEGER) {
620
	SetColor(&gcol_fill, bg);
-
 
621
	gnome_canvas_item_set(item,
844
	gnome_canvas_item_set(item,
622
			      "fill_color_gdk", &gcol_fill,
845
			      "fill_color_rgba", Color_RGBA(bg),
623
			      NULL);
846
			      NULL);
624
    }
847
    }
625
    if(fg != NA_INTEGER) {
848
    if(fg != NA_INTEGER) {
626
	SetColor(&gcol_outline, fg);
-
 
627
	gnome_canvas_item_set(item,
849
	gnome_canvas_item_set(item,
628
			      "outline_color", "black",
850
			      "outline_color_rgba", Color_RGBA(fg),
629
			      NULL);
851
			      NULL);
630
    }
852
    }
631
 
853
 
632
    gnome_canvas_points_free(points);
854
    gnome_canvas_points_free(points);
633
}
855
}
634
 
856
 
635
static void GNOME_Text(double x, double y, int coords,
857
static void GNOME_Text(double x, double y, int coords,
636
		       char *str, double rot, double hadj, DevDesc *dd)
858
		       char *str, double rot, double hadj, DevDesc *dd)
637
{
859
{
-
 
860
  double affine[6] = {1, 0, 0, 1, 0, 0};
-
 
861
  double rrot = DEG2RAD * rot;
638
    GnomeCanvasItem *item;
862
  GnomeCanvasItem *item;
639
    gnomeDesc *gtkd = (gnomeDesc *) dd->deviceSpecific;
863
  gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
640
    GdkColor gcol_fill;
864
  int size;
641
 
865
 
642
    GConvert(&x, &y, coords, DEVICE, dd);
866
  GConvert(&x, &y, coords, DEVICE, dd);
643
 
867
 
-
 
868
  size = dd->gp.cex * dd->gp.ps + 0.5;
644
    SetColor(&gcol_fill, dd->gp.col);
869
  SetFont(dd, dd->gp.font, size);
645
  
870
  
-
 
871
  if (rot != 0)
-
 
872
    {
-
 
873
      affine[0] = affine[3] = cos(rrot);
-
 
874
      affine[1] = -sin(rrot);
-
 
875
      affine[2] = -affine[1];
-
 
876
      affine[4] = x;
-
 
877
      affine[5] = y;
-
 
878
      x = y = 0.0;
-
 
879
    }
-
 
880
 
646
    item = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(gtkd->canvas)),
881
  item = gnome_canvas_item_new (gd->group,
647
				 gnome_canvas_text_get_type(),
882
				gnome_canvas_text_get_type(),
648
				 "text", str,
883
				"text", str,
649
				 "anchor", GTK_ANCHOR_NW,
884
				"anchor", GTK_ANCHOR_SOUTH_WEST,
650
				 "x", x,
885
				"x", x,
651
				 "y", y,
886
				"y", y,
652
				 /*"font", "-adobe-times-medium-r-normal-*-*-120-*-*-p-*-iso8859-1",*/
-
 
653
				 "font", "-*-times-medium-r-*-*-120-*-*-*-*-*-*-*",
887
				"font_gdk", gd->font,
654
				 "fill_color_gdk", &gcol_fill,
888
				"fill_color_rgba", Color_RGBA(dd->gp.col),
655
				 NULL);
889
				NULL);
-
 
890
 
-
 
891
  if (rot != 0)
-
 
892
    gnome_canvas_item_affine_relative (item, affine);
656
}
893
}
657
 
894
 
658
/* locator */
895
/* locator */
-
 
896
 
-
 
897
static gboolean locator_cb (GtkWidget * canvas, GdkEventButton * event,
-
 
898
			    gpointer data)
-
 
899
{
-
 
900
  GdkEventButton *info = (GdkEventButton*) data;
-
 
901
  
-
 
902
  *info = *event;
-
 
903
  gtk_main_quit();
-
 
904
}
-
 
905
 
659
static Rboolean GNOME_Locator(double *x, double *y, DevDesc *dd)
906
static Rboolean GNOME_Locator(double *x, double *y, DevDesc *dd)
660
{
907
{
-
 
908
  gnomeDesc *gd = (gnomeDesc *) dd->deviceSpecific;
-
 
909
  GdkEventButton info;
-
 
910
  guint handler_id;
-
 
911
 
-
 
912
  /* Flush any pending events */
-
 
913
  while (gtk_events_pending())
-
 
914
    gtk_main_iteration();
-
 
915
 
-
 
916
  /* connect signal */
-
 
917
  handler_id = gtk_signal_connect (GTK_OBJECT (gd->canvas),
-
 
918
				   "button-press-event",
-
 
919
				   GTK_SIGNAL_FUNC (locator_cb), &info);
-
 
920
 
-
 
921
  /* run the handler */
-
 
922
  gtk_main();
-
 
923
 
-
 
924
  *x = (double) info.x;
-
 
925
  *y = (double) info.y;
-
 
926
 
-
 
927
  /* clean up */
-
 
928
  gtk_signal_disconnect(GTK_OBJECT(gd->canvas), handler_id);
-
 
929
 
-
 
930
  if (info.button == 1)
-
 
931
    {
-
 
932
      gdk_beep();
-
 
933
      return TRUE;
-
 
934
    }
-
 
935
  else
661
    return FALSE;
936
    return FALSE;
662
}
937
}
663
 
938
 
664
/* useless stuff */
939
/* useless stuff */
665
 
940
 
Line 675... Line 950...
675
/* Device driver entry point */
950
/* Device driver entry point */
676
Rboolean GnomeDeviceDriver(DevDesc *dd, char *display, 
951
Rboolean GnomeDeviceDriver(DevDesc *dd, char *display, 
677
			   double width, double height, double pointsize)
952
			   double width, double height, double pointsize)
678
{
953
{
679
    int ps;
954
    int ps;
680
    gnomeDesc *gtkd;
955
    gnomeDesc *gd;
681
 
956
 
682
    if(!(gtkd = (gnomeDesc *) malloc(sizeof(gnomeDesc))))
957
    if(!(gd = (gnomeDesc *) malloc(sizeof(gnomeDesc))))
683
	return FALSE;
958
	return FALSE;
684
 
959
 
685
    dd->deviceSpecific = (void *) gtkd;
960
    dd->deviceSpecific = (void *) gd;
686
 
961
 
687
    /* FIXME: font loading */
962
    /* FIXME: font loading */
688
    ps = pointsize;
963
    ps = pointsize;
689
    if(ps < 6 || ps > 24) ps = 12;
964
    if(ps < 6 || ps > 24) ps = 12;
690
    ps = 2 * (ps / 2);
965
    ps = 2 * (ps / 2);
691
    gtkd->fontface = -1;
966
    gd->fontface = -1;
692
    gtkd->fontsize = -1;
967
    gd->fontsize = -1;
693
    dd->dp.font = 1;
968
    dd->dp.font = 1;
694
    dd->dp.ps = ps;
969
    dd->dp.ps = ps;
695
 
970
 
696
    /* device driver start */
971
    /* device driver start */
697
    if(!GNOME_Open(dd, gtkd, display, width, height)) {
972
    if(!GNOME_Open(dd, gd, display, width, height)) {
698
	free(gtkd);
973
	free(gd);
699
	return FALSE;
974
	return FALSE;
700
    }
975
    }
701
 
976
 
702
    /* setup data structure */
977
    /* setup data structure */
703
    dd->dp.open = GNOME_Open;
978
    dd->dp.open = GNOME_Open;
Line 718... Line 993...
718
    dd->dp.mode = GNOME_Mode;
993
    dd->dp.mode = GNOME_Mode;
719
    dd->dp.hold = GNOME_Hold;
994
    dd->dp.hold = GNOME_Hold;
720
    dd->dp.metricInfo = GNOME_MetricInfo;
995
    dd->dp.metricInfo = GNOME_MetricInfo;
721
 
996
 
722
    dd->dp.left = 0;
997
    dd->dp.left = 0;
723
    dd->dp.right = gtkd->windowWidth;
998
    dd->dp.right = gd->windowWidth;
724
    dd->dp.bottom = gtkd->windowHeight;
999
    dd->dp.bottom = gd->windowHeight;
725
    dd->dp.top = 0;
1000
    dd->dp.top = 0;
726
 
1001
 
727
    /* FIXME: nominal character sizes */
1002
    /* FIXME: nominal character sizes */
728
    dd->dp.cra[0] = 10;
1003
    dd->dp.cra[0] = 10;
729
    dd->dp.cra[1] = 10;
1004
    dd->dp.cra[1] = 10;
Line 745... Line 1020...
745
    dd->dp.canClip = FALSE;/* FIXME: really? */
1020
    dd->dp.canClip = FALSE;/* FIXME: really? */
746
    dd->dp.canHAdj = 0;/* not better? {0, 0.5, 1} */
1021
    dd->dp.canHAdj = 0;/* not better? {0, 0.5, 1} */
747
 
1022
 
748
 
1023
 
749
    /* x11 device description stuff */
1024
    /* x11 device description stuff */
750
    gtkd->cex = 1.0;
1025
    gd->cex = 1.0;
751
    gtkd->srt = 0.0;
1026
    gd->srt = 0.0;
752
    gtkd->resize = FALSE;
1027
    gd->resize = FALSE;
753
 
1028
 
754
    dd->displayListOn = TRUE;
1029
    dd->displayListOn = TRUE;
755
 
1030
 
756
    /* finish */
1031
    /* finish */
757
    return TRUE;
1032
    return TRUE;
758
}
1033
}
-
 
1034
 
-
 
1035
 
-
 
1036
 
-
 
1037
 
-
 
1038
 
-
 
1039
 
-
 
1040
 
-
 
1041
 
-
 
1042
 
-
 
1043
 
-
 
1044
 
-
 
1045
 
-
 
1046
 
-
 
1047
 
-
 
1048
 
-
 
1049
 
-
 
1050
 
-
 
1051
 
-
 
1052