Index: src/include/Internal.h
===================================================================
RCS file: /u8/rdevel/CVS-ARCHIVE/R/src/include/Internal.h,v
retrieving revision 1.47
diff -r1.47 Internal.h
35a36
> SEXP do_asGTKDevice(SEXP, SEXP, SEXP, SEXP);
Index: src/library/base/R/unix/x11.R
===================================================================
RCS file: /u8/rdevel/CVS-ARCHIVE/R/src/library/base/R/unix/x11.R,v
retrieving revision 1.5
diff -r1.5 x11.R
15,16c15,16
< gtk <- function(display = "", width = 7, height = 7, pointsize = 12)
<     .Internal(GTK(display, width, height, pointsize))
---
> gtk <- function(display = "", width = 7, height = 7, pointsize = 12, no.window = FALSE)
>     .Internal(GTK(display, width, height, pointsize, no.window))
17a18,20
> 
> asGtkDevice <- function(drawingArea, pointsize = 12)
>   .Internal(asGTKDevice(drawingArea, pointsize))
Index: src/main/names.c
===================================================================
RCS file: /u8/rdevel/CVS-ARCHIVE/R/src/main/names.c,v
retrieving revision 1.246
diff -r1.246 names.c
681a682
> {"asGTKDevice",	do_asGTKDevice,	0,	111,	2,	PP_FUNCALL},
Index: src/modules/gnome/devGTK.c
===================================================================
RCS file: /u8/rdevel/CVS-ARCHIVE/R/src/modules/gnome/devGTK.c,v
retrieving revision 1.14
diff -r1.14 devGTK.c
76c76
< 			 double height, double pointsize);
---
> 			 double height, double pointsize, Rboolean);
115c115,117
< static Rboolean GTK_Open(NewDevDesc*, gtkDesc*, char*, double, double);
---
> static Rboolean GTK_Open(NewDevDesc*, gtkDesc*, char*, double, double, Rboolean);
> 
> static gint initialize(NewDevDesc *dd);
303d304
<     gtkDesc *gtkd;
307a309,314
>     return(initialize(dd));
> }
> 
> static gint initialize(NewDevDesc *dd)
> {
>     gtkDesc *gtkd;
322a330,337
>     /* create offscreen drawable */
>     gtkd->pixmap = gdk_pixmap_new(gtkd->drawing->window,
> 				  gtkd->windowWidth, gtkd->windowHeight,
> 				  -1);
>     gdk_gc_set_foreground(gtkd->wgc, &gtkd->gcol_bg);
>     gdk_draw_rectangle(gtkd->pixmap, gtkd->wgc, TRUE, 0, 0,
> 		       gtkd->windowWidth, gtkd->windowHeight);
> 
364a380,382
>     if(gtkd->wgc == NULL)
> 	realize_event(gtkd->drawing, dd);
> 
420c438
< static Rboolean GTK_Open(NewDevDesc *dd, gtkDesc *gtkd, char *dsp, double w, double h)
---
> static Rboolean GTK_Open(NewDevDesc *dd, gtkDesc *gtkd, char *dsp, double w, double h, Rboolean noWindow)
438c456,460
<     gtkd->window = gnome_app_new("R.graphics", "R Graphics");
---
>     if(noWindow == FALSE) {
> 	gtkd->window = gnome_app_new("R.graphics", "R Graphics");
> 
> 	gtk_window_set_policy(GTK_WINDOW(gtkd->window), TRUE, TRUE, FALSE);
> 	gtk_widget_realize(gtkd->window);
440,441c462,465
<     gtk_window_set_policy(GTK_WINDOW(gtkd->window), TRUE, TRUE, FALSE);
<     gtk_widget_realize(gtkd->window);
---
> 	/* create toolbar */
> 	gnome_app_create_toolbar_with_data(GNOME_APP(gtkd->window), graphics_toolbar, (gpointer) dd);
>     } else
> 	gtkd->window = NULL;
443,444d466
<     /* create toolbar */
<     gnome_app_create_toolbar_with_data(GNOME_APP(gtkd->window), graphics_toolbar, (gpointer) dd);
463,464c485,488
<     gnome_app_set_contents(GNOME_APP(gtkd->window), gtkd->drawing);
<     gtk_widget_realize(gtkd->drawing);
---
>     if(noWindow == FALSE) {
> 	gnome_app_set_contents(GNOME_APP(gtkd->window), gtkd->drawing);
> 	gtk_widget_realize(gtkd->drawing);
>     }
471,472c495,497
<     gtk_signal_connect(GTK_OBJECT(gtkd->window), "delete_event",
< 		       (GtkSignalFunc) delete_event, (gpointer) dd);
---
>     if(noWindow == FALSE) {
> 	gtk_signal_connect(GTK_OBJECT(gtkd->window), "delete_event",
> 			   (GtkSignalFunc) delete_event, (gpointer) dd);
474,475c499,501
<     /* show everything */
<     gtk_widget_show_all(gtkd->window);
---
> 	/* show everything */
> 	gtk_widget_show_all(gtkd->window);
>     }
481,488d506
<     /* create offscreen drawable */
<     gtkd->pixmap = gdk_pixmap_new(gtkd->drawing->window,
< 				  gtkd->windowWidth, gtkd->windowHeight,
< 				  -1);
<     gdk_gc_set_foreground(gtkd->wgc, &gtkd->gcol_bg);
<     gdk_draw_rectangle(gtkd->pixmap, gtkd->wgc, TRUE, 0, 0,
< 		       gtkd->windowWidth, gtkd->windowHeight);
< 
597c615,616
< 	gdk_pixmap_unref(gtkd->pixmap);
---
> 	if(gtkd->pixmap)
> 	    gdk_pixmap_unref(gtkd->pixmap);
637c656,657
<     gtk_widget_destroy(gtkd->window);
---
>     if(gtkd->window)
> 	gtk_widget_destroy(gtkd->window);
639c659,660
<     gdk_pixmap_unref(gtkd->pixmap);
---
>     if(gtkd->pixmap)
> 	gdk_pixmap_unref(gtkd->pixmap);
658c679,680
<     title_text = g_strdup_printf(title_text_active, devnum);
---
>     if(gtkd->window) {
> 	title_text = g_strdup_printf(title_text_active, devnum);
660c682
<     gtk_window_set_title(GTK_WINDOW(gtkd->window), title_text);
---
> 	gtk_window_set_title(GTK_WINDOW(gtkd->window), title_text);
662c684,685
<     g_free(title_text);
---
> 	g_free(title_text);
>     }
676c699,700
<     title_text = g_strdup_printf(title_text_inactive, devnum);
---
>     if(gtkd->window) {
> 	title_text = g_strdup_printf(title_text_inactive, devnum);
678c702
<     gtk_window_set_title(GTK_WINDOW(gtkd->window), title_text);
---
> 	gtk_window_set_title(GTK_WINDOW(gtkd->window), title_text);
680c704,705
<     g_free(title_text);
---
> 	g_free(title_text);
>     }
988c1013
< 		double height, double pointsize)
---
> 		double height, double pointsize, Rboolean noWindow)
1018c1043
<     if(!GTK_Open(dd, gtkd, display, width, height)) {
---
>     if(!GTK_Open(dd, gtkd, display, width, height, noWindow)) {
1096a1122,1280
> GtkWidget *
> GTKDeviceGetDrawingWidget(NewDevDesc *dev)
> {
>   gtkDesc *desc;
>   desc = dev->deviceSpecific;
>   return(desc->drawing);
> }
> 
> Rboolean
> asGTKDevice(NewDevDesc *dd, SEXP widget, double pointsize)
> {
>   double ps = pointsize;
>   gint iw, ih, w, h;
>   GtkWidget *drawing = (GtkWidget*) R_ExternalPtrAddr(widget);
>   gtkDesc *gtkd;
> 
>   gchar tmp[2];
>   gint cumwidth, c, rbearing, lbearing;
>   double max_rbearing, min_lbearing;
> 
>   GTK_DRAWING_AREA(drawing);
> 
>   if(!(gtkd = (gtkDesc *) malloc(sizeof(gtkDesc))))
>       return FALSE;
> 
>   w = 0; h = 0;
>   gtkd->window = NULL;
>   gtkd->drawing = NULL;
>   gtkd->wgc = NULL;
>   gtkd->gcursor = NULL;
> 
>     /* font loading */
>   ps = pointsize;
>   if(ps < 6 || ps > 24) ps = 12;
>   ps = 2 * (ps / 2);
>   gtkd->fontface = -1;
>   gtkd->fontsize = -1;
>   dd->startfont = 1; 
>   dd->startps = ps;
>   dd->startcol = 0;
>   dd->startfill = NA_INTEGER;
>   dd->startlty = LTY_SOLID; 
>   dd->startgamma = 1;
> 
> 
>     /* device driver start */
>   {
>   gtkd->drawing = drawing;
>   gtk_widget_set_events(gtkd->drawing,
> 			  GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
>   gdk_rgb_init();
>   gtk_widget_push_visual(gdk_rgb_get_visual());
>   gtk_widget_push_colormap(gdk_rgb_get_cmap());
> 
>   gtkd->windowWidth = iw = w / pixelWidth();
>   gtkd->windowHeight = ih = h / pixelHeight();
>     /* connect to signal handlers, etc */
>   gtk_signal_connect(GTK_OBJECT(gtkd->drawing), "realize",
> 		     (GtkSignalFunc) realize_event, (gpointer) dd);
> 
> 
>   SetColor(&gtkd->gcol_bg, R_RGB(255, 255, 255)); //FIXME canvas color
> 
>     /* connect to signal handlers, etc */
>   gtk_signal_connect(GTK_OBJECT(gtkd->drawing), "configure_event",
> 		     (GtkSignalFunc) configure_event, (gpointer) dd);
>   gtk_signal_connect(GTK_OBJECT(gtkd->drawing), "expose_event",
> 		     (GtkSignalFunc) expose_event, (gpointer) dd);
> 
>   dd->deviceSpecific = (void *) gtkd;
> 
>     /* initialise line params */
>     gtkd->lty = -1;
>     gtkd->lwd = -1;
> 
> 
>     /* let other widgets use the default colour settings */
>     gtk_widget_pop_visual();
>     gtk_widget_pop_colormap();
> 
>     /* Set base font */
>     if(!SetBaseFont(gtkd)) {
> 	Rprintf("can't find X11 font\n");
> 	return FALSE;
>     }
>   }
> 
>   dd->newDevStruct = 1;
> 
>     /* setup data structure */
>   dd->open = GTK_Open;
>   dd->close = GTK_Close;
>   dd->activate = GTK_Activate;
>   dd->deactivate = GTK_Deactivate;
>   dd->size = GTK_Size;
>   dd->newPage = GTK_NewPage;
>   dd->clip = GTK_Clip;
>   dd->strWidth = GTK_StrWidth;
>   dd->text = GTK_Text;
>   dd->rect = GTK_Rect;
>   dd->circle = GTK_Circle;
>   dd->line = GTK_Line;
>   dd->polyline = GTK_Polyline;
>   dd->polygon = GTK_Polygon;
>   dd->locator = GTK_Locator;
>   dd->mode = GTK_Mode;
>   dd->hold = GTK_Hold;
>   dd->metricInfo = GTK_MetricInfo;
> 
>   dd->left = 0;
>   dd->right = gtkd->windowWidth;
>   dd->bottom = gtkd->windowHeight;
>   dd->top = 0;
> 
>     /* nominal character sizes */
>   max_rbearing = 0;
>   min_lbearing = 10000; /* just a random big number */
>   for(c = 0; c <= 255; c++) {
>       g_snprintf(tmp, 2, "%c", (gchar) c);
>       gdk_string_extents(gtkd->font, tmp,
> 			 &lbearing, &rbearing,
> 			 NULL, NULL, NULL);
>       if(lbearing < min_lbearing || c == 0)
> 	  min_lbearing = lbearing;
>       if(rbearing > max_rbearing)
> 	  max_rbearing = rbearing;
>     }
> 
>   dd->cra[0] = max_rbearing - min_lbearing;
>   dd->cra[1] = (double) gtkd->font->ascent + (double) gtkd->font->descent;
> 
>     /* character addressing offsets */
>   dd->xCharOffset = 0.4900;
>   dd->yCharOffset = 0.3333;
>   dd->yLineBias = 0.1;
> 
>     /* inches per raster unit */
>   dd->ipr[0] = pixelWidth();
>   dd->ipr[1] = pixelHeight();
> 
>     /* device capabilities */
>   dd->canResizePlot= TRUE;
>   dd->canChangeFont= FALSE;
>   dd->canRotateText= TRUE;
>   dd->canResizeText= TRUE;
>   dd->canClip = FALSE;/* FIXME: really? */
>   dd->canHAdj = 0;/* not better? {0, 0.5, 1} */
>   dd->canChangeGamma = FALSE;
> 
>     /* gtk device description stuff */
>   gtkd->cex = 1.0;
>   gtkd->srt = 0.0;
>   gtkd->resize = FALSE;
> 
>   dd->displayListOn = TRUE;
> 
>     /* finish */
>   return TRUE;
> }
Index: src/unix/devUI.h
===================================================================
RCS file: /u8/rdevel/CVS-ARCHIVE/R/src/unix/devUI.h,v
retrieving revision 1.11
diff -r1.11 devUI.h
20c20,22
< extern Rboolean (*ptr_GTKDeviceDriver)(DevDesc*, char*, double, double, double);
---
> extern Rboolean (*ptr_GTKDeviceDriver)(DevDesc*, char*, double, double, double, Rboolean);
> extern void*    (*ptr_GTKDeviceGetDrawingWidget)(DevDesc*);
> extern Rboolean (*ptr_asGTKDevice)(DevDesc*, SEXP, double);
55c57,58
< Rboolean stub_GTKDeviceDriver(DevDesc*, char*, double, double, double);
---
> Rboolean stub_GTKDeviceDriver(DevDesc*, char*, double, double, double, Rboolean);
> Rboolean stub_asGTKDevice(DevDesc *dd, SEXP widget, double pointsize);
Index: src/unix/devices.c
===================================================================
RCS file: /u8/rdevel/CVS-ARCHIVE/R/src/unix/devices.c,v
retrieving revision 1.22
diff -r1.22 devices.c
152a153
>     SEXP value = R_NilValue;
156a158
>     Rboolean noWindow;
164c166,167
<     ps = asReal(CAR(args));
---
>     ps = asReal(CAR(args)); args = CDR(args);
>     noWindow = asLogical(CAR(args)); 
173c176
< 	if (!ptr_GTKDeviceDriver ((DevDesc*)dev, display, width, height, ps)) {
---
> 	if (!ptr_GTKDeviceDriver ((DevDesc*)dev, display, width, height, ps, noWindow)) {
177a181,217
> 	dd = GEcreateDevDesc(dev);
>         dd->newDevStruct = 1;
> 	addDevice((DevDesc*) dd);
> 	GEinitDisplayList(dd);
> 	if(noWindow) { /* Is this protected adequately? */
> 	    value = R_MakeExternalPtr((void*) ptr_GTKDeviceGetDrawingWidget(dd->dev), install("GtkWidget"), NULL);
> 	}
>     } END_SUSPEND_INTERRUPTS;
>     vmaxset(vmax);
>     return value;
> }
> 
> 
> SEXP do_asGTKDevice(SEXP call, SEXP op, SEXP args, SEXP env)
> {
>     SEXP value = R_NilValue;
>     NewDevDesc *dev;
>     GEDevDesc *dd;
>     char *vmax;
>     double ps;
>     SEXP widget;
>     gcall = call;
>     vmax = vmaxget();
>     widget = CAR(args); args = CDR(args);
>     ps = asReal(CAR(args));
>     R_CheckDeviceAvailable();
>     BEGIN_SUSPEND_INTERRUPTS {
> 	/* Allocate and initialize the device driver data */
> 	if (!(dev = (NewDevDesc *) calloc(1, sizeof(NewDevDesc))))
> 	    return 0;
> 	/* Do this for early redraw attempts */
> 	dev->displayList = R_NilValue;
> 	if (!ptr_asGTKDevice((DevDesc*)dev, widget, ps)) {
> 	    free(dev);
> 	    errorcall(call, "unable to start device gtk");
> 	}
> 	gsetVar(install(".Device"), mkString("InternalGTK"), R_NilValue);
Index: src/unix/gnome.c
===================================================================
RCS file: /u8/rdevel/CVS-ARCHIVE/R/src/unix/gnome.c,v
retrieving revision 1.7
diff -r1.7 gnome.c
70c70,71
<     ptr_GnomeDeviceDriver, ptr_GTKDeviceDriver,
---
>     ptr_GnomeDeviceDriver, ptr_GTKDeviceDriver, 
>     ptr_GTKDeviceGetDrawingWidget, ptr_asGTKDevice,
126a128,131
>     ptr_GTKDeviceGetDrawingWidget = Rdlsym(handle, "GTKDeviceGetDrawingWidget");
>     if(!ptr_GTKDeviceGetDrawingWidget) R_Suicide("Cannot load GTKDeviceGetDrawingWidget");
>     ptr_asGTKDevice = Rdlsym(handle, "asGTKDevice");
>     if(!ptr_asGTKDevice) R_Suicide("Cannot load asGTKDevice");
Index: src/unix/stubs.c
===================================================================
RCS file: /u8/rdevel/CVS-ARCHIVE/R/src/unix/stubs.c,v
retrieving revision 1.11
diff -r1.11 stubs.c
55c55
< 			  double height, double pointsize)
---
> 			  double height, double pointsize, Rboolean noWindow)
57a58,64
>     return FALSE;
> }
> 
> 
> Rboolean stub_asGTKDevice(DevDesc *dd, SEXP widget, double pointsize)
> {
>     error("no support for creating a gtk device from a widget");
Index: src/unix/system.c
===================================================================
RCS file: /u8/rdevel/CVS-ARCHIVE/R/src/unix/system.c,v
retrieving revision 1.113
diff -r1.113 system.c
173a174
>     ptr_asGTKDevice = stub_asGTKDevice;
